Re: Remaining SATA (and other) issues TAKE 2

From: Søren Schmidt <sos_at_deepcore.dk>
Date: Sun, 11 Nov 2007 11:40:08 +0100
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 
etc, sorry about that :)

Please apply to clean releng_7 sources.

Let me know how it turns out.

-Søren

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
_at__at_ -142,6 +142,7 _at__at_
 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);
_at__at_ -792,6 +793,7 _at__at_
 	    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;
 }
 
_at__at_ -2760,6 +2762,8 _at__at_
 	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
_at__at_ -3288,9 +3292,13 _at__at_
 	/* 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;
_at__at_ -3778,8 +3786,41 _at__at_
 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
_at__at_ -4849,6 +4890,8 _at__at_
 	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
_at__at_ -213,6 +213,7 _at__at_
 	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;
 }
 
Received on Sun Nov 11 2007 - 09:40:23 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:21 UTC