pm8001_free_dev(pm8001_dev);
                        }
                }
-       }       break;
+       }
+       break;
+       case IO_XFER_ERROR_ABORTED_NCQ_MODE:
+       {
+               dev = pm8001_dev->sas_device;
+               sas_ata_device_link_abort(dev, false);
+       }
+       break;
        }
        kfree(pw);
 }
        return ret;
 }
 
-static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha,
-               struct pm8001_device *pm8001_ha_dev)
-{
-       struct pm8001_ccb_info *ccb;
-       struct sas_task *task;
-       struct task_abort_req task_abort;
-       u32 opc = OPC_INB_SATA_ABORT;
-       int ret;
-
-       pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
-       pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
-
-       task = sas_alloc_slow_task(GFP_ATOMIC);
-       if (!task) {
-               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
-               return;
-       }
-
-       task->task_done = pm8001_task_done;
-
-       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
-       if (!ccb) {
-               sas_free_task(task);
-               return;
-       }
-
-       memset(&task_abort, 0, sizeof(task_abort));
-       task_abort.abort_all = cpu_to_le32(1);
-       task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-       task_abort.tag = cpu_to_le32(ccb->ccb_tag);
-
-       ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
-                                  sizeof(task_abort), 0);
-       if (ret) {
-               sas_free_task(task);
-               pm8001_ccb_free(pm8001_ha, ccb);
-       }
-}
-
-static void pm8001_send_read_log(struct pm8001_hba_info *pm8001_ha,
-               struct pm8001_device *pm8001_ha_dev)
-{
-       struct sata_start_req sata_cmd;
-       int res;
-       struct pm8001_ccb_info *ccb;
-       struct sas_task *task = NULL;
-       struct host_to_dev_fis fis;
-       struct domain_device *dev;
-       u32 opc = OPC_INB_SATA_HOST_OPSTART;
-
-       task = sas_alloc_slow_task(GFP_ATOMIC);
-       if (!task) {
-               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
-               return;
-       }
-       task->task_done = pm8001_task_done;
-
-       /*
-        * Allocate domain device by ourselves as libsas is not going to
-        * provide any.
-        */
-       dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
-       if (!dev) {
-               sas_free_task(task);
-               pm8001_dbg(pm8001_ha, FAIL,
-                          "Domain device cannot be allocated\n");
-               return;
-       }
-       task->dev = dev;
-       task->dev->lldd_dev = pm8001_ha_dev;
-
-       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
-       if (!ccb) {
-               sas_free_task(task);
-               kfree(dev);
-               return;
-       }
-
-       pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
-       pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
-
-       /* construct read log FIS */
-       memset(&fis, 0, sizeof(struct host_to_dev_fis));
-       fis.fis_type = 0x27;
-       fis.flags = 0x80;
-       fis.command = ATA_CMD_READ_LOG_EXT;
-       fis.lbal = 0x10;
-       fis.sector_count = 0x1;
-
-       memset(&sata_cmd, 0, sizeof(sata_cmd));
-       sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
-       sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-       sata_cmd.ncqtag_atap_dir_m = cpu_to_le32((0x1 << 7) | (0x5 << 9));
-       memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
-
-       res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
-                                  sizeof(sata_cmd), 0);
-       if (res) {
-               sas_free_task(task);
-               pm8001_ccb_free(pm8001_ha, ccb);
-               kfree(dev);
-       }
-}
-
 /**
  * mpi_ssp_completion- process the event that FW response to the SSP request.
  * @pm8001_ha: our hba card information
                return;
        }
 
-       if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG))
-               && unlikely(!t || !t->lldd_task || !t->dev)) {
+       if (pm8001_dev && unlikely(!t || !t->lldd_task || !t->dev)) {
                pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n");
                return;
        }
                if (param == 0) {
                        ts->resp = SAS_TASK_COMPLETE;
                        ts->stat = SAS_SAM_STAT_GOOD;
-                       /* check if response is for SEND READ LOG */
-                       if (pm8001_dev &&
-                           (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
-                               pm8001_send_abort_all(pm8001_ha, pm8001_dev);
-                               /* Free the tag */
-                               pm8001_tag_free(pm8001_ha, tag);
-                               sas_free_task(t);
-                               return;
-                       }
                } else {
                        u8 len;
                        ts->resp = SAS_TASK_COMPLETE;
        if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) {
                /* find device using device id */
                pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id);
