From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932111AbcAXWDK (ORCPT ); Sun, 24 Jan 2016 17:03:10 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:60472 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753538AbcAXWBz (ORCPT ); Sun, 24 Jan 2016 17:01:55 -0500 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Cc: Xiangliang Yu , Tejun Heo , Luis Henriques Subject: [PATCH 3.16.y-ckt 010/128] AHCI: Fix softreset failed issue of Port Multiplier Date: Sun, 24 Jan 2016 21:59:25 +0000 Message-Id: <1453672883-2708-11-git-send-email-luis.henriques@canonical.com> In-Reply-To: <1453672883-2708-1-git-send-email-luis.henriques@canonical.com> References: <1453672883-2708-1-git-send-email-luis.henriques@canonical.com> X-Extended-Stable: 3.16 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.7-ckt23 -stable review patch. If anyone has any objections, please let me know. ---8<------------------------------------------------------------ From: Xiangliang Yu commit 023113d24ef9e1d2b44cb2446872b17e2b01d8b1 upstream. Current code doesn't update port value of Port Multiplier(PM) when sending FIS of softreset to device, command will fail if FBS is enabled. There are two ways to fix the issue: the first is to disable FBS before sending softreset command to PM device and the second is to update port value of PM when sending command. For the first way, i can't find any related rule in AHCI Spec. The second way can avoid disabling FBS and has better performance. Signed-off-by: Xiangliang Yu Signed-off-by: Tejun Heo Signed-off-by: Luis Henriques --- drivers/ata/libahci.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 86c3c24b835f..a0bfdcfafd92 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -1271,6 +1271,15 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp, ata_tf_to_fis(tf, pmp, is_cmd, fis); ahci_fill_cmd_slot(pp, 0, cmd_fis_len | flags | (pmp << 12)); + /* set port value for softreset of Port Multiplier */ + if (pp->fbs_enabled && pp->fbs_last_dev != pmp) { + tmp = readl(port_mmio + PORT_FBS); + tmp &= ~(PORT_FBS_DEV_MASK | PORT_FBS_DEC); + tmp |= pmp << PORT_FBS_DEV_OFFSET; + writel(tmp, port_mmio + PORT_FBS); + pp->fbs_last_dev = pmp; + } + /* issue & wait */ writel(1, port_mmio + PORT_CMD_ISSUE);