Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 19 Dec 2002 20:43:31 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Josef Karthauser <joe@FreeBSD.ORG>
Cc:        "Brian F. Feldman" <green@FreeBSD.ORG>, current@FreeBSD.ORG
Subject:   Re: kernel panic trying to utilize a da(4)/umass(4) device with ohci(4)
Message-ID:  <200212200443.gBK4hVUi028914@apollo.backplane.com>
References:  <200210062342.g96NgIoA001063@green.bikeshed.org> <200211171818.gAHII1WI008641@green.bikeshed.org> <20021117193722.GA35364@genius.tao.org.uk>

next in thread | previous in thread | raw e-mail | index | archive | help
   I fixed a serious DMA physical address translation bug in OHCI today.
   Look on the lists today for this message.  Message and patch enclosed.

   Note that this fixes one bug in FreeBSD's implementation and a second
   bug that is NetBSD/OpenBSD specific.  I would appreciate it if someone
   would forward this information to the NetBSD/OpenBSD folks.

   These were very serious bugs.

						-Matt

:Date: Thu, 19 Dec 2002 17:11:32 -0800 (PST)
:From: Matthew Dillon <dillon@apollo.backplane.com>
:Message-Id: <200212200111.gBK1BW0h026510@apollo.backplane.com>
:To: Nate Lawson <nate@root.org>
:Cc: freebsd-current@FreeBSD.ORG
:Subject: Re: UMASS USB bug? (getting the Sony disk-on-key device working)
:References:  <Pine.BSF.4.21.0212191442450.60085-100000@root.org>
:Sender: owner-freebsd-current@FreeBSD.ORG
:List-ID: <freebsd-current.FreeBSD.ORG>
:List-Archive: <http://docs.freebsd.org/mail/>; (Web Archive)
:List-Help: <mailto:majordomo@FreeBSD.ORG?subject=help> (List Instructions)
:List-Subscribe: <mailto:majordomo@FreeBSD.ORG?subject=subscribe%20freebsd-current>
:List-Unsubscribe: <mailto:majordomo@FreeBSD.ORG?subject=unsubscribe%20freebsd-current>
:X-Loop: FreeBSD.ORG
:Precedence: bulk
:...
:

Index: ohci.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ohci.c,v
retrieving revision 1.116
diff -u -r1.116 ohci.c
--- ohci.c	9 Dec 2002 01:41:24 -0000	1.116
+++ ohci.c	20 Dec 2002 01:02:11 -0000
@@ -493,17 +493,17 @@
 	u_int32_t intr, tdflags;
 	int offset = 0;
 	int len, curlen;
+	int orig_len;
 	usb_dma_t *dma = &xfer->dmabuf;
 	u_int16_t flags = xfer->flags;
 
 	DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen));
 
-	len = alen;
+	orig_len = len = alen;
 	cur = sp;
 
-
 	dataphys = DMAADDR(dma, 0);
-	dataphysend = OHCI_PAGE(dataphys + len - 1);
+	dataphysend = OHCI_PAGE(DMAADDR(dma, len - 1));
 	tdflags = htole32(
 	    (rd ? OHCI_TD_IN : OHCI_TD_OUT) |
 	    (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) |
@@ -518,8 +518,8 @@
 
 		/* The OHCI hardware can handle at most one page crossing. */
 #if defined(__NetBSD__) || defined(__OpenBSD__)
-		if (OHCI_PAGE(dataphys) == OHCI_PAGE(dataphysend) ||
-		    OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == OHCI_PAGE(dataphysend))
+		if (OHCI_PAGE(dataphys) == dataphysend ||
+		    OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend)
 #elif defined(__FreeBSD__)
 		/* XXX This is pretty broken: Because we do not allocate
 		 * a contiguous buffer (contiguous in physical pages) we
@@ -527,7 +527,7 @@
 		 * So check whether the start and end of the buffer are on
 		 * the same page.
 		 */
-		if (OHCI_PAGE(dataphys) == OHCI_PAGE(dataphysend))
+		if (OHCI_PAGE(dataphys) == dataphysend)
 #endif
 		{
 			/* we can handle it in this TD */
@@ -544,6 +544,8 @@
 			/* must use multiple TDs, fill as much as possible. */
 			curlen = 2 * OHCI_PAGE_SIZE -
 				 OHCI_PAGE_MASK(dataphys);
+			if (curlen > len)	/* may have fit in one page */
+				curlen = len;
 #elif defined(__FreeBSD__)
 			/* See comment above (XXX) */
 			curlen = OHCI_PAGE_SIZE -
@@ -568,6 +570,9 @@
 			    dataphys, dataphys + curlen - 1));
 		if (len == 0)
 			break;
+		if (len < 0)
+			panic("Length went negative: %d curlen %d (dma %p offset %08x dataphysend %p currentdataphysend %p", len, curlen, *dma, (int)offset, (void *)dataphysend, (void *)OHCI_PAGE(DMAADDR(dma,0) + orig_len - 1));
+
 		DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
 		offset += curlen;
 		cur = next;

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200212200443.gBK4hVUi028914>