-               /* send read log extension */
                if (pm8001_dev)
-                       pm8001_send_read_log(pm8001_ha, pm8001_dev);
+                       pm8001_handle_event(pm8001_ha,
+                               pm8001_dev,
+                               IO_XFER_ERROR_ABORTED_NCQ_MODE);
                return;
        }
 
        pm8001_ccb_task_free(pm8001_ha, ccb);
        mb();
 
-       if (pm8001_dev->id & NCQ_ABORT_ALL_FLAG) {
-               sas_free_task(t);
-               pm8001_dev->id &= ~NCQ_ABORT_ALL_FLAG;
-       } else {
-               t->task_done(t);
-       }
+       t->task_done(t);
 
        return 0;
 }
        u64 phys_addr;
        u32 ATAP = 0x0;
        u32 dir;
-       unsigned long flags;
        u32  opc = OPC_INB_SATA_HOST_OPSTART;
 
        memset(&sata_cmd, 0, sizeof(sata_cmd));
                sata_cmd.esgl = 0;
        }
 
-       /* Check for read log for failed drive and return */
-       if (sata_cmd.sata_fis.command == 0x2f) {
-               if (((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) ||
-                       (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) ||
-                       (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) {
-                       struct task_status_struct *ts;
-
-                       pm8001_ha_dev->id &= 0xDFFFFFFF;
-                       ts = &task->task_status;
-
-                       spin_lock_irqsave(&task->task_state_lock, flags);
-                       ts->resp = SAS_TASK_COMPLETE;
-                       ts->stat = SAS_SAM_STAT_GOOD;
-                       task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
-                       task->task_state_flags |= SAS_TASK_STATE_DONE;
-                       if (unlikely((task->task_state_flags &
-                                       SAS_TASK_STATE_ABORTED))) {
-                               spin_unlock_irqrestore(&task->task_state_lock,
-                                                       flags);
-                               pm8001_dbg(pm8001_ha, FAIL,
-                                          "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
-                                          task, ts->resp,
-                                          ts->stat);
-                               pm8001_ccb_task_free(pm8001_ha, ccb);
-                       } else {
-                               spin_unlock_irqrestore(&task->task_state_lock,
-                                                       flags);
-                               pm8001_ccb_task_free_done(pm8001_ha, ccb);
-                               return 0;
-                       }
-               }
-       }
-
        return pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
                                    sizeof(sata_cmd), 0);
 }
 
        return pm8001_dev_found_notify(dev);
 }
 
-void pm8001_task_done(struct sas_task *task)
-{
-       del_timer(&task->slow_task->timer);
-       complete(&task->slow_task->completion);
-}
-
 #define PM8001_TASK_TIMEOUT 20
 
 /**
 
 #define FLASH_UPDATE_DNLD_NOT_SUPPORTED                0x10
 #define FLASH_UPDATE_DISABLED                  0x11
 
-#define        NCQ_READ_LOG_FLAG                       0x80000000
-#define        NCQ_ABORT_ALL_FLAG                      0x40000000
-#define        NCQ_2ND_RLE_FLAG                        0x20000000
-
 /* Device states */
 #define DS_OPERATIONAL                         0x01
 #define DS_PORT_IN_RESET                       0x02
 int pm8001_mpi_general_event(struct pm8001_hba_info *pm8001_ha, void *piomb);
 int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb);
 struct sas_task *pm8001_alloc_task(void);
-void pm8001_task_done(struct sas_task *task);
 void pm8001_free_task(struct sas_task *task);
 void pm8001_tag_free(struct pm8001_hba_info *pm8001_ha, u32 tag);
 struct pm8001_device *pm8001_find_dev(struct pm8001_hba_info *pm8001_ha,
 
        pm80xx_chip_intx_interrupt_disable(pm8001_ha);
 }
 
