[prev in list] [next in list] [prev in thread] [next in thread]
List: freebsd-alpha
Subject: ATA DMA patch
From: John Baldwin <jhb () freebsd ! org>
Date: 2007-11-28 19:03:18
Message-ID: 200711281403.18563.jhb () freebsd ! org
[Download RAW message or body]
Ok, so I have a patch for the ATA DMA problems relative to the fixes I just
checked into RELENG_6 and RELENG_6_3. I'd really like to get these tested so
that 6.3 will have working ATA DMA. I have a PWS machine locally, but it
doesn't have a UDMA controller and I wasn't able to reproduce any corruption
locally. So to test this can people first verify that they get corruption
with the existing up-to-date RELENG_6 code and then see if this patch makes it
go away? Note that the workaround is currently only enabled for the CIA
chipsets (such as in the PWS boxes). I know at least some other boxes (like
some PC164 boxes) also have an issue, but you can test those by forcing
busdma_pyxis_bug to be 1. If it does work we can come up with some way to
enable the workaround on PC164/2100, etc. boxes as well.
--- //depot/vendor/freebsd_6/src/sys/alpha/alpha/busdma_machdep.c 2007/11/27 17:47:17
+++ //depot/user/jhb/alpha_busdma/sys/alpha/alpha/busdma_machdep.c 2007/11/28 14:21:01
@@ -77,7 +77,7 @@
STAILQ_ENTRY(bounce_page) links;
};
-int busdma_swi_pending;
+int busdma_pyxis_bug, busdma_swi_pending;
static struct mtx bounce_lock;
static STAILQ_HEAD(bp_list, bounce_page) bounce_page_list;
@@ -514,6 +514,22 @@
vm_offset_t vaddr;
bus_addr_t paddr;
int seg;
+ bus_size_t boundary;
+ bus_size_t maxsegsz;
+
+ /*
+ * Enforce a boundary of 8k for buffers that aren't allocated
+ * via bus_dmamem_alloc() on systems with the Pyxis pass 1 DMA
+ * bug. This is somewhat gross.
+ */
+ boundary = dmat->boundary;
+ maxsegsz = dmat->maxsegsz;
+ if (busdma_pyxis_bug && map != &nobounce_dmamap) {
+ if (boundary == 0 || boundary > 8192)
+ boundary = 8192;
+ if (boundary < maxsegsz)
+ maxsegsz = boundary;
+ }
/*
* If we are being called during a callback, pagesneeded will
@@ -566,7 +582,7 @@
vaddr = (vm_offset_t)buf;
lastaddr = *lastaddrp;
- bmask = ~(dmat->boundary - 1);
+ bmask = ~(boundary - 1);
for (seg = *segp; buflen > 0 ; ) {
/*
@@ -587,8 +603,8 @@
/*
* Make sure we don't cross any boundaries.
*/
- if (dmat->boundary > 0) {
- baddr = (curaddr + dmat->boundary) & bmask;
+ if (boundary > 0) {
+ baddr = (curaddr + boundary) & bmask;
if (sgsize > (baddr - curaddr))
sgsize = (baddr - curaddr);
}
@@ -611,8 +627,8 @@
first = 0;
} else {
if (curaddr == lastaddr &&
- (segs[seg].ds_len + sgsize) <= dmat->maxsegsz &&
- (dmat->boundary == 0 ||
+ (segs[seg].ds_len + sgsize) <= maxsegsz &&
+ (boundary == 0 ||
(segs[seg].ds_addr & bmask) == (curaddr & bmask)))
segs[seg].ds_len += sgsize;
else {
--- //depot/vendor/freebsd_6/src/sys/alpha/include/md_var.h 2005/12/09 17:45:51
+++ //depot/user/jhb/alpha_busdma/sys/alpha/include/md_var.h 2007/11/25 14:02:05
@@ -50,6 +50,7 @@
#endif
extern long Maxmem;
extern int busdma_swi_pending;
+extern int busdma_pyxis_bug;
extern struct rpb *hwrpb;
extern volatile int mc_expected;
extern volatile int mc_received;
--- //depot/vendor/freebsd_6/src/sys/alpha/pci/cia.c 2005/12/09 17:45:51
+++ //depot/user/jhb/alpha_busdma/sys/alpha/pci/cia.c 2007/11/25 14:02:05
@@ -490,6 +490,7 @@
ctrl &= ~(CTRL_RD_TYPE|CTRL_RL_TYPE|CTRL_RM_TYPE);
REGVAL(CIA_CSR_CTRL) = ctrl;
alpha_mb();
+ busdma_pyxis_bug = 1;
}
#endif
--
John Baldwin
_______________________________________________
freebsd-alpha@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-alpha
To unsubscribe, send any mail to "freebsd-alpha-unsubscribe@freebsd.org"
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic