Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 11 Nov 2007 11:40:08 +0100
From:      =?ISO-8859-1?Q?S=F8ren_Schmidt?= <sos@deepcore.dk>
To:        Alexander Sabourenkov <screwdriver@lxnt.info>
Cc:        Nathan Butcher <n-butcher@fusiongol.com>, freebsd-current@freebsd.org
Subject:   Re: Remaining SATA (and other) issues TAKE 2
Message-ID:  <4736DC08.3030809@deepcore.dk>
In-Reply-To: <4732E7C2.3030403@lxnt.info>
References:  <47326FB8.50602@fusiongol.com> <4732CEE3.3070003@lxnt.info> <4732DA32.3090601@deepcore.dk> <4732E18A.6040802@lxnt.info> <4732E37F.9020707@deepcore.dk> <4732E7C2.3030403@lxnt.info>

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------050407030106060702030805
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: quoted-printable

Hi All

Alexander found the bug causing the data to be offset wrongly in my last =

patch, this new one should fix that so we dont get disappearing nodes=20
etc, sorry about that :)

Please apply to clean releng_7 sources.

Let me know how it turns out.

-S=F8ren

--------------050407030106060702030805
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
	name="promise-fix2"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="promise-fix2"

Index: ata-chipset.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-chipset.c,v
retrieving revision 1.202.2.2
diff -u -r1.202.2.2 ata-chipset.c
--- ata-chipset.c	31 Oct 2007 19:59:53 -0000	1.202.2.2
+++ ata-chipset.c	8 Nov 2007 20:15:48 -0000
@@ -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_setprd(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);
@@ -792,6 +793,7 @@
 	    prd[i].dbc = htole32((segs[i].ds_len - 1) & ATA_AHCI_PRD_MASK);
 	}
     }
+    KASSERT(nsegs <= ATA_DMA_ENTRIES, "too many DMA segment entries\n");
     args->nsegs = nsegs;
 }
 
@@ -2760,6 +2762,8 @@
 	prd[i].addrhi = htole32((u_int64_t)segs[i].ds_addr >> 32);
     }
     prd[i - 1].count |= htole32(ATA_DMA_EOT);
+    KASSERT(nsegs <= ATA_DMA_ENTRIES, "too many DMA segment entries\n");
+    args->nsegs = nsegs;
 }
 
 static void
@@ -3288,9 +3292,13 @@
 	/* prime fake interrupt register */
 	ATA_OUTL(ctlr->r_res2, fake_reg, 0xffffffff);
 
-	/* clear SATA status */
+	/* clear SATA status and unmask interrupts */
 	ATA_OUTL(ctlr->r_res2, stat_reg, 0x000000ff);
 
+	/* enable "long burst lenght" on gen2 chips */
+	if ((ctlr->chip->cfg2 == PRSATA2) || (ctlr->chip->cfg2 == PRCMBO2))
+	    ATA_OUTL(ctlr->r_res2, 0x44, ATA_INL(ctlr->r_res2, 0x44) | 0x2000);
+
 	ctlr->allocate = ata_promise_mio_allocate;
 	ctlr->reset = ata_promise_mio_reset;
 	ctlr->dmainit = ata_promise_mio_dmainit;
@@ -3778,8 +3786,41 @@
 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_setprd;
+}
+
+
+#define MAXLASTSGSIZE (32 * sizeof(u_int32_t))
+static void 
+ata_promise_mio_setprd(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
+{
+    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 > MAXLASTSGSIZE) {
+	//printf("split last SG element of %u\n", segs[i - 1].ds_len);
+	prd[i - 1].count = htole32(segs[i - 1].ds_len - MAXLASTSGSIZE);
+	prd[i].count = htole32(MAXLASTSGSIZE);
+	prd[i].addr = htole32(segs[i - 1].ds_addr + (segs[i - 1].ds_len - MAXLASTSGSIZE));
+	nsegs++;
+	i++;
+    }
+    prd[i - 1].count |= htole32(ATA_DMA_EOT);
+    KASSERT(nsegs <= ATA_DMA_ENTRIES, "too many DMA segment entries\n");
+    args->nsegs = nsegs;
 }
 
 static void
@@ -4849,6 +4890,8 @@
 	prd[i].count = htole32(segs[i].ds_len);
     }
     prd[i - 1].control = htole32(ATA_DMA_EOT);
+    KASSERT(nsegs <= ATA_DMA_ENTRIES, "too many DMA segment entries\n");
+    args->nsegs = nsegs;
 }
 
 static void
Index: ata-dma.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/ata/ata-dma.c,v
retrieving revision 1.147
diff -u -r1.147 ata-dma.c
--- ata-dma.c	8 Apr 2007 21:53:52 -0000	1.147
+++ ata-dma.c	8 Nov 2007 20:15:48 -0000
@@ -213,6 +213,7 @@
 	prd[i].count = htole32(segs[i].ds_len);
     }
     prd[i - 1].count |= htole32(ATA_DMA_EOT);
+    KASSERT(nsegs <= ATA_DMA_ENTRIES, "too many DMA segment entries\n");
     args->nsegs = nsegs;
 }
 

--------------050407030106060702030805--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4736DC08.3030809>