-static void pm80xx_send_abort_all(struct pm8001_hba_info *pm8001_ha,
-               struct pm8001_device *pm8001_ha_dev)
-{
-       struct pm8001_ccb_info *ccb;
-       struct sas_task *task;
-       struct task_abort_req task_abort;
-       u32 opc = OPC_INB_SATA_ABORT;
-       int ret;
-
-       pm8001_ha_dev->id |= NCQ_ABORT_ALL_FLAG;
-       pm8001_ha_dev->id &= ~NCQ_READ_LOG_FLAG;
-
-       task = sas_alloc_slow_task(GFP_ATOMIC);
-       if (!task) {
-               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task\n");
-               return;
-       }
-       task->task_done = pm8001_task_done;
-
-       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
-       if (!ccb) {
-               sas_free_task(task);
-               return;
-       }
-
-       memset(&task_abort, 0, sizeof(task_abort));
-       task_abort.abort_all = cpu_to_le32(1);
-       task_abort.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-       task_abort.tag = cpu_to_le32(ccb->ccb_tag);
-
-       ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort,
-                                  sizeof(task_abort), 0);
-       pm8001_dbg(pm8001_ha, FAIL, "Executing abort task end\n");
-       if (ret) {
-               sas_free_task(task);
-               pm8001_ccb_free(pm8001_ha, ccb);
-       }
-}
-
-static void pm80xx_send_read_log(struct pm8001_hba_info *pm8001_ha,
-               struct pm8001_device *pm8001_ha_dev)
-{
-       struct sata_start_req sata_cmd;
-       int res;
-       struct pm8001_ccb_info *ccb;
-       struct sas_task *task = NULL;
-       struct host_to_dev_fis fis;
-       struct domain_device *dev;
-       u32 opc = OPC_INB_SATA_HOST_OPSTART;
-
-       task = sas_alloc_slow_task(GFP_ATOMIC);
-       if (!task) {
-               pm8001_dbg(pm8001_ha, FAIL, "cannot allocate task !!!\n");
-               return;
-       }
-       task->task_done = pm8001_task_done;
-
-       /*
-        * Allocate domain device by ourselves as libsas is not going to
-        * provide any.
-        */
-       dev = kzalloc(sizeof(struct domain_device), GFP_ATOMIC);
-       if (!dev) {
-               sas_free_task(task);
-               pm8001_dbg(pm8001_ha, FAIL,
-                          "Domain device cannot be allocated\n");
-               return;
-       }
-
-       task->dev = dev;
-       task->dev->lldd_dev = pm8001_ha_dev;
-
-       ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_ha_dev, task);
-       if (!ccb) {
-               sas_free_task(task);
-               kfree(dev);
-               return;
-       }
-
-       pm8001_ha_dev->id |= NCQ_READ_LOG_FLAG;
-       pm8001_ha_dev->id |= NCQ_2ND_RLE_FLAG;
-
-       memset(&sata_cmd, 0, sizeof(sata_cmd));
-
-       /* construct read log FIS */
-       memset(&fis, 0, sizeof(struct host_to_dev_fis));
-       fis.fis_type = 0x27;
-       fis.flags = 0x80;
-       fis.command = ATA_CMD_READ_LOG_EXT;
-       fis.lbal = 0x10;
-       fis.sector_count = 0x1;
-
-       sata_cmd.tag = cpu_to_le32(ccb->ccb_tag);
-       sata_cmd.device_id = cpu_to_le32(pm8001_ha_dev->device_id);
-       sata_cmd.ncqtag_atap_dir_m_dad = cpu_to_le32(((0x1 << 7) | (0x5 << 9)));
-       memcpy(&sata_cmd.sata_fis, &fis, sizeof(struct host_to_dev_fis));
-
-       res = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &sata_cmd,
-                                  sizeof(sata_cmd), 0);
-       pm8001_dbg(pm8001_ha, FAIL, "Executing read log end\n");
-       if (res) {
-               sas_free_task(task);
-               pm8001_ccb_free(pm8001_ha, ccb);
-               kfree(dev);
-       }
-}
-
 /**
  * mpi_ssp_completion - process the event that FW response to the SSP request.
  * @pm8001_ha: our hba card information
                return;
        }
 
-       if ((pm8001_dev && !(pm8001_dev->id & NCQ_READ_LOG_FLAG))
-               && unlikely(!t || !t->lldd_task || !t->dev)) {
-               pm8001_dbg(pm8001_ha, FAIL, "task or dev null\n");
+
+       if (pm8001_dev && unlikely(!t->lldd_task || !t->dev))
                return;
-       }
 
        ts = &t->task_status;
 
                if (param == 0) {
                        ts->resp = SAS_TASK_COMPLETE;
                        ts->stat = SAS_SAM_STAT_GOOD;
-                       /* check if response is for SEND READ LOG */
-                       if (pm8001_dev &&
-                           (pm8001_dev->id & NCQ_READ_LOG_FLAG)) {
-                               pm80xx_send_abort_all(pm8001_ha, pm8001_dev);
-                               /* Free the tag */
-                               pm8001_tag_free(pm8001_ha, tag);
-                               sas_free_task(t);
-                               return;
-                       }
                } else {
                        u8 len;
                        ts->resp = SAS_TASK_COMPLETE;
        if (event == IO_XFER_ERROR_ABORTED_NCQ_MODE) {
                /* find device using device id */
                pm8001_dev = pm8001_find_dev(pm8001_ha, dev_id);
-               /* send read log extension */
+               /* send read log extension by aborting the link - libata does what we want */
                if (pm8001_dev)
-                       pm80xx_send_read_log(pm8001_ha, pm8001_dev);
+                       pm8001_handle_event(pm8001_ha,
+                               pm8001_dev,
+                               IO_XFER_ERROR_ABORTED_NCQ_MODE);
                return;
        }
 
        u32 end_addr_high, end_addr_low;
        u32 ATAP = 0x0;
        u32 dir;
-       unsigned long flags;
        u32 opc = OPC_INB_SATA_HOST_OPSTART;
        memset(&sata_cmd, 0, sizeof(sata_cmd));
 
                                     (task->ata_task.atapi_packet[15] << 24)));
        }
 
