linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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)

  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).