Thu Dec 8 02:51:08 2011 UTC ()
- convert usbd_bus_methods{} and usbd_pipe_methods{} to use
c99 struct initialisers
- move the locks from the pipe to the bus, since we'll need
access to them from bus-level ops
- remove dead-for-years SPLUSBCHECK and replaced it with
asserts that the thread lock is held
- begin to document the locking scheme
- convert usbd_*lock_pipe() into real function-like macros
(mrg)
diff -r1.181.6.3 -r1.181.6.4 src/sys/dev/usb/ehci.c
diff -r1.218.6.5 -r1.218.6.6 src/sys/dev/usb/ohci.c
diff -r1.240.6.4 -r1.240.6.5 src/sys/dev/usb/uhci.c
diff -r1.125.6.3 -r1.125.6.4 src/sys/dev/usb/usb.c
diff -r1.180.6.1 -r1.180.6.2 src/sys/dev/usb/usb_subr.c
diff -r1.134.2.1 -r1.134.2.2 src/sys/dev/usb/usbdi.c
diff -r1.93.8.1 -r1.93.8.2 src/sys/dev/usb/usbdivar.h
--- src/sys/dev/usb/ehci.c 2011/12/06 02:10:01 1.181.6.3
+++ src/sys/dev/usb/ehci.c 2011/12/08 02:51:07 1.181.6.4
@@ -1,4 +1,4 @@
-/* $NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $ */
+/* $NetBSD: ehci.c,v 1.181.6.4 2011/12/08 02:51:07 mrg Exp $ */
/*
* Copyright (c) 2004-2011 The NetBSD Foundation, Inc.
@@ -53,7 +53,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.3 2011/12/06 02:10:01 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.181.6.4 2011/12/08 02:51:07 mrg Exp $");
#include "ohci.h"
#include "uhci.h"
@@ -220,7 +220,8 @@
Static usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
int ival);
-Static void ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
+Static void ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *,
+ ehci_soft_qh_t *);
Static void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
ehci_soft_qh_t *);
Static void ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
@@ -261,68 +262,68 @@
#define ehci_active_intr_list(ex) ((ex)->inext.tqe_prev != NULL)
Static const struct usbd_bus_methods ehci_bus_methods = {
- ehci_open,
- ehci_softintr,
- ehci_poll,
- ehci_allocm,
- ehci_freem,
- ehci_allocx,
- ehci_freex,
- ehci_get_locks,
+ .open_pipe = ehci_open,
+ .soft_intr = ehci_softintr,
+ .do_poll = ehci_poll,
+ .allocm = ehci_allocm,
+ .freem = ehci_freem,
+ .allocx = ehci_allocx,
+ .freex = ehci_freex,
+ .get_locks = ehci_get_locks,
};
Static const struct usbd_pipe_methods ehci_root_ctrl_methods = {
- ehci_root_ctrl_transfer,
- ehci_root_ctrl_start,
- ehci_root_ctrl_abort,
- ehci_root_ctrl_close,
- ehci_noop,
- ehci_root_ctrl_done,
+ .transfer = ehci_root_ctrl_transfer,
+ .start = ehci_root_ctrl_start,
+ .abort = ehci_root_ctrl_abort,
+ .close = ehci_root_ctrl_close,
+ .cleartoggle = ehci_noop,
+ .done = ehci_root_ctrl_done,
};
Static const struct usbd_pipe_methods ehci_root_intr_methods = {
- ehci_root_intr_transfer,
- ehci_root_intr_start,
- ehci_root_intr_abort,
- ehci_root_intr_close,
- ehci_noop,
- ehci_root_intr_done,
+ .transfer = ehci_root_intr_transfer,
+ .start = ehci_root_intr_start,
+ .abort = ehci_root_intr_abort,
+ .close = ehci_root_intr_close,
+ .cleartoggle = ehci_noop,
+ .done = ehci_root_intr_done,
};
Static const struct usbd_pipe_methods ehci_device_ctrl_methods = {
- ehci_device_ctrl_transfer,
- ehci_device_ctrl_start,
- ehci_device_ctrl_abort,
- ehci_device_ctrl_close,
- ehci_noop,
- ehci_device_ctrl_done,
+ .transfer = ehci_device_ctrl_transfer,
+ .start = ehci_device_ctrl_start,
+ .abort = ehci_device_ctrl_abort,
+ .close = ehci_device_ctrl_close,
+ .cleartoggle = ehci_noop,
+ .done = ehci_device_ctrl_done,
};
Static const struct usbd_pipe_methods ehci_device_intr_methods = {
- ehci_device_intr_transfer,
- ehci_device_intr_start,
- ehci_device_intr_abort,
- ehci_device_intr_close,
- ehci_device_clear_toggle,
- ehci_device_intr_done,
+ .transfer = ehci_device_intr_transfer,
+ .start = ehci_device_intr_start,
+ .abort = ehci_device_intr_abort,
+ .close = ehci_device_intr_close,
+ .cleartoggle = ehci_device_clear_toggle,
+ .done = ehci_device_intr_done,
};
Static const struct usbd_pipe_methods ehci_device_bulk_methods = {
- ehci_device_bulk_transfer,
- ehci_device_bulk_start,
- ehci_device_bulk_abort,
- ehci_device_bulk_close,
- ehci_device_clear_toggle,
- ehci_device_bulk_done,
+ .transfer = ehci_device_bulk_transfer,
+ .start = ehci_device_bulk_start,
+ .abort = ehci_device_bulk_abort,
+ .close = ehci_device_bulk_close,
+ .cleartoggle = ehci_device_clear_toggle,
+ .done = ehci_device_bulk_done,
};
Static const struct usbd_pipe_methods ehci_device_isoc_methods = {
- ehci_device_isoc_transfer,
- ehci_device_isoc_start,
- ehci_device_isoc_abort,
- ehci_device_isoc_close,
- ehci_noop,
- ehci_device_isoc_done,
+ .transfer = ehci_device_isoc_transfer,
+ .start = ehci_device_isoc_start,
+ .abort = ehci_device_isoc_abort,
+ .close = ehci_device_isoc_close,
+ .cleartoggle = ehci_noop,
+ .done = ehci_device_isoc_done,
};
static const uint8_t revbits[EHCI_MAX_POLLRATE] = {
@@ -1753,13 +1754,13 @@
goto bad;
pipe->methods = &ehci_device_ctrl_methods;
mutex_enter(&sc->sc_lock);
- ehci_add_qh(sqh, sc->sc_async_head);
+ ehci_add_qh(sc, sqh, sc->sc_async_head);
mutex_exit(&sc->sc_lock);
break;
case UE_BULK:
pipe->methods = &ehci_device_bulk_methods;
mutex_enter(&sc->sc_lock);
- ehci_add_qh(sqh, sc->sc_async_head);
+ ehci_add_qh(sc, sqh, sc->sc_async_head);
mutex_exit(&sc->sc_lock);
break;
case UE_INTERRUPT:
@@ -1815,10 +1816,11 @@
* Add an ED to the schedule. Called at splusb().
*/
Static void
-ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
+ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
{
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
+
usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link),
sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE);
sqh->next = head->next;
@@ -1846,7 +1848,8 @@
{
ehci_soft_qh_t *p;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
+
/* XXX */
for (p = head; p != NULL && p->next != sqh; p = p->next)
;
@@ -3711,7 +3714,7 @@
sqh->islot = islot;
isp = &sc->sc_islots[islot];
- ehci_add_qh(sqh, isp->sqh);
+ ehci_add_qh(sc, sqh, isp->sqh);
return (USBD_NORMAL_COMPLETION);
}
--- src/sys/dev/usb/ohci.c 2011/12/07 05:41:53 1.218.6.5
+++ src/sys/dev/usb/ohci.c 2011/12/08 02:51:07 1.218.6.6
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.218.6.5 2011/12/07 05:41:53 macallan Exp $ */
+/* $NetBSD: ohci.c,v 1.218.6.6 2011/12/08 02:51:07 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/ohci.c,v 1.22 1999/11/17 22:33:40 n_hibma Exp $ */
/*
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.5 2011/12/07 05:41:53 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.218.6.6 2011/12/08 02:51:07 mrg Exp $");
#include "opt_usb.h"
@@ -120,7 +120,8 @@
Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *,
ohci_soft_ed_t *);
-Static void ohci_rem_ed(ohci_soft_ed_t *, ohci_soft_ed_t *);
+Static void ohci_rem_ed(ohci_softc_t *, ohci_soft_ed_t *,
+ ohci_soft_ed_t *);
Static void ohci_hash_add_td(ohci_softc_t *, ohci_soft_td_t *);
Static void ohci_hash_rem_td(ohci_softc_t *, ohci_soft_td_t *);
Static ohci_soft_td_t *ohci_hash_find_td(ohci_softc_t *, ohci_physaddr_t);
@@ -271,68 +272,68 @@
#define OHCI_INTR_ENDPT 1
Static const struct usbd_bus_methods ohci_bus_methods = {
- ohci_open,
- ohci_softintr,
- ohci_poll,
- ohci_allocm,
- ohci_freem,
- ohci_allocx,
- ohci_freex,
- ohci_get_locks,
+ .open_pipe = ohci_open,
+ .soft_intr = ohci_softintr,
+ .do_poll = ohci_poll,
+ .allocm = ohci_allocm,
+ .freem = ohci_freem,
+ .allocx = ohci_allocx,
+ .freex = ohci_freex,
+ .get_locks = ohci_get_locks,
};
Static const struct usbd_pipe_methods ohci_root_ctrl_methods = {
- ohci_root_ctrl_transfer,
- ohci_root_ctrl_start,
- ohci_root_ctrl_abort,
- ohci_root_ctrl_close,
- ohci_noop,
- ohci_root_ctrl_done,
+ .transfer = ohci_root_ctrl_transfer,
+ .start = ohci_root_ctrl_start,
+ .abort = ohci_root_ctrl_abort,
+ .close = ohci_root_ctrl_close,
+ .cleartoggle = ohci_noop,
+ .done = ohci_root_ctrl_done,
};
Static const struct usbd_pipe_methods ohci_root_intr_methods = {
- ohci_root_intr_transfer,
- ohci_root_intr_start,
- ohci_root_intr_abort,
- ohci_root_intr_close,
- ohci_noop,
- ohci_root_intr_done,
+ .transfer = ohci_root_intr_transfer,
+ .start = ohci_root_intr_start,
+ .abort = ohci_root_intr_abort,
+ .close = ohci_root_intr_close,
+ .cleartoggle = ohci_noop,
+ .done = ohci_root_intr_done,
};
Static const struct usbd_pipe_methods ohci_device_ctrl_methods = {
- ohci_device_ctrl_transfer,
- ohci_device_ctrl_start,
- ohci_device_ctrl_abort,
- ohci_device_ctrl_close,
- ohci_noop,
- ohci_device_ctrl_done,
+ .transfer = ohci_device_ctrl_transfer,
+ .start = ohci_device_ctrl_start,
+ .abort = ohci_device_ctrl_abort,
+ .close = ohci_device_ctrl_close,
+ .cleartoggle = ohci_noop,
+ .done = ohci_device_ctrl_done,
};
Static const struct usbd_pipe_methods ohci_device_intr_methods = {
- ohci_device_intr_transfer,
- ohci_device_intr_start,
- ohci_device_intr_abort,
- ohci_device_intr_close,
- ohci_device_clear_toggle,
- ohci_device_intr_done,
+ .transfer = ohci_device_intr_transfer,
+ .start = ohci_device_intr_start,
+ .abort = ohci_device_intr_abort,
+ .close = ohci_device_intr_close,
+ .cleartoggle = ohci_device_clear_toggle,
+ .done = ohci_device_intr_done,
};
Static const struct usbd_pipe_methods ohci_device_bulk_methods = {
- ohci_device_bulk_transfer,
- ohci_device_bulk_start,
- ohci_device_bulk_abort,
- ohci_device_bulk_close,
- ohci_device_clear_toggle,
- ohci_device_bulk_done,
+ .transfer = ohci_device_bulk_transfer,
+ .start = ohci_device_bulk_start,
+ .abort = ohci_device_bulk_abort,
+ .close = ohci_device_bulk_close,
+ .cleartoggle = ohci_device_clear_toggle,
+ .done = ohci_device_bulk_done,
};
Static const struct usbd_pipe_methods ohci_device_isoc_methods = {
- ohci_device_isoc_transfer,
- ohci_device_isoc_start,
- ohci_device_isoc_abort,
- ohci_device_isoc_close,
- ohci_noop,
- ohci_device_isoc_done,
+ .transfer = ohci_device_isoc_transfer,
+ .start = ohci_device_isoc_start,
+ .abort = ohci_device_isoc_abort,
+ .close = ohci_device_isoc_close,
+ .cleartoggle = ohci_noop,
+ .done = ohci_device_isoc_done,
};
int
@@ -1869,12 +1870,13 @@
/*
* Add an ED to the schedule. Called at splusb().
*/
-void
+Static void
ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
{
DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head));
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
+
usb_syncmem(&head->dma, head->offs + offsetof(ohci_ed_t, ed_nexted),
sizeof(head->ed.ed_nexted),
BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
@@ -1893,12 +1895,12 @@
/*
* Remove an ED from the schedule. Called at splusb().
*/
-void
-ohci_rem_ed(ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
+Static void
+ohci_rem_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head)
{
ohci_soft_ed_t *p;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
/* XXX */
for (p = head; p != NULL && p->next != sed; p = p->next)
@@ -1932,7 +1934,7 @@
{
int h = HASH(std->physaddr);
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
}
@@ -1941,8 +1943,9 @@
void
ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std)
{
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
+
LIST_REMOVE(std, hnext);
}
@@ -1966,7 +1969,7 @@
{
int h = HASH(sitd->physaddr);
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n",
sitd, (u_long)sitd->physaddr));
@@ -1978,7 +1981,7 @@
void
ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd)
{
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n",
sitd, (u_long)sitd->physaddr));
@@ -2271,7 +2274,7 @@
printf("ohci_close_pipe: pipe still not empty\n");
}
#endif
- ohci_rem_ed(sed, head);
+ ohci_rem_ed(sc, sed, head);
/* Make sure the host controller is not touching this ED */
usb_delay_ms(&sc->sc_bus, 1);
pipe->endpoint->datatoggle =
--- src/sys/dev/usb/uhci.c 2011/12/06 05:40:02 1.240.6.4
+++ src/sys/dev/usb/uhci.c 2011/12/08 02:51:08 1.240.6.5
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.240.6.4 2011/12/06 05:40:02 mrg Exp $ */
+/* $NetBSD: uhci.c,v 1.240.6.5 2011/12/08 02:51:08 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -43,7 +43,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.4 2011/12/06 05:40:02 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.240.6.5 2011/12/08 02:51:08 mrg Exp $");
#include "opt_usb.h"
@@ -284,68 +284,68 @@
#define UHCI_INTR_ENDPT 1
const struct usbd_bus_methods uhci_bus_methods = {
- uhci_open,
- uhci_softintr,
- uhci_poll,
- uhci_allocm,
- uhci_freem,
- uhci_allocx,
- uhci_freex,
- uhci_get_locks,
+ .open_pipe = uhci_open,
+ .soft_intr = uhci_softintr,
+ .do_poll = uhci_poll,
+ .allocm = uhci_allocm,
+ .freem = uhci_freem,
+ .allocx = uhci_allocx,
+ .freex = uhci_freex,
+ .get_locks = uhci_get_locks,
};
const struct usbd_pipe_methods uhci_root_ctrl_methods = {
- uhci_root_ctrl_transfer,
- uhci_root_ctrl_start,
- uhci_root_ctrl_abort,
- uhci_root_ctrl_close,
- uhci_noop,
- uhci_root_ctrl_done,
+ .transfer = uhci_root_ctrl_transfer,
+ .start = uhci_root_ctrl_start,
+ .abort = uhci_root_ctrl_abort,
+ .close = uhci_root_ctrl_close,
+ .cleartoggle = uhci_noop,
+ .done = uhci_root_ctrl_done,
};
const struct usbd_pipe_methods uhci_root_intr_methods = {
- uhci_root_intr_transfer,
- uhci_root_intr_start,
- uhci_root_intr_abort,
- uhci_root_intr_close,
- uhci_noop,
- uhci_root_intr_done,
+ .transfer = uhci_root_intr_transfer,
+ .start = uhci_root_intr_start,
+ .abort = uhci_root_intr_abort,
+ .close = uhci_root_intr_close,
+ .cleartoggle = uhci_noop,
+ .done = uhci_root_intr_done,
};
const struct usbd_pipe_methods uhci_device_ctrl_methods = {
- uhci_device_ctrl_transfer,
- uhci_device_ctrl_start,
- uhci_device_ctrl_abort,
- uhci_device_ctrl_close,
- uhci_noop,
- uhci_device_ctrl_done,
+ .transfer = uhci_device_ctrl_transfer,
+ .start = uhci_device_ctrl_start,
+ .abort = uhci_device_ctrl_abort,
+ .close = uhci_device_ctrl_close,
+ .cleartoggle = uhci_noop,
+ .done = uhci_device_ctrl_done,
};
const struct usbd_pipe_methods uhci_device_intr_methods = {
- uhci_device_intr_transfer,
- uhci_device_intr_start,
- uhci_device_intr_abort,
- uhci_device_intr_close,
- uhci_device_clear_toggle,
- uhci_device_intr_done,
+ .transfer = uhci_device_intr_transfer,
+ .start = uhci_device_intr_start,
+ .abort = uhci_device_intr_abort,
+ .close = uhci_device_intr_close,
+ .cleartoggle = uhci_device_clear_toggle,
+ .done = uhci_device_intr_done,
};
const struct usbd_pipe_methods uhci_device_bulk_methods = {
- uhci_device_bulk_transfer,
- uhci_device_bulk_start,
- uhci_device_bulk_abort,
- uhci_device_bulk_close,
- uhci_device_clear_toggle,
- uhci_device_bulk_done,
+ .transfer = uhci_device_bulk_transfer,
+ .start = uhci_device_bulk_start,
+ .abort = uhci_device_bulk_abort,
+ .close = uhci_device_bulk_close,
+ .cleartoggle = uhci_device_clear_toggle,
+ .done = uhci_device_bulk_done,
};
const struct usbd_pipe_methods uhci_device_isoc_methods = {
- uhci_device_isoc_transfer,
- uhci_device_isoc_start,
- uhci_device_isoc_abort,
- uhci_device_isoc_close,
- uhci_noop,
- uhci_device_isoc_done,
+ .transfer = uhci_device_isoc_transfer,
+ .start = uhci_device_isoc_start,
+ .abort = uhci_device_isoc_abort,
+ .close = uhci_device_isoc_close,
+ .cleartoggle = uhci_noop,
+ .done = uhci_device_isoc_done,
};
#define uhci_add_intr_info(sc, ii) \
@@ -1097,7 +1097,7 @@
{
uhci_soft_qh_t *eqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
eqh = sc->sc_hctl_end;
@@ -1124,7 +1124,7 @@
{
uhci_soft_qh_t *pqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh));
#ifdef UHCI_CTL_LOOP
@@ -1174,7 +1174,7 @@
{
uhci_soft_qh_t *eqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
eqh = sc->sc_lctl_end;
@@ -1197,7 +1197,7 @@
{
uhci_soft_qh_t *pqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh));
/* See comment in uhci_remove_hs_ctrl() */
@@ -1231,7 +1231,7 @@
{
uhci_soft_qh_t *eqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
eqh = sc->sc_bulk_end;
@@ -1255,7 +1255,7 @@
{
uhci_soft_qh_t *pqh;
- SPLUSBCHECK;
+ KASSERT(mutex_owned(&sc->sc_lock));
DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
uhci_rem_loop(sc);
--- src/sys/dev/usb/usb.c 2011/12/07 22:52:17 1.125.6.3
+++ src/sys/dev/usb/usb.c 2011/12/08 02:51:08 1.125.6.4
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.c,v 1.125.6.3 2011/12/07 22:52:17 mrg Exp $ */
+/* $NetBSD: usb.c,v 1.125.6.4 2011/12/08 02:51:08 mrg Exp $ */
/*
* Copyright (c) 1998, 2002, 2008 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.3 2011/12/07 22:52:17 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.125.6.4 2011/12/08 02:51:08 mrg Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usb.h"
@@ -224,6 +224,13 @@
break;
default:
panic("usb_doattach");
+ }
+
+ if (mpsafe) {
+ sc->sc_bus->methods->get_locks(sc->sc_bus,
+ &sc->sc_bus->intr_lock, &sc->sc_bus->lock);
+ } else {
+ sc->sc_bus->intr_lock = sc->sc_bus->lock = NULL;
}
ue = usb_alloc_event();
--- src/sys/dev/usb/usb_subr.c 2011/12/04 13:23:17 1.180.6.1
+++ src/sys/dev/usb/usb_subr.c 2011/12/08 02:51:08 1.180.6.2
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_subr.c,v 1.180.6.1 2011/12/04 13:23:17 jmcneill Exp $ */
+/* $NetBSD: usb_subr.c,v 1.180.6.2 2011/12/08 02:51:08 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.180.6.2 2011/12/08 02:51:08 mrg Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usbverbose.h"
@@ -750,11 +750,6 @@
ep->edesc->bEndpointAddress, usbd_errstr(err)));
free(p, M_USB);
return (err);
- }
- if (dev->bus->methods->get_locks) {
- dev->bus->methods->get_locks(dev->bus, &p->intr_lock, &p->lock);
- } else {
- p->intr_lock = p->lock = NULL;
}
*pipe = p;
return (USBD_NORMAL_COMPLETION);
--- src/sys/dev/usb/usbdi.c 2011/12/04 13:23:17 1.134.2.1
+++ src/sys/dev/usb/usbdi.c 2011/12/08 02:51:08 1.134.2.2
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.c,v 1.134.2.1 2011/12/04 13:23:17 jmcneill Exp $ */
+/* $NetBSD: usbdi.c,v 1.134.2.2 2011/12/08 02:51:08 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
/*
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.1 2011/12/04 13:23:17 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.134.2.2 2011/12/08 02:51:08 mrg Exp $");
#include "opt_compat_netbsd.h"
#include "opt_usb.h"
@@ -310,17 +310,17 @@
/* Sync transfer, wait for completion. */
if (err != USBD_IN_PROGRESS)
return (err);
- usbd_lock(pipe->lock);
+ usbd_lock_pipe(pipe);
if (!xfer->done) {
if (pipe->device->bus->use_polling)
panic("usbd_transfer: not done");
- if (pipe->lock) {
- cv_wait(&xfer->cv, pipe->lock);
+ if (pipe->device->bus->lock) {
+ cv_wait(&xfer->cv, pipe->device->bus->lock);
} else {
tsleep(xfer, PRIBIO, "usbsyn", 0);
}
}
- usbd_unlock(pipe->lock);
+ usbd_unlock_pipe(pipe);
return (xfer->status);
}
@@ -537,9 +537,9 @@
return (USBD_NORMAL_COMPLETION);
}
#endif
- usbd_lock(pipe->lock);
+ usbd_lock_pipe(pipe);
err = usbd_ar_pipe(pipe);
- usbd_unlock(pipe->lock);
+ usbd_unlock_pipe(pipe);
if (pipe->intrxfer != intrxfer)
usbd_free_xfer(intrxfer);
return (err);
@@ -727,8 +727,7 @@
{
usbd_xfer_handle xfer;
- SPLUSBCHECK;
- KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+ KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
#ifdef USB_DEBUG
@@ -741,11 +740,11 @@
DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
pipe, xfer, pipe->methods));
/* Make the HC abort it (and invoke the callback). */
- if (pipe->lock)
- mutex_exit(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_exit(pipe->device->bus->lock);
pipe->methods->abort(xfer);
- if (pipe->lock)
- mutex_enter(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_enter(pipe->device->bus->lock);
/* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
}
pipe->aborting = 0;
@@ -763,12 +762,11 @@
xfer->status == USBD_TIMEOUT;
int repeat, polling;
- SPLUSBCHECK;
DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
"actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
- KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+ KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_ONQU) {
@@ -837,22 +835,26 @@
if (repeat) {
if (xfer->callback) {
- if (pipe->lock) mutex_exit(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_exit(pipe->device->bus->lock);
xfer->callback(xfer, xfer->priv, xfer->status);
- if (pipe->lock) mutex_enter(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_enter(pipe->device->bus->lock);
}
pipe->methods->done(xfer);
} else {
pipe->methods->done(xfer);
if (xfer->callback) {
- if (pipe->lock) mutex_exit(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_exit(pipe->device->bus->lock);
xfer->callback(xfer, xfer->priv, xfer->status);
- if (pipe->lock) mutex_enter(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_enter(pipe->device->bus->lock);
}
}
if (sync && !polling) {
- if (pipe->lock) {
+ if (pipe->device->bus->lock) {
cv_broadcast(&xfer->cv);
} else {
wakeup(xfer);
@@ -878,7 +880,7 @@
DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
pipe, pipe->running, xfer->timeout));
- KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+ KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
@@ -907,7 +909,7 @@
usbd_xfer_handle xfer;
usbd_status err;
- SPLUSBCHECK;
+ KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
#ifdef DIAGNOSTIC
if (pipe == NULL) {
@@ -920,7 +922,7 @@
}
#endif
- KASSERT(pipe->lock == NULL || mutex_owned(pipe->lock));
+ KASSERT(pipe->device->bus->lock == NULL || mutex_owned(pipe->device->bus->lock));
/* Get next request in queue. */
xfer = SIMPLEQ_FIRST(&pipe->queue);
@@ -928,11 +930,11 @@
if (xfer == NULL) {
pipe->running = 0;
} else {
- if (pipe->lock)
- mutex_exit(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_exit(pipe->device->bus->lock);
err = pipe->methods->start(xfer);
- if (pipe->lock)
- mutex_enter(pipe->lock);
+ if (pipe->device->bus->lock)
+ mutex_enter(pipe->device->bus->lock);
if (err != USBD_IN_PROGRESS) {
printf("usbd_start_next: error=%d\n", err);
pipe->running = 0;
--- src/sys/dev/usb/usbdivar.h 2011/12/04 13:23:17 1.93.8.1
+++ src/sys/dev/usb/usbdivar.h 2011/12/08 02:51:08 1.93.8.2
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdivar.h,v 1.93.8.1 2011/12/04 13:23:17 jmcneill Exp $ */
+/* $NetBSD: usbdivar.h,v 1.93.8.2 2011/12/08 02:51:08 mrg Exp $ */
/* $FreeBSD: src/sys/dev/usb/usbdivar.h,v 1.11 1999/11/17 22:33:51 n_hibma Exp $ */
/*
@@ -34,6 +34,41 @@
#include <sys/callout.h>
#include <sys/mutex.h>
+/*
+ * Discussion about locking in the USB code:
+ *
+ * There are two locks presented by the host controller: the interrupt lock
+ * and the thread lock. The interrupt lock, either a spin or adaptive mutex,
+ * manages hardware state and anything else touched in an interrupt context.
+ * The thread lock has everything else.
+ *
+ * List of hardware interface methods, and which locks are held when each
+ * is called by this module:
+ *
+ * BUS METHOD INTR THREAD NOTES
+ * ----------------------- ------- ------- -------------------------
+ * open_pipe - - might want to take thread lock?
+ * soft_intr - - intr lock is taken sometimes, thread lock taken often, but nothing demanded?
+ * do_poll - - might want to take thread lock?
+ * allocm - -
+ * freem - -
+ * allocx - -
+ * freex - -
+ * get_locks - - Called at attach time
+ *
+ * PIPE METHOD INTR THREAD NOTES
+ * ----------------------- ------- ------- -------------------------
+ * transfer - -
+ * start - -
+ * abort - -
+ * close - -
+ * cleartoggle - -
+ * done - x
+ *
+ * The above semantics are likely to change.
+ *
+ */
+
/* From usb_mem.h */
struct usb_dma_block;
typedef struct {
@@ -107,7 +142,9 @@
const struct usbd_bus_methods *methods;
u_int32_t pipe_size; /* size of a pipe struct */
/* Filled by usb driver */
- struct usbd_device *root_hub;
+ kmutex_t *intr_lock;
+ kmutex_t *lock;
+ struct usbd_device *root_hub;
usbd_device_handle devices[USB_MAX_DEVICES];
char needs_explore;/* a hub a signalled a change */
char use_polling;
@@ -178,9 +215,6 @@
char repeat;
int interval;
- kmutex_t *intr_lock;
- kmutex_t *lock;
-
/* Filled by HC driver. */
const struct usbd_pipe_methods *methods;
};
@@ -267,19 +301,18 @@
void usb_needs_reattach(usbd_device_handle);
void usb_schedsoftintr(struct usbd_bus *);
-#define usbd_lock(m) if (m) { s = -1; mutex_enter(m); } else s = splusb()
-#define usbd_unlock(m) if (m) { s = -1; mutex_exit(m); } else splx(s)
+#define usbd_lock_pipe(p) do { \
+ if ((p)->device->bus->lock) { \
+ s = -1; \
+ mutex_enter((p)->device->bus->lock); \
+ } else \
+ s = splusb(); \
+} while (0)
-/*
+#define usbd_unlock_pipe(p) do { \
- * XXX This check is extremely bogus. Bad Bad Bad.
+ if ((p)->device->bus->lock) { \
- */
+ s = -1; \
-#if defined(DIAGNOSTIC) && 0
+ mutex_exit((p)->device->bus->lock); \
-#define SPLUSBCHECK \
+ } else \
- do { int _s = splusb(), _su = splusb(); \
+ splx(s); \
- if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
+} while (0)
- _s, _su, __FILE__, __LINE__); \
- splx(_s); \
- } while (0)
-#else
-#define SPLUSBCHECK
-#endif