Module Name:    src
Committed By:   tsutsui
Date:           Fri Feb  1 12:53:47 UTC 2013

Modified Files:
        src/sys/dev/usb: ehci.c uhci.c

Log Message:
Call usb_syncmem() against descriptors more strictly.
(not sure if the previous ones were fatal though)


To generate a diff of this commit:
cvs rdiff -u -r1.204 -r1.205 src/sys/dev/usb/ehci.c
cvs rdiff -u -r1.255 -r1.256 src/sys/dev/usb/uhci.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/usb/ehci.c
diff -u src/sys/dev/usb/ehci.c:1.204 src/sys/dev/usb/ehci.c:1.205
--- src/sys/dev/usb/ehci.c:1.204	Tue Jan 29 00:00:15 2013
+++ src/sys/dev/usb/ehci.c	Fri Feb  1 12:53:47 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: ehci.c,v 1.204 2013/01/29 00:00:15 christos Exp $ */
+/*	$NetBSD: ehci.c,v 1.205 2013/02/01 12:53:47 tsutsui Exp $ */
 
 /*
  * Copyright (c) 2004-2012 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.204 2013/01/29 00:00:15 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.205 2013/02/01 12:53:47 tsutsui Exp $");
 
 #include "ohci.h"
 #include "uhci.h"
@@ -816,7 +816,11 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
 	    lsqtd->offs + offsetof(ehci_qtd_t, qtd_status),
 	    sizeof(lsqtd->qtd.qtd_status),
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-	if (le32toh(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
+	status = le32toh(lsqtd->qtd.qtd_status);
+	usb_syncmem(&lsqtd->dma,
+	    lsqtd->offs + offsetof(ehci_qtd_t, qtd_status),
+	    sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
+	if (status & EHCI_QTD_ACTIVE) {
 		DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
 		for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
 			usb_syncmem(&sqtd->dma,
@@ -839,9 +843,6 @@ ehci_check_qh_intr(ehci_softc_t *sc, str
 		}
 		DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
 			      ex, ex->sqtdstart));
-		usb_syncmem(&lsqtd->dma,
-		    lsqtd->offs + offsetof(ehci_qtd_t, qtd_status),
-		    sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD);
 		return;
 	}
  done:

Index: src/sys/dev/usb/uhci.c
diff -u src/sys/dev/usb/uhci.c:1.255 src/sys/dev/usb/uhci.c:1.256
--- src/sys/dev/usb/uhci.c:1.255	Wed Jan 30 16:01:45 2013
+++ src/sys/dev/usb/uhci.c	Fri Feb  1 12:53:47 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: uhci.c,v 1.255 2013/01/30 16:01:45 tsutsui Exp $	*/
+/*	$NetBSD: uhci.c,v 1.256 2013/02/01 12:53:47 tsutsui Exp $	*/
 
 /*
  * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.255 2013/01/30 16:01:45 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.256 2013/02/01 12:53:47 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1099,6 +1099,7 @@ void
 uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
 {
 	uhci_soft_qh_t *pqh;
+	uint32_t elink;
 
 	KASSERT(mutex_owned(&sc->sc_lock));
 
@@ -1122,7 +1123,10 @@ uhci_remove_hs_ctrl(uhci_softc_t *sc, uh
 	usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
 	    sizeof(sqh->qh.qh_elink),
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-	if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
+	elink = le32toh(sqh->qh.qh_elink);
+	usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
+	    sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD);
+	if (!(elink & UHCI_PTR_T)) {
 		sqh->qh.qh_elink = htole32(UHCI_PTR_T);
 		usb_syncmem(&sqh->dma,
 		    sqh->offs + offsetof(uhci_qh_t, qh_elink),
@@ -1172,6 +1176,7 @@ void
 uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
 {
 	uhci_soft_qh_t *pqh;
+	uint32_t elink;
 
 	KASSERT(mutex_owned(&sc->sc_lock));
 
@@ -1180,7 +1185,10 @@ uhci_remove_ls_ctrl(uhci_softc_t *sc, uh
 	usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
 	    sizeof(sqh->qh.qh_elink),
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-	if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
+	elink = le32toh(sqh->qh.qh_elink);
+	usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
+	    sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD);
+	if (!(elink & UHCI_PTR_T)) {
 		sqh->qh.qh_elink = htole32(UHCI_PTR_T);
 		usb_syncmem(&sqh->dma,
 		    sqh->offs + offsetof(uhci_qh_t, qh_elink),
@@ -1431,7 +1439,12 @@ uhci_check_intr(uhci_softc_t *sc, uhci_i
 	    lstd->offs + offsetof(uhci_td_t, td_status),
 	    sizeof(lstd->td.td_status),
 	    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-	if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) {
+	status = le32toh(lstd->td.td_status);
+	usb_syncmem(&lstd->dma,
+	    lstd->offs + offsetof(uhci_td_t, td_status),
+	    sizeof(lstd->td.td_status),
+	    BUS_DMASYNC_PREREAD);
+	if (status & UHCI_TD_ACTIVE) {
 		DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii));
 		for (std = ii->stdstart; std != lstd; std = std->link.std) {
 			usb_syncmem(&std->dma,
@@ -1460,10 +1473,6 @@ uhci_check_intr(uhci_softc_t *sc, uhci_i
 		}
 		DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n",
 			      ii, ii->stdstart));
-		usb_syncmem(&lstd->dma,
-		    lstd->offs + offsetof(uhci_td_t, td_status),
-		    sizeof(lstd->td.td_status),
-		    BUS_DMASYNC_PREREAD);
 		return;
 	}
  done:
@@ -1854,6 +1863,7 @@ uhci_free_std_chain(uhci_softc_t *sc, uh
 		    uhci_soft_td_t *stdend)
 {
 	uhci_soft_td_t *p;
+	uint32_t td_link;
 
 	/*
 	 * to avoid race condition with the controller which may be looking
@@ -1865,7 +1875,12 @@ uhci_free_std_chain(uhci_softc_t *sc, uh
 		    p->offs + offsetof(uhci_td_t, td_link),
 		    sizeof(p->td.td_link),
 		    BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
-		if ((le32toh(p->td.td_link) & UHCI_PTR_T) == 0) {
+		td_link = le32toh(p->td.td_link);
+		usb_syncmem(&p->dma,
+		    p->offs + offsetof(uhci_td_t, td_link),
+		    sizeof(p->td.td_link),
+		    BUS_DMASYNC_PREREAD);
+		if ((td_link & UHCI_PTR_T) == 0) {
 			p->td.td_link = htole32(UHCI_PTR_T);
 			usb_syncmem(&p->dma,
 			    p->offs + offsetof(uhci_td_t, td_link),

Reply via email to