From patchwork Tue Sep 15 13:07:32 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Pettersson X-Patchwork-Id: 33652 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by bilbo.ozlabs.org (Postfix) with ESMTP id 7D64EB7B6B for ; Tue, 15 Sep 2009 23:29:13 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753683AbZION17 (ORCPT ); Tue, 15 Sep 2009 09:27:59 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753878AbZION17 (ORCPT ); Tue, 15 Sep 2009 09:27:59 -0400 Received: from fanny.its.uu.se ([130.238.4.241]:43041 "EHLO fanny.its.uu.se" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753683AbZION17 (ORCPT ); Tue, 15 Sep 2009 09:27:59 -0400 X-Greylist: delayed 1219 seconds by postgrey-1.27 at vger.kernel.org; Tue, 15 Sep 2009 09:27:58 EDT Received: by fanny.its.uu.se (Postfix, from userid 212) id B27CA63DD; Tue, 15 Sep 2009 15:07:41 +0200 (MSZ) X-Spam-Checker-Version: SpamAssassin 3.1.9 (2007-02-13) on spamass.its.uu.se X-Spam-Level: X-Spam-Status: No, score=-1.2 required=5.0 tests=ALL_TRUSTED,AWL autolearn=disabled version=3.1.9 Received: from pilspetsen.it.uu.se (pilspetsen.it.uu.se [130.238.18.39]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by fanny.its.uu.se (Postfix) with ESMTP id D4215636F; Tue, 15 Sep 2009 15:07:33 +0200 (MSZ) Received: (from mikpe@localhost) by pilspetsen.it.uu.se (8.13.8+Sun/8.13.8) id n8FD7Wsi015406; Tue, 15 Sep 2009 15:07:32 +0200 (MEST) X-Authentication-Warning: pilspetsen.it.uu.se: mikpe set sender to mikpe@it.uu.se using -f MIME-Version: 1.0 Message-ID: <19119.37268.448603.191642@pilspetsen.it.uu.se> Date: Tue, 15 Sep 2009 15:07:32 +0200 From: Mikael Pettersson To: Jeff Garzik Subject: [PATCH 2.6.31] sata_promise: disable hotplug on 1st gen chips Cc: Kurt Roeckx , linux-ide@vger.kernel.org X-Mailer: VM 7.17 under Emacs 20.7.1 Sender: linux-ide-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ide@vger.kernel.org 1st generation Promise SATA chips are prone to generating spurious hotplug events which can disrupt normal operation. This has been observed on 20376 and 20378 chips. This patch thus disables hotplug support on 1st gen chips while leaving it enabled for 2nd gen chips. The pdc_sata_hotplug_offset() function becomes redundant so it is removed. Tested on 1st gen 20376 and 20378 mainboard chips and on a 2nd gen SATA300 PCI card. Signed-off-by: Mikael Pettersson Tested-by: Kurt Roeckx --- Kurt: you tested this so I added your Tested-by, I hope that's Ok? Jeff: this is a safe patch that I think should go to -stable soonish drivers/ata/sata_promise.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ide" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff -rupN linux-2.6.31/drivers/ata/sata_promise.c linux-2.6.31.sata_promise-disable-gen1-hotplug/drivers/ata/sata_promise.c --- linux-2.6.31/drivers/ata/sata_promise.c 2009-06-10 12:00:44.000000000 +0200 +++ linux-2.6.31.sata_promise-disable-gen1-hotplug/drivers/ata/sata_promise.c 2009-09-10 14:07:17.000000000 +0200 @@ -195,9 +195,12 @@ static struct ata_port_operations pdc_sa .hardreset = pdc_sata_hardreset, }; -/* First-generation chips need a more restrictive ->check_atapi_dma op */ +/* First-generation chips need a more restrictive ->check_atapi_dma op, + and ->freeze/thaw that ignore the hotplug controls. */ static struct ata_port_operations pdc_old_sata_ops = { .inherits = &pdc_sata_ops, + .freeze = pdc_freeze, + .thaw = pdc_thaw, .check_atapi_dma = pdc_old_sata_check_atapi_dma, }; @@ -626,11 +629,6 @@ static unsigned int pdc_sata_ata_port_to return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags)); } -static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap) -{ - return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR; -} - static void pdc_freeze(struct ata_port *ap) { void __iomem *ata_mmio = ap->ioaddr.cmd_addr; @@ -647,7 +645,7 @@ static void pdc_sata_freeze(struct ata_p { struct ata_host *host = ap->host; void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; - unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); + unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR; unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); u32 hotplug_status; @@ -685,7 +683,7 @@ static void pdc_sata_thaw(struct ata_por { struct ata_host *host = ap->host; void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR]; - unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap); + unsigned int hotplug_offset = PDC2_SATA_PLUG_CSR; unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap); u32 hotplug_status; @@ -832,14 +830,14 @@ static irqreturn_t pdc_interrupt(int irq spin_lock(&host->lock); /* read and clear hotplug flags for all ports */ - if (host->ports[0]->flags & PDC_FLAG_GEN_II) + if (host->ports[0]->flags & PDC_FLAG_GEN_II) { hotplug_offset = PDC2_SATA_PLUG_CSR; - else - hotplug_offset = PDC_SATA_PLUG_CSR; - hotplug_status = readl(host_mmio + hotplug_offset); - if (hotplug_status & 0xff) - writel(hotplug_status | 0xff, host_mmio + hotplug_offset); - hotplug_status &= 0xff; /* clear uninteresting bits */ + hotplug_status = readl(host_mmio + hotplug_offset); + if (hotplug_status & 0xff) + writel(hotplug_status | 0xff, host_mmio + hotplug_offset); + hotplug_status &= 0xff; /* clear uninteresting bits */ + } else + hotplug_status = 0; /* reading should also clear interrupts */ mask = readl(host_mmio + PDC_INT_SEQMASK); @@ -1034,9 +1032,11 @@ static void pdc_host_init(struct ata_hos tmp = readl(host_mmio + hotplug_offset); writel(tmp | 0xff, host_mmio + hotplug_offset); - /* unmask plug/unplug ints */ tmp = readl(host_mmio + hotplug_offset); - writel(tmp & ~0xff0000, host_mmio + hotplug_offset); + if (is_gen2) /* unmask plug/unplug ints */ + writel(tmp & ~0xff0000, host_mmio + hotplug_offset); + else /* mask plug/unplug ints */ + writel(tmp | 0xff0000, host_mmio + hotplug_offset); /* don't initialise TBG or SLEW on 2nd generation chips */ if (is_gen2)