From: Peter Favrholdt <linux-ide@how.dk>
To: linux-ide@vger.kernel.org
Cc: Mikael Pettersson <mikpe@it.uu.se>, Jeff Garzik <jeff@garzik.org>,
Tejun Heo <tj@kernel.org>
Subject: Re: [PATCH #upstream-fixes] sata_promise: request follow-up SRST
Date: Sun, 30 Nov 2008 16:06:23 +0100 [thread overview]
Message-ID: <4932ABEF.3080108@how.dk> (raw)
In-Reply-To: <18737.47407.218634.726384@harpo.it.uu.se>
Hi Mikael and list,
Mikael Pettersson wrote:
> Here's a patch on top of 2.6.28-rc6 that should make sata_promise's
> reset sequences a closer match to what Promise's drivers do.
> ...snip...
> Testers welcome.
I don't have physical access to my system at the moment, and some
channels/drives had already failed during previous testing. Without a
proper power-cycle the system did not recover the failed channels when
rebooted into 2.6.28-rc6 with your patch :-(
Best regards,
Peter
> --- linux-2.6.28-rc6/drivers/ata/sata_promise.c.~1~ 2008-11-29 16:05:04.000000000 +0100
> +++ linux-2.6.28-rc6/drivers/ata/sata_promise.c 2008-11-29 20:26:26.000000000 +0100
> @@ -56,6 +56,7 @@ enum {
> /* host register offsets (from host->iomap[PDC_MMIO_BAR]) */
> PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
> PDC_FLASH_CTL = 0x44, /* Flash control register */
> + PDC_PCI_CTL = 0x48, /* PCI control/status reg */
> PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
> PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */
> PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
> @@ -75,7 +76,17 @@ enum {
> PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
>
> /* per-port SATA register offsets (from ap->ioaddr.scr_addr) */
> + PDC_SATA_ERROR = 0x04,
> PDC_PHYMODE4 = 0x14,
> + PDC_LINK_LAYER_ERRORS = 0x6C,
> + PDC_FPDMA_CTLSTAT = 0xD8,
> + PDC_INTERNAL_DEBUG_1 = 0xF8, /* also used for PATA */
> + PDC_INTERNAL_DEBUG_2 = 0xFC, /* also used for PATA */
> +
> + /* PDC_FPDMA_CTLSTAT bit definitions */
> + PDC_FPDMA_CTLSTAT_RESET = 1 << 3,
> + PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG = 1 << 10,
> + PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG = 1 << 11,
>
> /* PDC_GLOBAL_CTL bit definitions */
> PDC_PH_ERR = (1 << 8), /* PCI error while loading packet */
> @@ -354,12 +365,76 @@ static int pdc_sata_port_start(struct at
> return 0;
> }
>
> +static void pdc_fpdma_clear_interrupt_flag(struct ata_port *ap)
> +{
> + void __iomem *sata_mmio = ap->ioaddr.scr_addr;
> + u32 tmp;
> +
> + tmp = readl(sata_mmio + PDC_FPDMA_CTLSTAT);
> + tmp |= PDC_FPDMA_CTLSTAT_DMASETUP_INT_FLAG;
> + tmp |= PDC_FPDMA_CTLSTAT_SETDB_INT_FLAG;
> +
> + /* It's not allowed to write to the entire FPDMA_CTLSTAT register
> + when NCQ is running. So do a byte-sized write to bits 10 and 11. */
> + writeb(tmp >> 8, sata_mmio + PDC_FPDMA_CTLSTAT + 1);
> + readb(sata_mmio + PDC_FPDMA_CTLSTAT + 1); /* flush */
> +}
> +
> +static void pdc_fpdma_reset(struct ata_port *ap)
> +{
> + void __iomem *sata_mmio = ap->ioaddr.scr_addr;
> + u8 tmp;
> +
> + tmp = (u8)readl(sata_mmio + PDC_FPDMA_CTLSTAT);
> + tmp &= 0x7F;
> + tmp |= PDC_FPDMA_CTLSTAT_RESET;
> + writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
> + readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
> + udelay(100);
> + tmp &= ~PDC_FPDMA_CTLSTAT_RESET;
> + writeb(tmp, sata_mmio + PDC_FPDMA_CTLSTAT);
> + readl(sata_mmio + PDC_FPDMA_CTLSTAT); /* flush */
> +
> + pdc_fpdma_clear_interrupt_flag(ap);
> +}
> +
> +static void pdc_not_at_command_packet_phase(struct ata_port *ap)
> +{
> + void __iomem *sata_mmio = ap->ioaddr.scr_addr;
> + unsigned int i;
> + u32 tmp;
> +
> + /* check not at ASIC packet command phase */
> + for (i = 0; i < 100; ++i) {
> + writel(0, sata_mmio + PDC_INTERNAL_DEBUG_1);
> + tmp = readl(sata_mmio + PDC_INTERNAL_DEBUG_2);
> + if ((tmp & 0xF) != 1)
> + break;
> + udelay(100);
> + }
> +}
> +
> +static void pdc_clear_internal_debug_record_error_register(struct ata_port *ap)
> +{
> + void __iomem *sata_mmio = ap->ioaddr.scr_addr;
> +
> + writel(0xffffffff, sata_mmio + PDC_SATA_ERROR);
> + writel(0xffff0000, sata_mmio + PDC_LINK_LAYER_ERRORS);
> +}
> +
> static void pdc_reset_port(struct ata_port *ap)
> {
> void __iomem *ata_ctlstat_mmio = ap->ioaddr.cmd_addr + PDC_CTLSTAT;
> unsigned int i;
> u32 tmp;
>
> + if (ap->flags & PDC_FLAG_GEN_II)
> + pdc_not_at_command_packet_phase(ap);
> +
> + tmp = readl(ata_ctlstat_mmio);
> + tmp |= PDC_RESET;
> + writel(tmp, ata_ctlstat_mmio);
> +
> for (i = 11; i > 0; i--) {
> tmp = readl(ata_ctlstat_mmio);
> if (tmp & PDC_RESET)
> @@ -374,6 +449,11 @@ static void pdc_reset_port(struct ata_po
> tmp &= ~PDC_RESET;
> writel(tmp, ata_ctlstat_mmio);
> readl(ata_ctlstat_mmio); /* flush */
> +
> + if (sata_scr_valid(&ap->link) && (ap->flags & PDC_FLAG_GEN_II)) {
> + pdc_fpdma_reset(ap);
> + pdc_clear_internal_debug_record_error_register(ap);
> + }
> }
>
> static int pdc_pata_cable_detect(struct ata_port *ap)
> @@ -706,11 +786,50 @@ static int pdc_pata_softreset(struct ata
> return ata_sff_softreset(link, class, deadline);
> }
>
> +static unsigned int pdc_ata_port_to_ata_no(const struct ata_port *ap)
> +{
> + void __iomem *ata_mmio = ap->ioaddr.cmd_addr;
> + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
> +
> + /* ata_mmio == host_mmio + 0x200 + ata_no * 0x80 */
> + return (ata_mmio - host_mmio - 0x200) / 0x80;
> +}
> +
> +static void pdc_hard_reset_port(struct ata_port *ap)
> +{
> + void __iomem *host_mmio = ap->host->iomap[PDC_MMIO_BAR];
> + void __iomem *pcictl_b1_mmio = host_mmio + PDC_PCI_CTL + 1;
> + unsigned int ata_no = pdc_ata_port_to_ata_no(ap);
> + u8 tmp;
> +
> + spin_lock(&ap->host->lock);
> +
> + tmp = readb(pcictl_b1_mmio);
> + tmp &= ~(0x10 << ata_no);
> + writeb(tmp, pcictl_b1_mmio);
> + readb(pcictl_b1_mmio); /* flush */
> + udelay(100);
> + tmp |= (0x10 << ata_no);
> + writeb(tmp, pcictl_b1_mmio);
> + readb(pcictl_b1_mmio); /* flush */
> +
> + spin_unlock(&ap->host->lock);
> +}
> +
> static int pdc_sata_hardreset(struct ata_link *link, unsigned int *class,
> unsigned long deadline)
> {
> + if (link->ap->flags & PDC_FLAG_GEN_II)
> + pdc_not_at_command_packet_phase(link->ap);
> + /* hotplug IRQs should have been masked by pdc_sata_freeze() */
> + pdc_hard_reset_port(link->ap);
> pdc_reset_port(link->ap);
> - return sata_sff_hardreset(link, class, deadline);
> +
> + /* sata_promise can't reliably acquire the first D2H Reg FIS
> + * after hardreset. Do non-waiting hardreset and request
> + * follow-up SRST.
> + */
> + return sata_std_hardreset(link, class, deadline);
> }
>
> static void pdc_error_handler(struct ata_port *ap)
next prev parent reply other threads:[~2008-11-30 15:10 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-11-13 21:21 FYI: BUG in SATA Promise 300 TX4 (2.6.24 - 2.6.27-3) w/Linux Linda Walsh
2008-11-16 6:04 ` Tejun Heo
2008-11-16 11:08 ` Mikael Pettersson
2008-11-16 14:24 ` Tejun Heo
2008-11-16 16:48 ` Brad Campbell
2008-11-17 2:01 ` Tejun Heo
2008-11-16 17:34 ` Peter Favrholdt
2008-11-16 17:39 ` Peter Favrholdt
2008-11-17 2:01 ` Tejun Heo
2008-11-17 11:47 ` Peter Favrholdt
2008-11-18 1:11 ` Tejun Heo
2008-11-18 18:03 ` Peter Favrholdt
2008-11-19 1:55 ` Tejun Heo
2008-11-20 10:22 ` Peter Favrholdt
2008-11-20 11:10 ` Mikael Pettersson
2008-11-21 4:42 ` Tejun Heo
2008-11-21 4:56 ` [PATCH #upstream-fixes] sata_promise: request follow-up SRST Tejun Heo
2008-11-22 16:30 ` Mikael Pettersson
2008-11-23 22:38 ` Peter Favrholdt
2008-11-25 13:00 ` Peter Favrholdt
2008-11-26 2:46 ` Tejun Heo
2008-11-26 8:12 ` Peter Favrholdt
2008-11-26 23:07 ` Peter Favrholdt
2008-11-25 17:27 ` Jeff Garzik
2008-11-25 21:17 ` Mikael Pettersson
2008-11-29 21:50 ` Mikael Pettersson
2008-11-30 15:06 ` Peter Favrholdt [this message]
2009-02-10 4:30 ` Jeff Garzik
2009-02-10 17:28 ` Mikael Pettersson
2009-02-10 21:13 ` Jeff Garzik
2009-02-23 12:17 ` [PATCH #upstream-fixes] sata_promise: request follow-up SRST - it works Peter Favrholdt
-- strict thread matches above, loose matches on Subject: below --
2009-09-25 5:24 [PATCH #upstream-fixes] sata_promise: request follow-up SRST Walter Hutchins
2009-09-26 2:57 ` Robert Hancock
2009-09-26 18:42 ` Walter Hutchins
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4932ABEF.3080108@how.dk \
--to=linux-ide@how.dk \
--cc=jeff@garzik.org \
--cc=linux-ide@vger.kernel.org \
--cc=mikpe@it.uu.se \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).