-       /* Check for read log for failed drive and return */
-       if (sata_cmd.sata_fis.command == 0x2f) {
-               if (pm8001_ha_dev && ((pm8001_ha_dev->id & NCQ_READ_LOG_FLAG) ||
-                       (pm8001_ha_dev->id & NCQ_ABORT_ALL_FLAG) ||
-                       (pm8001_ha_dev->id & NCQ_2ND_RLE_FLAG))) {
-                       struct task_status_struct *ts;
-
-                       pm8001_ha_dev->id &= 0xDFFFFFFF;
-                       ts = &task->task_status;
-
-                       spin_lock_irqsave(&task->task_state_lock, flags);
-                       ts->resp = SAS_TASK_COMPLETE;
-                       ts->stat = SAS_SAM_STAT_GOOD;
-                       task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
-                       task->task_state_flags |= SAS_TASK_STATE_DONE;
-                       if (unlikely((task->task_state_flags &
-                                       SAS_TASK_STATE_ABORTED))) {
-                               spin_unlock_irqrestore(&task->task_state_lock,
-                                                       flags);
-                               pm8001_dbg(pm8001_ha, FAIL,
-                                          "task 0x%p resp 0x%x  stat 0x%x but aborted by upper layer\n",
-                                          task, ts->resp,
-                                          ts->stat);
-                               pm8001_ccb_task_free(pm8001_ha, ccb);
-                               return 0;
-                       } else {
-                               spin_unlock_irqrestore(&task->task_state_lock,
-                                                       flags);
-                               pm8001_ccb_task_free_done(pm8001_ha, ccb);
-                               atomic_dec(&pm8001_ha_dev->running_req);
-                               return 0;
-                       }
-               }
-       }
        trace_pm80xx_request_issue(pm8001_ha->id,
                                ccb->device ? ccb->device->attached_phy : PM8001_MAX_PHYS,
                                ccb->ccb_tag, opc,