Received: by 2002:ac0:da4c:0:0:0:0:0 with SMTP id a12csp545964imi; Fri, 22 Jul 2022 04:43:50 -0700 (PDT) X-Google-Smtp-Source: AGRyM1sSSXEyF40KSETVtuzgEp2BQEPk4I739igvyYGPVngRl8M8ABwbzo31WUzSqPVGSLreE2mc X-Received: by 2002:a05:6a00:1915:b0:52b:17fa:6f33 with SMTP id y21-20020a056a00191500b0052b17fa6f33mr3343859pfi.54.1658490230496; Fri, 22 Jul 2022 04:43:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658490230; cv=none; d=google.com; s=arc-20160816; b=dVH2z0puf5CFGlyP5iYLKVCx1pqpa/Fq2EvFKWtEPpuJAW/av3xIOutfm9WrTJciL7 hOR0zLyRfYYw8alYyo+e3rM1F9EVtS++aIKyy6vq+hH2UOAO/Fq9aOfpd93ZYlYUcUQl haUnWr0vIIBmX2AqgjdRC7JnJYdwK4RI3528LeuzkF1aQXbOkpCr0McmIZadh0UqaX77 Q3B6mNCIvsB9/FVTHg6A48SeJuSJLF3Qw3O4dmwIZmM/rCoxR8ZwKcnSgT8R73OuEYHa b1iIF/VP4iXftM7m+tCGNvzIinz7ApHsVM+H5ZRwvVgBYznZBbRLG+uCThFx1YJUUIAm sWZw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from; bh=m/tA4sTPOOX+UMHvVoMMvXRHLmycinu0TMBHtJJao0c=; b=fmow4CG5JK5B5KprhO7E+ka4TXuCzliGjglTkgyC7oIuMEYWVKej0Ui2NJHqwGIv2C iHgv2WrWLBF+RrhK1FgfyUhxzKhsHMn/B6YgzzPxLMPoam7xqIciQrd2yI+oQ1y8PIiO k7T5Ba0iznffqJ18VVH8uJLVxZrFEkwokXjDYwt4vwjSCA5r5qVrDpR02RTqk5hCLLHv KHYNrrT1pPb42xoV7/69ZXhXHXtV4uco3Gsfkimb5bhm1vr5wteu41zLcpPk8HVhabf4 CIze4Ymk9Tx1vE5iO/hsxbw08VXdMkQ7ZNQTBcB8xKNQArYV2cJEeuHkm3ACPGDy5R7C ERug== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d16-20020a056a0024d000b0050605f7112bsi6030671pfv.130.2022.07.22.04.43.35; Fri, 22 Jul 2022 04:43:50 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234724AbiGVLaq (ORCPT + 99 others); Fri, 22 Jul 2022 07:30:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60482 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234621AbiGVLah (ORCPT ); Fri, 22 Jul 2022 07:30:37 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB546753B3; Fri, 22 Jul 2022 04:30:35 -0700 (PDT) Received: from fraeml744-chm.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4Lq6ZG1V7Wz67twb; Fri, 22 Jul 2022 19:25:58 +0800 (CST) Received: from lhreml724-chm.china.huawei.com (10.201.108.75) by fraeml744-chm.china.huawei.com (10.206.15.225) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Fri, 22 Jul 2022 13:30:33 +0200 Received: from localhost.localdomain (10.69.192.58) by lhreml724-chm.china.huawei.com (10.201.108.75) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.24; Fri, 22 Jul 2022 12:30:29 +0100 From: John Garry To: , , , , , , CC: , , John Garry Subject: [PATCH RFT 3/6] scsi: pm8001: Use sas_ata_link_abort() to handle NCQ errors Date: Fri, 22 Jul 2022 19:24:06 +0800 Message-ID: <1658489049-232850-4-git-send-email-john.garry@huawei.com> X-Mailer: git-send-email 2.8.1 In-Reply-To: <1658489049-232850-1-git-send-email-john.garry@huawei.com> References: <1658489049-232850-1-git-send-email-john.garry@huawei.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.69.192.58] X-ClientProxiedBy: dggems702-chm.china.huawei.com (10.3.19.179) To lhreml724-chm.china.huawei.com (10.201.108.75) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org In commit c6b9ef5779c3 ("[SCSI] pm80xx: NCQ error handling changes") the driver had support added to handle NCQ errors but much of what is done in this handling is duplicated from the libata EH. In that named commit we handle in 2x main steps: a. Issue read log ext10 to examine and clear the errors b. Issue SATA_ABORT command Indeed, in libata EH, we do similar to above: a. ata_do_eh() -> ata_eh_autopsy() -> ata_eh_link_autopsy() -># ata_eh_analyze_ncq_error() -> ata_eh_read_log_10h() b. ata_do_eh() -> ata_eh_recover() which will issue a device soft reset or hard reset Since there is so much duplication, use sas_ata_link_abort() which will abort all pending IOs and kick off ATA EH which will do the steps, above. The pm8001_send_abort_all() call to issue the SATA_ABORT command is added in pm8001_I_T_nexus_reset() [which is called from ata_eh_recover() to issue the device reset] as there is currently no better place to locate it. In future if we add ata_port_operations.softreset callback implementation for libsas then that may be better. Signed-off-by: John Garry --- drivers/scsi/pm8001/pm8001_hwi.c | 179 ++++++++----------------------- drivers/scsi/pm8001/pm8001_sas.c | 5 + drivers/scsi/pm8001/pm8001_sas.h | 8 +- drivers/scsi/pm8001/pm80xx_hwi.c | 163 ++-------------------------- 4 files changed, 58 insertions(+), 297 deletions(-) diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index 6a88255cb3c3..bb5c0a746fff 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -1720,7 +1720,15 @@ void pm8001_work_fn(struct work_struct *work) pm8001_free_dev(pm8001_dev); } } - } break; + } + break; + case IO_XFER_ERROR_ABORTED_NCQ_MODE: + { + pm8001_dev->id |= NCQ_ERR_FLAG; + dev = pm8001_dev->sas_device; + sas_ata_link_abort(dev); + } + break; } kfree(pw); } @@ -1744,108 +1752,47 @@ int pm8001_handle_event(struct pm8001_hba_info *pm8001_ha, void *data, return ret; } -static void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, - struct pm8001_device *pm8001_ha_dev) +void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, + struct pm8001_device *pm8001_dev) { + DECLARE_COMPLETION_ONSTACK(completion); struct pm8001_ccb_info *ccb; - struct sas_task *task; struct task_abort_req task_abort; u32 opc = OPC_INB_SATA_ABORT; + struct domain_device *dev = pm8001_dev->sas_device; 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); + ccb = pm8001_ccb_alloc(pm8001_ha, pm8001_dev, NULL); + if (!ccb) 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.device_id = cpu_to_le32(pm8001_dev->device_id); task_abort.tag = cpu_to_le32(ccb->ccb_tag); - + pm8001_dev->sata_abort_all_completion = &completion; + pm8001_dev->id |= NCQ_ERR_ABORT_ALL_FLAG; ret = pm8001_mpi_build_cmd(pm8001_ha, 0, opc, &task_abort, sizeof(task_abort), 0); if (ret) { - sas_free_task(task); + pm8001_dev->sata_abort_all_completion = NULL; 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. + * It's always wise to use a timeout when dealing with HW. + * The value is abritary, same as PM8001_TASK_TIMEOUT at time of + * writing. */ - 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); - } + ret = wait_for_completion_timeout(&completion, 20 * HZ); + if (!ret) + pm8001_dbg(pm8001_ha, FAIL, "Failed to send SATA ABORT ALL:%016llx\n", + SAS_ADDR(dev->sas_addr)); + + pm8001_dev->sata_abort_all_completion = NULL; + /* Clear the flag regardless - not much else which we can do */ + pm8001_dev->id &= ~NCQ_ERR_FLAG; + pm8001_dev->id &= ~NCQ_ERR_ABORT_ALL_FLAG; } /** @@ -2297,8 +2244,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) 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; } @@ -2356,15 +2302,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb) 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; @@ -2662,9 +2599,10 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, void *piomb) 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; } @@ -3628,6 +3566,12 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) t = ccb->task; pm8001_dev = ccb->device; /* retrieve device */ + if (pm8001_dev->id & NCQ_ERR_ABORT_ALL_FLAG) { + if (pm8001_dev->sata_abort_all_completion) + complete(pm8001_dev->sata_abort_all_completion); + return 0; + } + if (!t) { pm8001_dbg(pm8001_ha, FAIL, " TASK NULL. RETURNING !!!\n"); return -1; @@ -3654,12 +3598,7 @@ int pm8001_mpi_task_abort_resp(struct pm8001_hba_info *pm8001_ha, void *piomb) 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; } @@ -4211,7 +4150,6 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, 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)); @@ -4266,39 +4204,6 @@ static int pm8001_chip_sata_req(struct pm8001_hba_info *pm8001_ha, 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); } diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index a2ccb3484f90..1e0c0e6e0277 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -818,6 +818,11 @@ int pm8001_I_T_nexus_reset(struct domain_device *dev) pm8001_dev = dev->lldd_dev; pm8001_ha = pm8001_find_ha_by_dev(dev); + + /* If in NCQ ABORT MODE then we need to issue a SATA_ABORT */ + if (pm8001_dev->id & NCQ_ERR_FLAG) + pm8001_send_abort_all(pm8001_ha, pm8001_dev); + phy = sas_get_local_phy(dev); if (dev_is_sata(dev)) { diff --git a/drivers/scsi/pm8001/pm8001_sas.h b/drivers/scsi/pm8001/pm8001_sas.h index 060ab680a7ed..b3eb4610336c 100644 --- a/drivers/scsi/pm8001/pm8001_sas.h +++ b/drivers/scsi/pm8001/pm8001_sas.h @@ -263,6 +263,7 @@ struct pm8001_device { u32 id; struct completion *dcompletion; struct completion *setds_completion; + struct completion *sata_abort_all_completion; u32 device_id; atomic_t running_req; }; @@ -576,9 +577,8 @@ struct pm8001_fw_image_header { #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 +#define NCQ_ERR_FLAG 0x20000000 +#define NCQ_ERR_ABORT_ALL_FLAG 0x40000000 /* Device states */ #define DS_OPERATIONAL 0x01 @@ -658,6 +658,8 @@ void pm8001_open_reject_retry( int pm8001_mem_alloc(struct pci_dev *pdev, void **virt_addr, dma_addr_t *pphys_addr, u32 *pphys_addr_hi, u32 *pphys_addr_lo, u32 mem_size, u32 align); +void pm8001_send_abort_all(struct pm8001_hba_info *pm8001_ha, + struct pm8001_device *pm8001_ha_dev); void pm8001_chip_iounmap(struct pm8001_hba_info *pm8001_ha); int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index d55f8b1c236d..f0c27c152d0d 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -1772,113 +1772,6 @@ pm80xx_chip_interrupt_disable(struct pm8001_hba_info *pm8001_ha, u8 vec) 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 @@ -2396,11 +2289,9 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, 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; @@ -2457,15 +2348,6 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, 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; @@ -2800,9 +2682,11 @@ static void mpi_sata_event(struct pm8001_hba_info *pm8001_ha, 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; } @@ -4525,7 +4409,6 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, 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)); cpu_id = smp_processor_id(); @@ -4704,40 +4587,6 @@ static int pm80xx_chip_sata_req(struct pm8001_hba_info *pm8001_ha, (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, -- 2.35.3