.fw_flash_update_req    = pm8001_chip_fw_flash_update_req,
        .set_dev_state_req      = pm8001_chip_set_dev_state_req,
        .sas_re_init_req        = pm8001_chip_sas_re_initialization,
+       .fatal_errors           = pm80xx_fatal_errors,
 };
 
        int rc = TMF_RESP_FUNC_FAILED, ret;
        u32 phy_id;
        struct sas_task_slow slow_task;
+
        if (unlikely(!task || !task->lldd_task || !task->dev))
                return TMF_RESP_FUNC_FAILED;
+
        dev = task->dev;
        pm8001_dev = dev->lldd_dev;
        pm8001_ha = pm8001_find_ha_by_dev(dev);
        phy_id = pm8001_dev->attached_phy;
+
+       if (PM8001_CHIP_DISP->fatal_errors(pm8001_ha)) {
+               // If the controller is seeing fatal errors
+               // abort task will not get a response from the controller
+               return TMF_RESP_FUNC_FAILED;
+       }
+
        ret = pm8001_find_tag(task, &tag);
        if (ret == 0) {
                pm8001_info(pm8001_ha, "no tag for task:%p\n", task);
 
        int (*sas_diag_execute_req)(struct pm8001_hba_info *pm8001_ha,
                u32 state);
        int (*sas_re_init_req)(struct pm8001_hba_info *pm8001_ha);
+       int (*fatal_errors)(struct pm8001_hba_info *pm8001_ha);
 };
 
 struct pm8001_chip_info {
 ssize_t pm80xx_get_non_fatal_dump(struct device *cdev,
                struct device_attribute *attr, char *buf);
 ssize_t pm8001_get_gsm_dump(struct device *cdev, u32, char *buf);
+int pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha);
 /* ctl shared API */
 extern struct device_attribute *pm8001_host_attrs[];
 
 
        return 0;
 }
 
+/**
+ * pm80xx_fatal_errors - returns non zero *ONLY* when fatal errors
+ * @pm8001_ha: our hba card information
+ *
+ * Fatal errors are recoverable only after a host reboot.
+ */
+int
+pm80xx_fatal_errors(struct pm8001_hba_info *pm8001_ha)
+{
+       int ret = 0;
+       u32 scratch_pad_rsvd0 = pm8001_cr32(pm8001_ha, 0,
+                                       MSGU_HOST_SCRATCH_PAD_6);
+       u32 scratch_pad_rsvd1 = pm8001_cr32(pm8001_ha, 0,
+                                       MSGU_HOST_SCRATCH_PAD_7);
+       u32 scratch_pad1 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
+       u32 scratch_pad2 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_2);
+       u32 scratch_pad3 = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_3);
+
+       if (pm8001_ha->chip_id != chip_8006 &&
+                       pm8001_ha->chip_id != chip_8074 &&
+                       pm8001_ha->chip_id != chip_8076) {
+               return 0;
+       }
+
+       if (MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(scratch_pad1)) {
+               pm8001_dbg(pm8001_ha, FAIL,
+                       "Fatal error SCRATCHPAD1 = 0x%x SCRATCHPAD2 = 0x%x SCRATCHPAD3 = 0x%x SCRATCHPAD_RSVD0 = 0x%x SCRATCHPAD_RSVD1 = 0x%x\n",
+                               scratch_pad1, scratch_pad2, scratch_pad3,
+                               scratch_pad_rsvd0, scratch_pad_rsvd1);
+               ret = 1;
+       }
+
+       return ret;
+}
+
 /**
  * pm8001_chip_soft_rst - soft reset the PM8001 chip, so that the clear all
  * the FW register status to the originated status.
        .set_nvmd_req           = pm8001_chip_set_nvmd_req,
        .fw_flash_update_req    = pm8001_chip_fw_flash_update_req,
        .set_dev_state_req      = pm8001_chip_set_dev_state_req,
+       .fatal_errors           = pm80xx_fatal_errors,
 };
 
 #define MSGU_HOST_SCRATCH_PAD_6                        0x6C
 #define MSGU_HOST_SCRATCH_PAD_7                        0x70
 
+#define MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ((x & 0x3) == 0x2)
+#define MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) (((x >> 2) & 0x3) == 0x2)
+#define MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ((((x >> 4) & 0x7) == 0x7) || \
+                                               (((x >> 4) & 0x7) == 0x4))
+#define MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) (((x >> 10) & 0x3) == 0x2)
+#define MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x) (((x >> 12) & 0x3) == 0x2)
+#define MSGU_SCRATCHPAD1_STATE_FATAL_ERROR(x)  \
+                       (MSGU_SCRATCHPAD1_RAAE_STATE_ERR(x) ||      \
+                        MSGU_SCRATCHPAD1_ILA_STATE_ERR(x) ||       \
+                        MSGU_SCRATCHPAD1_BOOTLDR_STATE_ERR(x) ||   \
+                        MSGU_SCRATCHPAD1_IOP0_STATE_ERR(x) ||      \
+                        MSGU_SCRATCHPAD1_IOP1_STATE_ERR(x))
+
 /* bit definition for ODMR register */
 #define ODMR_MASK_ALL                  0xFFFFFFFF/* mask all
                                        interrupt vector */