Module Name:    src
Committed By:   skrll
Date:           Wed Oct  2 22:55:04 UTC 2013

Modified Files:
        src/sys/dev/ic: sl811hs.c sl811hsvar.h

Log Message:
Modernise slhci. Many thanks to rkujawa@ for testing.


To generate a diff of this commit:
cvs rdiff -u -r1.40 -r1.41 src/sys/dev/ic/sl811hs.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/ic/sl811hsvar.h

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/ic/sl811hs.c
diff -u src/sys/dev/ic/sl811hs.c:1.40 src/sys/dev/ic/sl811hs.c:1.41
--- src/sys/dev/ic/sl811hs.c:1.40	Mon Sep 23 11:27:45 2013
+++ src/sys/dev/ic/sl811hs.c	Wed Oct  2 22:55:04 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: sl811hs.c,v 1.40 2013/09/23 11:27:45 skrll Exp $	*/
+/*	$NetBSD: sl811hs.c,v 1.41 2013/10/02 22:55:04 skrll Exp $	*/
 
 /*
  * Not (c) 2007 Matthew Orgass
@@ -55,23 +55,6 @@
  *
  * Since this driver attaches to pcmcia, card removal at any point should be
  * expected and not cause panics or infinite loops.
- *
- * This driver does fine grained locking for its own data structures, however
- * the general USB code does not yet have locks, some of which would need to
- * be used in this driver.  This is mostly for debug use on single processor
- * systems.
- *
- * The theory of the wait lock is that start is the only function that would
- * be frequently called from arbitrary processors, so it should not need to
- * wait for the rest to be completed.  However, once entering the lock as much
- * device access as possible is done, so any other CPU that tries to service
- * an interrupt would be blocked.  Ideally, the hard and soft interrupt could
- * be assigned to the same CPU and start would normally just put work on the
- * wait queue and generate a soft interrupt.
- *
- * Any use of the main lock must check the wait lock before returning.  The
- * aquisition order is main lock then wait lock, but the wait lock must be
- * released last when clearing the wait queue.
  */
 
 /*
@@ -85,7 +68,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.40 2013/09/23 11:27:45 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.41 2013/10/02 22:55:04 skrll Exp $");
 
 #include "opt_slhci.h"
 
@@ -98,7 +81,6 @@ __KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 
 #include <sys/malloc.h>
 #include <sys/queue.h>
 #include <sys/gcq.h>
-#include <sys/simplelock.h>
 #include <sys/intr.h>
 #include <sys/cpu.h>
 #include <sys/bus.h>
@@ -313,10 +295,6 @@ struct slhci_pipe {
 	uint8_t 	ptype;		/* Pipe type */
 };
 
-#if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
-#define SLHCI_WAITLOCK 1
-#endif
-
 #ifdef SLHCI_PROFILE_TRANSFER
 #if defined(__mips__)
 /*
@@ -449,6 +427,7 @@ usbd_status slhci_allocm(struct usbd_bus
 void slhci_freem(struct usbd_bus *, usb_dma_t *);
 struct usbd_xfer * slhci_allocx(struct usbd_bus *);
 void slhci_freex(struct usbd_bus *, struct usbd_xfer *);
+static void slhci_get_lock(struct usbd_bus *, kmutex_t **);
 
 usbd_status slhci_transfer(struct usbd_xfer *);
 usbd_status slhci_start(struct usbd_xfer *);
@@ -478,11 +457,11 @@ usbd_status slhci_lock_call(struct slhci
     struct slhci_pipe *, struct usbd_xfer *);
 void slhci_start_entry(struct slhci_softc *, struct slhci_pipe *);
 void slhci_callback_entry(void *arg);
-void slhci_do_callback(struct slhci_softc *, struct usbd_xfer *, int *);
+void slhci_do_callback(struct slhci_softc *, struct usbd_xfer *);
 
 /* slhci_intr */
 
-void slhci_main(struct slhci_softc *, int *);
+void slhci_main(struct slhci_softc *);
 
 /* in lock functions */
 
