ATA DMA patch

John Baldwin <[email protected]>
Newsgroups gmane.os.freebsd.devel.alpha
Message-ID <[email protected]>
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
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-alpha
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.