From nobody@FreeBSD.org  Thu Aug  9 06:07:28 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6037016A417
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  9 Aug 2007 06:07:28 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 4F78B13C4DA
	for <freebsd-gnats-submit@FreeBSD.org>; Thu,  9 Aug 2007 06:07:28 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l7967R69093962
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 9 Aug 2007 06:07:27 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.1/8.14.1/Submit) id l7967RoC093961;
	Thu, 9 Aug 2007 06:07:27 GMT
	(envelope-from nobody)
Message-Id: <200708090607.l7967RoC093961@www.freebsd.org>
Date: Thu, 9 Aug 2007 06:07:27 GMT
From: Sverre Svenningsen <ss.alert@online.no>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Promise SATA300 TX4 breaks with zfs in 7.0-current
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         115337
>Category:       kern
>Synopsis:       [ata] Promise SATA300 TX4 breaks with zfs in 7.0-current
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    sos
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Aug 09 06:10:01 GMT 2007
>Closed-Date:    Tue Dec 25 12:23:35 UTC 2007
>Last-Modified:  Tue Dec 25 12:23:35 UTC 2007
>Originator:     Sverre Svenningsen
>Release:        7.0-CURRENT
>Organization:
>Environment:
FreeBSD nemesis.apalveien.net 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Sat Jun  2 23:20:29 CEST 2007     ssvenn@nemesis.apalveien.net:/usr/obj/usr/src/sys/NEMESIS  i386
>Description:
Promise SATA300 TX4 support (and possibly other similar chipsets) are
broken in the current source, but works fine in the 2007-06 snapshot.
Depending on your hardware setup it appears to generate lots of read/
write errors. In some cases the machine will silently lock up.

freebsd-current mailing list shows that several other users experience
the same thing

http://www.nabble.com/Promise-SATA300-TX4-card-issues-t3955951.html
http://lists.freebsd.org/pipermail/freebsd-current/2007-August/075992.html

NOTE: build date on my kernel is from before the issue arised. I had to
revert to an earlier build to stop the machine from locking up every few
minutes.


>How-To-Repeat:
cvsup to current kernel and world, enable zfs and try things like creating
a raidz pool, copying large amounts of data etc. must use promise sata card.
>Fix:


>Release-Note:
>Audit-Trail:

From: Alexander Sabourenkov <screwdriver@lxnt.info>
To: bug-followup@FreeBSD.org
Cc: ss.alert@online.no
Subject: Re: kern/115337: [ata] Promise SATA300 TX4 breaks with zfs in 7.0-current
Date: Wed, 31 Oct 2007 13:57:45 +0300

 I'm currently working on this, after fixing similar issue in Linux.
 
 
 See this:
 http://lists.freebsd.org/pipermail/freebsd-stable/2007-October/037795.html
 
 After second glance on the code it now seems that the way to go is to 
 make an ata_promise_begin_transaction() modeled after 
 ata_ahci_begin_transaction().
 
 If you have any comments on how to proceed with implementing the 
 workaround, please let me know.
 
 -- 
 
 ./lxnt

From: Alexander Sabourenkov <screwdriver@lxnt.info>
To: bug-followup@FreeBSD.org
Cc: ss.alert@online.no
Subject: Re: kern/115337: [ata] Promise SATA300 TX4 breaks with zfs in 7.0-current
Date: Fri, 02 Nov 2007 01:37:18 +0300

 I have ported the workaround for the hardware bug that causes data
 corruption on Promise SATA300 TX4 cards to RELENG_7.
 
 Bug description:
 SATA300 TX4 hardware chokes if last PRD entry (in a dma transfer) is
 larger than 164 bytes. This was found while analysing vendor-supplied
 linux driver.
 
 Workaround:
 Split trailing PRD entry if it's larger that 164 bytes.
 
 Two supplied patches do fix problem on my machine.
 
 There is, however, a style problem with them. It seems like PRD entry
 count is limited at 256. I have not found a good way to guarantee that
 one entry is always available to do the split, thus the ugly solution of
 patching ata-dma.c.
 
 
 Patches, patched and original files are at http://lxnt.info/tx4/freebsd/.
 
 
 --- ata-chipset.c.orig	2007-11-02 01:05:49.000000000 +0300
 +++ ata-chipset.c	2007-11-02 01:05:49.000000000 +0300
 @@ -142,6 +142,7 @@
  static int ata_promise_mio_command(struct ata_request *request);
  static void ata_promise_mio_reset(device_t dev);
  static void ata_promise_mio_dmainit(device_t dev);
 +static void ata_promise_mio_dmasetprd(void *xsc, bus_dma_segment_t
 *segs, int nsegs, int error);
  static void ata_promise_mio_setmode(device_t dev, int mode);
  static void ata_promise_sx4_intr(void *data);
  static int ata_promise_sx4_command(struct ata_request *request);
 @@ -185,7 +186,6 @@
  static int ata_check_80pin(device_t dev, int mode);
  static int ata_mode2idx(int mode);
 
 -
  /*
   * generic ATA support functions
   */
 @@ -3759,8 +3759,44 @@
  static void
  ata_promise_mio_dmainit(device_t dev)
  {
 +    struct ata_channel *ch = device_get_softc(dev);
 +	
      /* note start and stop are not used here */
      ata_dmainit(dev);
 +
 +    if (ch->dma)
 +	ch->dma->setprd = ata_promise_mio_dmasetprd;
 +}
 +
 +static void
 +ata_promise_mio_dmasetprd(void *xsc, bus_dma_segment_t *segs, int
 nsegs, int error)
 +{
 +    #define PDC_MAXLASTSGSIZE 41*4
 +    struct ata_dmasetprd_args *args = xsc;
 +    struct ata_dma_prdentry *prd = args->dmatab;
 +    int i;
 +
 +    if ((args->error = error))
 +	return;
 +
 +    for (i = 0; i < nsegs; i++) {
 +	prd[i].addr = htole32(segs[i].ds_addr);
 +	prd[i].count = htole32(segs[i].ds_len);
 +    }
 +
 +    if (segs[i - 1].ds_len > PDC_MAXLASTSGSIZE) {
 +	/*
 +	printf("splitting trailing PRD of %ld (limit %d)\n", segs[i -
 1].ds_len, PDC_MAXLASTSGSIZE);
 +	*/
 +	prd[i - 1].count = htole32(segs[i - 1].ds_len - PDC_MAXLASTSGSIZE);
 +	prd[i].count = htole32(PDC_MAXLASTSGSIZE);
 +	prd[i].addr = htole32(segs[i - 1].ds_addr + PDC_MAXLASTSGSIZE);
 +	i ++;
 +	nsegs ++;
 +    }
 +
 +    prd[i - 1].count |= htole32(ATA_DMA_EOT);
 +    args->nsegs = nsegs;
  }
 
  static void
 
 --- ata-dma.c.orig	2007-11-02 01:05:53.000000000 +0300
 +++ ata-dma.c	2007-11-02 01:05:53.000000000 +0300
 @@ -113,7 +113,7 @@
      if
 (bus_dma_tag_create(ch->dma->dmatag,ch->dma->alignment,ch->dma->boundary,
  			   ch->dma->max_address, BUS_SPACE_MAXADDR,
  			   NULL, NULL, ch->dma->max_iosize,
 -			   ATA_DMA_ENTRIES, ch->dma->segsize,
 +			   ATA_DMA_ENTRIES - 1, ch->dma->segsize,
  			   0, NULL, NULL, &ch->dma->data_tag))
  	goto error;
 
 
 -- 
 
 ./lxnt
 
Responsible-Changed-From-To: freebsd-bugs->sos 
Responsible-Changed-By: kris 
Responsible-Changed-When: Tue Dec 25 12:14:07 UTC 2007 
Responsible-Changed-Why:  
Contains patch for evaluation 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115337 
State-Changed-From-To: open->closed 
State-Changed-By: kris 
State-Changed-When: Tue Dec 25 12:23:20 UTC 2007 
State-Changed-Why:  
sos confirms this was previously fixed 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115337 
>Unformatted:
