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