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),