@@ -497,11 +476,9 @@ static void slhci_abdone(struct slhci_so
 static void slhci_tstart(struct slhci_softc *);
 static void slhci_dotransfer(struct slhci_softc *);
 
-static void slhci_callback(struct slhci_softc *, int *);
+static void slhci_callback(struct slhci_softc *);
 static void slhci_enter_xfer(struct slhci_softc *, struct slhci_pipe *);
-#ifdef SLHCI_WAITLOCK
 static void slhci_enter_xfers(struct slhci_softc *);
-#endif
 static void slhci_queue_timed(struct slhci_softc *, struct slhci_pipe *);
 static void slhci_xfer_timer(struct slhci_softc *, struct slhci_pipe *);
 
@@ -509,7 +486,7 @@ static void slhci_do_repeat(struct slhci
 static void slhci_callback_schedule(struct slhci_softc *);
 static void slhci_do_callback_schedule(struct slhci_softc *);
 #if 0
-void slhci_pollxfer(struct slhci_softc *, struct usbd_xfer *, int *); /* XXX */
+void slhci_pollxfer(struct slhci_softc *, struct usbd_xfer *); /* XXX */
 #endif
 
 static usbd_status slhci_do_poll(struct slhci_softc *, struct slhci_pipe *,
@@ -524,8 +501,6 @@ static usbd_status slhci_close_pipe(stru
     struct usbd_xfer *);
 static usbd_status slhci_do_abort(struct slhci_softc *, struct slhci_pipe *,
     struct usbd_xfer *);
-static usbd_status slhci_do_attach(struct slhci_softc *, struct slhci_pipe *,
-    struct usbd_xfer *);
 static usbd_status slhci_halt(struct slhci_softc *, struct slhci_pipe *,
     struct usbd_xfer *);
 
@@ -678,9 +653,6 @@ DDOLOGBUF(uint8_t *buf, unsigned int len
 #define DLOGBUF(x, b, l) ((void)0)
 #endif /* SLHCI_DEBUG */
 
-#define SLHCI_MAINLOCKASSERT(sc) ((void)0)
-#define SLHCI_LOCKASSERT(sc, main, wait) ((void)0)
-
 #ifdef DIAGNOSTIC
 #define LK_SLASSERT(exp, sc, spipe, xfer, ext) do {			\
 	if (!(exp)) {							\
@@ -715,7 +687,7 @@ const struct usbd_bus_methods slhci_bus_
 	.freem = slhci_freem,
 	.allocx = slhci_allocx,
 	.freex = slhci_freex,
-	.get_lock = NULL,
+	.get_lock = slhci_get_lock,
 	NULL, /* new_device */
 };
 
@@ -760,7 +732,6 @@ const struct usbd_pipe_methods slhci_roo
 #define FIND_TIMED(var, t, tvar, cond) \
    GCQ_FIND_TYPED(var, &(t)->timed, tvar, struct slhci_pipe, xq, cond)
 
-#ifdef SLHCI_WAITLOCK
 #define DEQUEUED_WAITQ(tvar, sc) \
     GCQ_DEQUEUED_FIRST_TYPED(tvar, &(sc)->sc_waitq, struct slhci_pipe, xq)
 
@@ -769,7 +740,6 @@ enter_waitq(struct slhci_softc *sc, stru
 {
 	gcq_insert_tail(&sc->sc_waitq, &spipe->xq);
 }
-#endif
 
 static inline void
 enter_q(struct slhci_transfers *t, struct slhci_pipe *spipe, int i)
@@ -883,17 +853,27 @@ slhci_freex(struct usbd_bus *bus, struct
 	free(xfer, M_USB);
 }
 
+static void
+slhci_get_lock(struct usbd_bus *bus, kmutex_t **lock)
+{
+	struct slhci_softc *sc = bus->hci_private;
+
+	*lock = &sc->sc_lock;
+}
+
 usbd_status
 slhci_transfer(struct usbd_xfer *xfer)
 {
+	struct slhci_softc *sc = xfer->pipe->device->bus->hci_private;
 	usbd_status error;
-	int s;
 
 	DLOG(D_TRACE, "%s transfer xfer %p spipe %p ",
 	    pnames(SLHCI_XFER_TYPE(xfer)), xfer, xfer->pipe,0);
 
 	/* Insert last in queue */
+	mutex_enter(&sc->sc_lock);
 	error = usb_insert_transfer(xfer);
+	mutex_exit(&sc->sc_lock);
 	if (error) {
 		if (error != USBD_IN_PROGRESS)
 			DLOG(D_ERR, "usb_insert_transfer returns %d!", error,
@@ -907,32 +887,30 @@ slhci_transfer(struct usbd_xfer *xfer)
 	 */
 
 	/*
-	 * Start next is always done at splusb, so we do this here so
-	 * start functions are always called at softusb. XXX
+	 * Start will take the lock.
 	 */
-	s = splusb();
 	error = xfer->pipe->methods->start(SIMPLEQ_FIRST(&xfer->pipe->queue));
-	splx(s);
 
 	return error;
 }
+#define	DWC_OTG_BUS2SC(bus)	((bus)->hci_private)
+
+#define	DWC_OTG_PIPE2SC(pipe)	DWC_OTG_BUS2SC((pipe)->device->bus)
+
+#define	DWC_OTG_XFER2SC(xfer)	DWC_OTG_PIPE2SC((xfer)->pipe)
 
 /* It is not safe for start to return anything other than USBD_INPROG. */
 usbd_status
 slhci_start(struct usbd_xfer *xfer)
 {
-	struct slhci_softc *sc;
-	struct usbd_pipe *pipe;
-	struct slhci_pipe *spipe;
-	struct slhci_transfers *t;
-	usb_endpoint_descriptor_t *ed;
+	struct slhci_softc *sc = xfer->pipe->device->bus->hci_private;
+	struct usbd_pipe *pipe = xfer->pipe;
+	struct slhci_pipe *spipe = (struct slhci_pipe *)pipe;
+	struct slhci_transfers *t = &sc->sc_transfers;
+;	usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
 	unsigned int max_packet;
 
-	pipe = xfer->pipe;
-	sc = pipe->device->bus->hci_private;
-	spipe = (struct slhci_pipe *)xfer->pipe;
-	t = &sc->sc_transfers;
-	ed = pipe->endpoint->edesc;
+	mutex_enter(&sc->sc_lock);
 
 	max_packet = UGETW(ed->wMaxPacketSize);
 
@@ -1049,6 +1027,8 @@ slhci_start(struct usbd_xfer *xfer)
 
 	slhci_start_entry(sc, spipe);
 
+	mutex_exit(&sc->sc_lock);
+
 	return USBD_IN_PROGRESS;
 }
 
@@ -1189,10 +1169,9 @@ slhci_preinit(struct slhci_softc *sc, Po
 #ifdef SLHCI_DEBUG
 	KERNHIST_INIT_STATIC(slhcihist, slhci_he);
 #endif
-	simple_lock_init(&sc->sc_lock);
-#ifdef SLHCI_WAITLOCK
-	simple_lock_init(&sc->sc_wait_lock);
-#endif
+	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
+	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED);
+
 	/* sc->sc_ier = 0;	*/
 	/* t->rootintr = NULL;	*/
 	t->flags = F_NODEV|F_UDISABLED;
@@ -1214,17 +1193,86 @@ slhci_preinit(struct slhci_softc *sc, Po
 	gcq_init_head(&t->timed);
 	gcq_init_head(&t->to);
 	gcq_init_head(&t->ap);
-#ifdef SLHCI_WAITLOCK
 	gcq_init_head(&sc->sc_waitq);
-#endif
 }
 
 int
 slhci_attach(struct slhci_softc *sc)
 {
-	if (slhci_lock_call(sc, &slhci_do_attach, NULL, NULL) !=
-	   USBD_NORMAL_COMPLETION)
+	struct slhci_transfers *t;
+	const char *rev;
+
+	t = &sc->sc_transfers;
+
+	/* Detect and check the controller type */
+	t->sltype = SL11_GET_REV(slhci_read(sc, SL11_REV));
+
+	/* SL11H not supported */
+	if (!slhci_supported_rev(t->sltype)) {
+		if (t->sltype == SLTYPE_SL11H)
+			printf("%s: SL11H unsupported or bus error!\n",
+			    SC_NAME(sc));
+		else
+			printf("%s: Unknown chip revision!\n", SC_NAME(sc));
 		return -1;
+	}
+
+	callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
+	callout_setfunc(&sc->sc_timer, slhci_reset_entry, sc);
+
+	/*
+	 * It is not safe to call the soft interrupt directly as
+	 * usb_schedsoftintr does in the use_polling case (due to locking).
+	 */
+	sc->sc_cb_softintr = softint_establish(SOFTINT_NET,
+	    slhci_callback_entry, sc);
+
+#ifdef SLHCI_DEBUG
+	ssc = sc;
+#ifdef USB_DEBUG
+	if (slhci_usbdebug >= 0)
+		usbdebug = slhci_usbdebug;
+#endif
+#endif
+
+	if (t->sltype == SLTYPE_SL811HS_R12)
+		rev = " (rev 1.2)";
+	else if (t->sltype == SLTYPE_SL811HS_R14)
+		rev = " (rev 1.4 or 1.5)";
+	else
+		rev = " (unknown revision)";
+
+	aprint_normal("%s: ScanLogic SL811HS/T USB Host Controller %s\n",
+	    SC_NAME(sc), rev);
+
+	aprint_normal("%s: Max Current %u mA (value by code, not by probe)\n",
+	    SC_NAME(sc), t->max_current * 2);
+
+#if defined(SLHCI_DEBUG) || defined(SLHCI_NO_OVERTIME) || \
+    defined(SLHCI_TRY_LSVH) || defined(SLHCI_PROFILE_TRANSFER)
+	aprint_normal("%s: driver options:"
+#ifdef SLHCI_DEBUG
+	" SLHCI_DEBUG"
+#endif
+#ifdef SLHCI_TRY_LSVH
+	" SLHCI_TRY_LSVH"
+#endif
+#ifdef SLHCI_NO_OVERTIME
+	" SLHCI_NO_OVERTIME"
+#endif
+#ifdef SLHCI_PROFILE_TRANSFER
+	" SLHCI_PROFILE_TRANSFER"
+#endif
+	"\n", SC_NAME(sc));
+#endif
+	sc->sc_bus.usbrev = USBREV_1_1;
+	sc->sc_bus.methods = __UNCONST(&slhci_bus_methods);
+	sc->sc_bus.pipe_size = sizeof(struct slhci_pipe);
+
+	if (!sc->sc_enable_power)
+		t->flags |= F_REALPOWER;
+
+	t->flags |= F_ACTIVE;
 
 	/* Attach usb and uhub. */
 	sc->sc_child = config_found(SC_DEV(sc), &sc->sc_bus, usbctlprint);
@@ -1257,6 +1305,9 @@ slhci_detach(struct slhci_softc *sc, int
 
 	softint_disestablish(sc->sc_cb_softintr);
 
+	mutex_destroy(&sc->sc_lock);
+	mutex_destroy(&sc->sc_intr_lock);
+
 	ret = 0;
 
 	if (sc->sc_child)
@@ -1294,6 +1345,8 @@ slhci_abort(struct usbd_xfer *xfer)
 	struct slhci_softc *sc;
 	struct slhci_pipe *spipe;
 
+	KASSERT(mutex_owned(&sc->sc_lock));
+
 	spipe = (struct slhci_pipe *)xfer->pipe;
 
 	if (spipe == NULL)
@@ -1308,7 +1361,7 @@ slhci_abort(struct usbd_xfer *xfer)
 
 callback:
 	xfer->status = USBD_CANCELLED;
-	/* Abort happens at splusb. */
+	/* Abort happens at IPL_USB. */
 	usb_transfer_complete(xfer);
 }
 
@@ -1385,24 +1438,18 @@ slhci_mem_use(struct usbd_bus *bus, int 
 	struct slhci_softc *sc = bus->hci_private;
 	int s;
 
-	s = splhardusb();
-	simple_lock(&sc->sc_wait_lock);
+	mutex_enter(&sc->sc_intr_lock);
 	sc->sc_mem_use += val;
-	simple_unlock(&sc->sc_wait_lock);
-	splx(s);
+	mutex_exit(&sc->sc_intr_lock);
 }
 #endif
 
 void
 slhci_reset_entry(void *arg)
 {
-	struct slhci_softc *sc;
-	int s;
+	struct slhci_softc *sc = arg;
 
-	sc = (struct slhci_softc *)arg;
-
-	s = splhardusb();
-	simple_lock(&sc->sc_lock);
+	mutex_enter(&sc->sc_intr_lock);
 	slhci_reset(sc);
 	/*
 	 * We cannot call the callback directly since we could then be reset
@@ -1412,8 +1459,7 @@ slhci_reset_entry(void *arg)
 	 * set. The callback code will check the wait queue.
 	 */
 	slhci_callback_schedule(sc);
-	simple_unlock(&sc->sc_lock);
-	splx(s);
+	mutex_exit(&sc->sc_intr_lock);
 }
 
 usbd_status
@@ -1421,15 +1467,11 @@ slhci_lock_call(struct slhci_softc *sc, 
     *spipe, struct usbd_xfer *xfer)
 {
 	usbd_status ret;
-	int x, s;
 
-	x = splusb();
-	s = splhardusb();
-	simple_lock(&sc->sc_lock);
+	mutex_enter(&sc->sc_intr_lock);
 	ret = (*lcf)(sc, spipe, xfer);
-	slhci_main(sc, &s);
-	splx(s);
-	splx(x);
+	slhci_main(sc);
+	mutex_exit(&sc->sc_intr_lock);
 
 	return ret;
 }
@@ -1438,28 +1480,18 @@ void
 slhci_start_entry(struct slhci_softc *sc, struct slhci_pipe *spipe)
 {
 	struct slhci_transfers *t;
-	int s;
 
+	mutex_enter(&sc->sc_intr_lock);
 	t = &sc->sc_transfers;
 
-	s = splhardusb();
-#ifdef SLHCI_WAITLOCK
-	if (simple_lock_try(&sc->sc_lock))
-#else
-	simple_lock(&sc->sc_lock);
-#endif
-	{
+	if (!(t->flags & (F_AINPROG|F_BINPROG))) {
 		slhci_enter_xfer(sc, spipe);
 		slhci_dotransfer(sc);
-		slhci_main(sc, &s);
-#ifdef SLHCI_WAITLOCK
+		slhci_main(sc);
 	} else {
-		simple_lock(&sc->sc_wait_lock);
 		enter_waitq(sc, spipe);
-		simple_unlock(&sc->sc_wait_lock);
-#endif
 	}
-	splx(s);
+	mutex_exit(&sc->sc_intr_lock);
 }
 
 void
@@ -1467,60 +1499,45 @@ slhci_callback_entry(void *arg)
 {
 	struct slhci_softc *sc;
 	struct slhci_transfers *t;
-	int s, x;
-
 
 	sc = (struct slhci_softc *)arg;
 
-	x = splusb();
-	s = splhardusb();
-	simple_lock(&sc->sc_lock);
+	KASSERT(mutex_owned(&sc->sc_lock));
+
+	mutex_enter(&sc->sc_intr_lock);
 	t = &sc->sc_transfers;
 	DLOG(D_SOFT, "callback_entry flags %#x", t->flags, 0,0,0);
 
-#ifdef SLHCI_WAITLOCK
 repeat:
-#endif
-	slhci_callback(sc, &s);
+	slhci_callback(sc);
 
-#ifdef SLHCI_WAITLOCK
-	simple_lock(&sc->sc_wait_lock);
 	if (!gcq_empty(&sc->sc_waitq)) {
 		slhci_enter_xfers(sc);
-		simple_unlock(&sc->sc_wait_lock);
 		slhci_dotransfer(sc);
 		slhci_waitintr(sc, 0);
 		goto repeat;
 	}
 
 	t->flags &= ~F_CALLBACK;
-	simple_unlock(&sc->sc_lock);
-	simple_unlock(&sc->sc_wait_lock);
-#else
-	t->flags &= ~F_CALLBACK;
-	simple_unlock(&sc->sc_lock);
-#endif
-	splx(s);
-	splx(x);
+	mutex_exit(&sc->sc_intr_lock);
 }
 
 void
-slhci_do_callback(struct slhci_softc *sc, struct usbd_xfer *xfer, int *s)
+slhci_do_callback(struct slhci_softc *sc, struct usbd_xfer *xfer)
 {
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	int repeat;
 
 	start_cc_time(&t_callback, (u_int)xfer);
-	simple_unlock(&sc->sc_lock);
-	splx(*s);
+	mutex_exit(&sc->sc_intr_lock);
 
+	mutex_enter(&sc->sc_lock);
 	repeat = xfer->pipe->repeat;
-
 	usb_transfer_complete(xfer);
+	mutex_exit(&sc->sc_lock);
 
-	*s = splhardusb();
-	simple_lock(&sc->sc_lock);
+	mutex_enter(&sc->sc_intr_lock);
 	stop_cc_time(&t_callback);
 
 	if (repeat && !sc->sc_bus.use_polling)
@@ -1530,16 +1547,15 @@ slhci_do_callback(struct slhci_softc *sc
 int
 slhci_intr(void *arg)
 {
-	struct slhci_softc *sc;
+	struct slhci_softc *sc = arg;
 	int ret;
 
-	sc = (struct slhci_softc *)arg;
-
 	start_cc_time(&t_hard_int, (unsigned int)arg);
-	simple_lock(&sc->sc_lock);
+	mutex_enter(&sc->sc_intr_lock);
 
 	ret = slhci_dointr(sc);
-	slhci_main(sc, NULL);
+	slhci_main(sc);
+	mutex_exit(&sc->sc_intr_lock);
 
 	stop_cc_time(&t_hard_int);
 	return ret;
@@ -1547,56 +1563,38 @@ slhci_intr(void *arg)
 
 /* called with main lock only held, returns with locks released. */
 void
-slhci_main(struct slhci_softc *sc, int *s)
+slhci_main(struct slhci_softc *sc)
 {
 	struct slhci_transfers *t;
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
-#ifdef SLHCI_WAITLOCK
 waitcheck:
-#endif
 	slhci_waitintr(sc, slhci_wait_time);
 
-
 	/*
-	 * XXX Directly calling the callback anytime s != NULL
-	 * causes panic:sbdrop with aue (simultaneously using umass).
-	 * Doing that affects process accounting, but is supposed to work as
-	 * far as I can tell.
-	 *
 	 * The direct call is needed in the use_polling and disabled cases
 	 * since the soft interrupt is not available.  In the disabled case,
 	 * this code can be reached from the usb detach, after the reaping of
-	 * the soft interrupt.  That test could be !F_ACTIVE (in which case
-	 * s != NULL could be an assertion), but there is no reason not to
-	 * make the callbacks directly in the other DISABLED cases.
+	 * the soft interrupt.  That test could be !F_ACTIVE, but there is no
+	 * reason not to make the callbacks directly in the other DISABLED
+	 * cases.
 	 */
 	if ((t->flags & F_ROOTINTR) || !gcq_empty(&t->q[Q_CALLBACKS])) {
-		if (__predict_false(sc->sc_bus.use_polling || t->flags &
-		    F_DISABLED) && s != NULL)
-			slhci_callback(sc, s);
+		if (__predict_false(sc->sc_bus.use_polling ||
+		    t->flags & F_DISABLED))
+			slhci_callback(sc);
 		else
 			slhci_callback_schedule(sc);
 	}
 
-#ifdef SLHCI_WAITLOCK
-	simple_lock(&sc->sc_wait_lock);
-
 	if (!gcq_empty(&sc->sc_waitq)) {
 		slhci_enter_xfers(sc);
-		simple_unlock(&sc->sc_wait_lock);
 		slhci_dotransfer(sc);
 		goto waitcheck;
 	}
-
-	simple_unlock(&sc->sc_lock);
-	simple_unlock(&sc->sc_wait_lock);
-#else
-	simple_unlock(&sc->sc_lock);
-#endif
 }
 
 /* End lock entry functions. Start in lock function. */
@@ -1755,7 +1753,7 @@ slhci_waitintr(struct slhci_softc *sc, i
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (__predict_false(sc->sc_bus.use_polling))
 		wait_time = 12000;
@@ -1779,7 +1777,7 @@ slhci_dointr(struct slhci_softc *sc)
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (sc->sc_ier == 0)
 		return 0;
@@ -1827,7 +1825,6 @@ slhci_dointr(struct slhci_softc *sc)
 	slhci_write(sc, SL11_ISR, r);
 	BSB_SYNC(sc->iot, sc->ioh, sc->pst, sc->psz);
 
-
 	/* If we have an insertion event we do not care about anything else. */
 	if (__predict_false(r & SL11_ISR_INSERT)) {
 		slhci_insert(sc);
@@ -1956,7 +1953,7 @@ slhci_abdone(struct slhci_softc *sc, int
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	DLOG(D_TRACE, "ABDONE flags %#x", t->flags, 0,0,0);
 
@@ -2251,11 +2248,10 @@ slhci_tstart(struct slhci_softc *sc)
 	struct slhci_transfers *t;
 	struct slhci_pipe *spipe;
 	int remaining_bustime;
-	int s;
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (!(t->flags & (F_AREADY|F_BREADY)))
 		return;
@@ -2269,7 +2265,6 @@ slhci_tstart(struct slhci_softc *sc)
 	 * signal transfer complete.  This leaves no time for any other
 	 * interrupts.
 	 */
-	s = splhigh();
 	remaining_bustime = (int)(slhci_read(sc, SL811_CSOF)) << 6;
 	remaining_bustime -= SLHCI_END_BUSTIME;
 
@@ -2306,7 +2301,6 @@ pend:
 			t->pend = spipe->bustime;
 		}
 	}
-	splx(s);
 }
 
 static void
@@ -2318,7 +2312,7 @@ slhci_dotransfer(struct slhci_softc *sc)
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
  	while ((t->len[A] == -1 || t->len[B] == -1) &&
 	    (GOT_FIRST_TIMED_COND(spipe, t, spipe->frame <= t->frame) ||
@@ -2388,10 +2382,9 @@ slhci_dotransfer(struct slhci_softc *sc)
 
 /*
  * slhci_callback is called after the lock is taken from splusb.
- * s is pointer to old spl (splusb).
  */
 static void
-slhci_callback(struct slhci_softc *sc, int *s)
+slhci_callback(struct slhci_softc *sc)
 {
 	struct slhci_transfers *t;
 	struct slhci_pipe *spipe;
@@ -2399,7 +2392,7 @@ slhci_callback(struct slhci_softc *sc, i
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	DLOG(D_SOFT, "CB flags %#x", t->flags, 0,0,0);
 	for (;;) {
@@ -2428,7 +2421,7 @@ slhci_callback(struct slhci_softc *sc, i
 		    "type %s", xfer->length, xfer->actlen, spipe,
 		    pnames(spipe->ptype));
 do_callback:
-		slhci_do_callback(sc, xfer, s);
+		slhci_do_callback(sc, xfer);
 	}
 }
 
@@ -2439,7 +2432,7 @@ slhci_enter_xfer(struct slhci_softc *sc,
 
 	t = &sc->sc_transfers;
 
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 
 	if (__predict_false(t->flags & F_DISABLED) ||
 	    __predict_false(spipe->pflags & PF_GONE)) {
@@ -2460,18 +2453,16 @@ slhci_enter_xfer(struct slhci_softc *sc,
 		enter_callback(t, spipe);
 }
 
-#ifdef SLHCI_WAITLOCK
 static void
 slhci_enter_xfers(struct slhci_softc *sc)
 {
 	struct slhci_pipe *spipe;
 
-	SLHCI_LOCKASSERT(sc, locked, locked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	while (DEQUEUED_WAITQ(spipe, sc))
 		slhci_enter_xfer(sc, spipe);
 }
-#endif
 
 static void
 slhci_queue_timed(struct slhci_softc *sc, struct slhci_pipe *spipe)
@@ -2482,7 +2473,7 @@ slhci_queue_timed(struct slhci_softc *sc
 
 	t = &sc->sc_transfers;
 
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 
 	FIND_TIMED(q, t, spp, spp->frame > spipe->frame);
 	gcq_insert_before(q, &spipe->xq);
@@ -2497,7 +2488,7 @@ slhci_xfer_timer(struct slhci_softc *sc,
 
 	t = &sc->sc_transfers;
 
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 
 	FIND_TO(q, t, spp, spp->to_frame >= spipe->to_frame);
 	gcq_insert_before(q, &spipe->to);
@@ -2533,7 +2524,7 @@ slhci_callback_schedule(struct slhci_sof
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (t->flags & F_ACTIVE)
 		slhci_do_callback_schedule(sc);
@@ -2546,7 +2537,7 @@ slhci_do_callback_schedule(struct slhci_
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (!(t->flags & F_CALLBACK)) {
 		t->flags |= F_CALLBACK;
@@ -2555,16 +2546,16 @@ slhci_do_callback_schedule(struct slhci_
 }
 
 #if 0
-/* must be called with lock taken from splusb */
+/* must be called with lock taken from IPL_USB */
 /* XXX static */ void
-slhci_pollxfer(struct slhci_softc *sc, struct usbd_xfer *xfer, int *s)
+slhci_pollxfer(struct slhci_softc *sc, struct usbd_xfer *xfer)
 {
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 	slhci_dotransfer(sc);
 	do {
 		slhci_dointr(sc);
 	} while (xfer->status == USBD_IN_PROGRESS);
-	slhci_do_callback(sc, xfer, s);
+	slhci_do_callback(sc, xfer);
 }
 #endif
 
@@ -2657,7 +2648,7 @@ slhci_do_abort(struct slhci_softc *sc, s
 
 	t = &sc->sc_transfers;
 
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 
 	if (spipe->xfer == xfer) {
 		if (spipe->ptype == PT_ROOT_INTR) {
@@ -2687,92 +2678,8 @@ slhci_do_abort(struct slhci_softc *sc, s
 	return USBD_NORMAL_COMPLETION;
 }
 
-static usbd_status
-slhci_do_attach(struct slhci_softc *sc, struct slhci_pipe *spipe, struct
-    usbd_xfer *xfer)
-{
-	struct slhci_transfers *t;
-	const char *rev;
-
-	t = &sc->sc_transfers;
-
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
-
-	/* Detect and check the controller type */
-	t->sltype = SL11_GET_REV(slhci_read(sc, SL11_REV));
-
-	/* SL11H not supported */
-	if (!slhci_supported_rev(t->sltype)) {
-		if (t->sltype == SLTYPE_SL11H)
-			printf("%s: SL11H unsupported or bus error!\n",
-			    SC_NAME(sc));
-		else
-			printf("%s: Unknown chip revision!\n", SC_NAME(sc));
-		return USBD_INVAL;
-	}
-
-	callout_init(&sc->sc_timer, CALLOUT_MPSAFE);
-	callout_setfunc(&sc->sc_timer, slhci_reset_entry, sc);
-
-	/*
-	 * It is not safe to call the soft interrupt directly as
-	 * usb_schedsoftintr does in the use_polling case (due to locking).
-	 */
-	sc->sc_cb_softintr = softint_establish(SOFTINT_NET,
-	    slhci_callback_entry, sc);
-
-#ifdef SLHCI_DEBUG
-	ssc = sc;
-#ifdef USB_DEBUG
-	if (slhci_usbdebug >= 0)
-		usbdebug = slhci_usbdebug;
-#endif
-#endif
-
-	if (t->sltype == SLTYPE_SL811HS_R12)
-		rev = " (rev 1.2)";
-	else if (t->sltype == SLTYPE_SL811HS_R14)
-		rev = " (rev 1.4 or 1.5)";
-	else
-		rev = " (unknown revision)";
-
-	aprint_normal("%s: ScanLogic SL811HS/T USB Host Controller %s\n",
-	    SC_NAME(sc), rev);
-
-	aprint_normal("%s: Max Current %u mA (value by code, not by probe)\n",
-	    SC_NAME(sc), t->max_current * 2);
-
-#if defined(SLHCI_DEBUG) || defined(SLHCI_NO_OVERTIME) || \
-    defined(SLHCI_TRY_LSVH) || defined(SLHCI_PROFILE_TRANSFER)
-	aprint_normal("%s: driver options:"
-#ifdef SLHCI_DEBUG
-	" SLHCI_DEBUG"
-#endif
-#ifdef SLHCI_TRY_LSVH
-	" SLHCI_TRY_LSVH"
-#endif
-#ifdef SLHCI_NO_OVERTIME
-	" SLHCI_NO_OVERTIME"
-#endif
-#ifdef SLHCI_PROFILE_TRANSFER
-	" SLHCI_PROFILE_TRANSFER"
-#endif
-	"\n", SC_NAME(sc));
-#endif
-	sc->sc_bus.usbrev = USBREV_1_1;
-	sc->sc_bus.methods = __UNCONST(&slhci_bus_methods);
-	sc->sc_bus.pipe_size = sizeof(struct slhci_pipe);
-
-	if (!sc->sc_enable_power)
-		t->flags |= F_REALPOWER;
-
-	t->flags |= F_ACTIVE;
-
-	return USBD_NORMAL_COMPLETION;
-}
-
 /*
- * Called to deactivate or stop use of the controller instead of panicing.
+ * Called to deactivate or stop use of the controller instead of panicking.
  * Will cancel the xfer correctly even when not on a list.
  */
 static usbd_status
@@ -2781,7 +2688,7 @@ slhci_halt(struct slhci_softc *sc, struc
 {
 	struct slhci_transfers *t;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	t = &sc->sc_transfers;
 
@@ -2830,7 +2737,7 @@ slhci_halt(struct slhci_softc *sc, struc
 static void
 slhci_intrchange(struct slhci_softc *sc, uint8_t new_ier)
 {
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 	if (sc->sc_ier != new_ier) {
 		sc->sc_ier = new_ier;
 		slhci_write(sc, SL11_IER, new_ier);
@@ -2850,7 +2757,7 @@ slhci_drain(struct slhci_softc *sc)
 	struct gcq *q;
 	int i;
 
- 	SLHCI_LOCKASSERT(sc, locked, unlocked);
+ 	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	t = &sc->sc_transfers;
 
@@ -2909,7 +2816,7 @@ slhci_reset(struct slhci_softc *sc)
 	uint8_t r, pol, ctrl;
 
 	t = &sc->sc_transfers;
-	SLHCI_MAINLOCKASSERT(sc);
+	KASSERT(mutex_owned(&sc->sc_intr_lock));
 
 	stop_cc_time(&t_delay);
 
@@ -3013,7 +2920,7 @@ slhci_reserve_bustime(struct slhci_softc
 	struct slhci_transfers *t;
 	int bustime, max_packet;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	t = &sc->sc_transfers;
 	max_packet = UGETW(spipe->pipe.endpoint->edesc->wMaxPacketSize);
@@ -3070,7 +2977,7 @@ slhci_insert(struct slhci_softc *sc)
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (t->flags & F_NODEV)
 		slhci_intrchange(sc, 0);
@@ -3160,7 +3067,7 @@ slhci_clear_feature(struct slhci_softc *
 	t = &sc->sc_transfers;
 	error = USBD_NORMAL_COMPLETION;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (what == UHF_PORT_POWER) {
 		DLOG(D_MSG, "POWER_OFF", 0,0,0,0);
@@ -3196,7 +3103,7 @@ slhci_set_feature(struct slhci_softc *sc
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (what == UHF_PORT_RESET) {
 		if (!(t->flags & F_ACTIVE)) {
@@ -3267,7 +3174,7 @@ slhci_get_status(struct slhci_softc *sc,
 
 	t = &sc->sc_transfers;
 
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	/*
 	 * We do not have a way to detect over current or bable and
@@ -3313,7 +3220,7 @@ slhci_root(struct slhci_softc *sc, struc
 	    USBD_CANCELLED);
 
 	DLOG(D_TRACE, "%s start", pnames(SLHCI_XFER_TYPE(xfer)), 0,0,0);
-	SLHCI_LOCKASSERT(sc, locked, unlocked);
+	KASSERT(mutex_locked(&sc->sc_intr_lock));
 
 	if (spipe->ptype == PT_ROOT_INTR) {
 		LK_SLASSERT(t->rootintr == NULL, sc, spipe, xfer, return

Index: src/sys/dev/ic/sl811hsvar.h
diff -u src/sys/dev/ic/sl811hsvar.h:1.10 src/sys/dev/ic/sl811hsvar.h:1.11
--- src/sys/dev/ic/sl811hsvar.h:1.10	Sun Sep 22 06:54:35 2013
+++ src/sys/dev/ic/sl811hsvar.h	Wed Oct  2 22:55:04 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: sl811hsvar.h,v 1.10 2013/09/22 06:54:35 skrll Exp $	*/
+/*	$NetBSD: sl811hsvar.h,v 1.11 2013/10/02 22:55:04 skrll Exp $	*/
 
 /*
  * Not (c) 2007 Matthew Orgass
@@ -14,7 +14,6 @@
  */
 
 #include <sys/gcq.h>
-#include <sys/simplelock.h>
 
 #define SC_DEV(sc)	((sc)->sc_dev)
 #define SC_NAME(sc)	(device_xname(SC_DEV(sc)))
@@ -55,8 +54,8 @@ struct slhci_softc {
 	device_t		sc_dev;
 	struct usbd_bus		sc_bus;
 
-	struct simplelock	sc_lock;
-	struct simplelock	sc_wait_lock;
+	kmutex_t		sc_lock;
+	kmutex_t		sc_intr_lock;
 
 	struct slhci_transfers	sc_transfers;	/* Info useful in transfers. */
 

Reply via email to