linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff Garzik <jeff@garzik.org>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Bernd Schubert <bs@q-leap.de>,
	linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] faster workaround
Date: Thu, 11 Oct 2007 10:19:37 -0400	[thread overview]
Message-ID: <470E30F9.5060705@garzik.org> (raw)
In-Reply-To: <20071011142628.48272a4a@the-village.bc.nu>

Alan Cox wrote:
>> -static void ata_fill_sg(struct ata_queued_cmd *qc)
>> +void ata_fill_sg(struct ata_queued_cmd *qc)
>>  {
>>  	struct ata_port *ap = qc->ap;
>>  	struct scatterlist *sg;
>> @@ -4217,10 +4217,15 @@ int ata_check_atapi_dma(struct ata_queue
>>   */
>>  void ata_qc_prep(struct ata_queued_cmd *qc)
>>  {
>> +	struct ata_port *ap = qc->ap;
>> +
>>  	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
>>  		return;
>>  
>> -	ata_fill_sg(qc);
>> +	if (ap->ops->fill_sg)
>> +		ap->ops->fill_sg(qc);
>> +	else
>> +		ata_fill_sg(qc);
>>  }
> 
> Its probably better to simply make your own sil_qc_prep function for this
> case rather than touch the core code.
> 
>> -	.sg_tablesize		= LIBATA_MAX_PRD,
>> +	.sg_tablesize		= 120, /* max 15 kiB sectors ? */
> 
> If you are just fiddling with the way the data is split then
> LIBATA_MAX_PRD - 1 should be totally safe)
> 
>>  	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
>>  	.emulated		= ATA_SHT_EMULATED,
>> -	.use_clustering		= ATA_SHT_USE_CLUSTERING,
>> +	.use_clustering		= 1,
> 
> Un-needed
> 
>>  	.proc_name		= DRV_NAME,
>> -	.dma_boundary		= ATA_DMA_BOUNDARY,
>> +	.dma_boundary		= 0x1fff,
> 
> Ok
> 
>>  	.slave_configure	= ata_scsi_slave_config,
>>  	.slave_destroy		= ata_scsi_slave_destroy,
>>  	.bios_param		= ata_std_bios_param,
> 
>> +	/* Errata workaround: if last segment is exactly 8K, split
>> +	 * into 7.5K and 512b pieces.
>> +	 */
>> +	len = le32_to_cpu(ap->prd[idx].flags_len) & 0xffff;
>> +	if (len == 8192) {
>> +		addr = le32_to_cpu(ap->prd[idx].addr);
>> +		ap->prd[idx].flags_len = cpu_to_le32(15 * 512);
>> +
>> +		idx++;
>> +		ap->prd[idx].addr = cpu_to_le32(addr + (15 * 512));
>> +		ap->prd[idx].flags_len = cpu_to_le32(512 | ATA_PRD_EOT);
>> +	}
>> +}
> 
> And since in this approach we are merely splitting the last PRD entry in
> some obscure cases we might as well do it by default as it should have no
> performance impact of any note done this way.

Unfortunately all this stuff is quite meaningless, which was why my 
patch was never merged.

The problem is that the 3112 generates Data FIS's of a size other than a 
multiple of 512 bytes.  Spec-legal, but exposed firmware bugs in many 
early SATA drives.  Early Seagate hard drives choked when the formula 
(sector%15)==1 was satisfied (or something along those lines).

The problem with the fix is that Data FIS size is only roughly 
correlated to PRD segment length or DMA boundary -- the chip could 
decide to send out a frame even if the PRD length is < 8K.  The 3112 can 
generate not-512b-sized FIS's at any time, not just at the end of the 
transfer.

That leaves us with two observations:

1) Just about the only valid optimization is to ensure that only the 
write path must be limited to small chunks, not both read- and 
write-paths.  Tejun had a patch to do this a long time ago, but it's an 
open question whether the large amount of code is worth it for a rare 
combination.

2) Once we identified, over time, the set of drives affected by this 
3112 quirk (aka drives that didn't fully comply to SATA spec), the 
debugging of corruption cases largely shifted to the standard routine: 
update the BIOS, replace the cables/RAM/power/mainboard/slot/etc. to be 
certain of problem location.

	Jeff



  reply	other threads:[~2007-10-11 14:19 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-08 15:09 sil3114 data corruption Bernd Schubert
2007-10-10  9:12 ` Bernd Schubert
2007-10-11 12:09   ` [PATCHES] " Bernd Schubert
2007-10-11 12:15     ` [PATCH 1/3] " Bernd Schubert
2007-10-11 12:20       ` [PATCH 2/3] " Bernd Schubert
2007-10-11 12:33     ` [PATCH 3/3] faster workaround Bernd Schubert
2007-10-11 13:26       ` Alan Cox
2007-10-11 14:19         ` Jeff Garzik [this message]
2007-10-11 14:39           ` Bernd Schubert
2007-10-11 15:04             ` Jeff Garzik
2007-10-11 15:18               ` Bernd Schubert
2007-10-12 21:08                 ` Jeff Garzik
2007-10-15 10:18                   ` Bernd Schubert
2007-10-11 14:50           ` Alan Cox
2007-10-11 14:59             ` Jeff Garzik
2007-10-23  8:08               ` Tejun Heo
2007-10-23 17:28                 ` Bernd Schubert
2007-10-24 13:39                 ` Soeren Sonnenburg

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=470E30F9.5060705@garzik.org \
    --to=jeff@garzik.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=bs@q-leap.de \
    --cc=linux-ide@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.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).