From patchwork Thu Dec 13 04:46:03 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [3.5.y.z, extended, stable] Patch "sata_svw: check DMA start bit before reset" has been added to staging queue X-Patchwork-Submitter: Herton Ronaldo Krzesinski X-Patchwork-Id: 205726 Message-Id: <1355373963-2986-1-git-send-email-herton.krzesinski@canonical.com> To: David Milburn Cc: kernel-team@lists.ubuntu.com, Jeff Garzik Date: Thu, 13 Dec 2012 02:46:03 -0200 From: Herton Ronaldo Krzesinski List-Id: Kernel team discussions This is a note to let you know that I have just added a patch titled sata_svw: check DMA start bit before reset to the linux-3.5.y-queue branch of the 3.5.y.z extended stable tree which can be found at: http://kernel.ubuntu.com/git?p=ubuntu/linux.git;a=shortlog;h=refs/heads/linux-3.5.y-queue If you, or anyone else, feels it should not be added to this tree, please reply to this email. For more information about the 3.5.y.z tree, see https://wiki.ubuntu.com/Kernel/Dev/ExtendedStable Thanks. -Herton ------ >From 32c3da87d03d47b50ce5580ca2a0898b6986606c Mon Sep 17 00:00:00 2001 From: David Milburn Date: Mon, 29 Oct 2012 18:00:22 -0500 Subject: [PATCH 07/20] sata_svw: check DMA start bit before reset commit b03e66a6be91f8389fcd902ab6c1563db1c9c06b upstream. If kdump is triggered with pending IO, controller may not respond causing kdump to fail. http://marc.info/?l=linux-ide&m=133032255424658&w=2 During error recovery ata_do_dev_read_id never completes due hang in mmio_insw. ata_do_dev_read_id ata_sff_data_xfer ioread16_rep mmio_insw if DMA start bit is cleared before reset, PIO command is successful and kdump succeeds. Signed-off-by: David Milburn Signed-off-by: Jeff Garzik Signed-off-by: Herton Ronaldo Krzesinski --- drivers/ata/sata_svw.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) -- 1.7.9.5 diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c index c646118..833607f 100644 --- a/drivers/ata/sata_svw.c +++ b/drivers/ata/sata_svw.c @@ -142,6 +142,39 @@ static int k2_sata_scr_write(struct ata_link *link, return 0; } +static int k2_sata_softreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return ata_sff_softreset(link, class, deadline); +} + +static int k2_sata_hardreset(struct ata_link *link, + unsigned int *class, unsigned long deadline) +{ + u8 dmactl; + void __iomem *mmio = link->ap->ioaddr.bmdma_addr; + + dmactl = readb(mmio + ATA_DMA_CMD); + + /* Clear the start bit */ + if (dmactl & ATA_DMA_START) { + dmactl &= ~ATA_DMA_START; + writeb(dmactl, mmio + ATA_DMA_CMD); + } + + return sata_sff_hardreset(link, class, deadline); +} static void k2_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { @@ -346,6 +379,8 @@ static struct scsi_host_template k2_sata_sht = { static struct ata_port_operations k2_sata_ops = { .inherits = &ata_bmdma_port_ops, + .softreset = k2_sata_softreset, + .hardreset = k2_sata_hardreset, .sff_tf_load = k2_sata_tf_load, .sff_tf_read = k2_sata_tf_read, .sff_check_status = k2_stat_check_status,