alpha/75317: ATA DMA broken on PCalpha
Sven Petai
hadara at bsd.ee
Mon Dec 20 08:40:13 PST 2004
>Number: 75317
>Category: alpha
>Synopsis: ATA DMA broken on PCalpha
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: freebsd-alpha
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Dec 20 16:40:12 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Sven Petai
>Release: FreeBSD 6.0-CURRENT
>Organization:
NPO BSD Estonia
>Environment:
>Description:
Machine fails to boot with various different symptoms after mounting root, sometimes
it hangs, sometimes it gets machine check etc. I traced it down to introduction
of version 1.129 of the file src/sys/dev/ata/ata-dma.c which among other changes removes code
that did split up segments into page sized chunks to avoid running into some kind
of bug in busdma. it was commented as:
"A maximum segment size was specified for bus_dma_tag_create, but
some busdma code does not seem to honor this, so fix up if needed."
>How-To-Repeat:
Just try to boot fbsd 5.3 release on similar hardware.
>Fix:
easy & ugly workaround is to just disable ata dma from the loader with
set hw.ata.ata_dma=0
maybe a little bit better workaround is following patch, which just reverts to
previous behaviour:
--- sys/dev/ata/ata-dma.c.orig Mon Dec 20 08:27:25 2004
+++ sys/dev/ata/ata-dma.c Mon Dec 20 08:47:15 2004
@@ -198,16 +198,22 @@
{
struct ata_dmasetprd_args *args = xsc;
struct ata_dma_prdentry *prd = args->dmatab;
- int i;
+ int i,j;
+ bus_size_t cnt;
+ u_int32_t lastcount;
if ((args->error = error))
return;
+ lastcount = j = 0;
for (i = 0; i < nsegs; i++) {
- prd[i].addr = htole32(segs[i].ds_addr);
- prd[i].count = htole32(segs[i].ds_len);
+ for (cnt = 0; cnt < segs[i].ds_len; cnt += PAGE_SIZE, j++) {
+ prd[j].addr = htole32(segs[i].ds_addr + cnt);
+ lastcount = ulmin(segs[i].ds_len - cnt, PAGE_SIZE) & 0xffff;
+ prd[j].count = htole32(lastcount);
+ }
}
- prd[i - 1].count |= htole32(ATA_DMA_EOT);
+ prd[j - 1].count |= htole32(lastcount | ATA_DMA_EOT);
}
static int
of course the real solution should be finding and fixing the bug in busdma code.
>Release-Note:
>Audit-Trail:
>Unformatted:
>System: FreeBSD alpha 6.0-CURRENT FreeBSD 6.0-CURRENT #23: Mon Dec 20 05:07:30 EET 2004 root at alpha:/mnt/disk/obj/usr/src/sys/HADARA alpha
dmesg can be found @ http://bsd.ee/~hadara/debug/pcalpha/kernel.txt
but relevant details of it should be:
Digital AlphaPC 164LX 533 MHz, 531MHz
8192 byte page size, 1 processor.
...
ad0: 1226MB <FUJITSU M1636TAU/5045> [2491/16/63] at ata0-master WDMA2
ad1: 3052MB <SAMSUNG SV0322A/JK200-36> [11024/9/63] at ata0-slave WDMA2
...
this is IDE only machine
More information about the freebsd-alpha
mailing list