Module Name:    src
Committed By:   mrg
Date:           Wed Nov 23 23:50:47 UTC 2011

Modified Files:
        src/sys/dev/usb: umidi.c

Log Message:
complete the port to audiomp:  take kernel lock in a few places for
USB (like uaudio), kill most of the spl* uses.


To generate a diff of this commit:
cvs rdiff -u -r1.45 -r1.46 src/sys/dev/usb/umidi.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/umidi.c
diff -u src/sys/dev/usb/umidi.c:1.45 src/sys/dev/usb/umidi.c:1.46
--- src/sys/dev/usb/umidi.c:1.45	Wed Nov 23 23:07:36 2011
+++ src/sys/dev/usb/umidi.c	Wed Nov 23 23:50:46 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: umidi.c,v 1.45 2011/11/23 23:07:36 jmcneill Exp $	*/
+/*	$NetBSD: umidi.c,v 1.46 2011/11/23 23:50:46 mrg Exp $	*/
 /*
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.45 2011/11/23 23:07:36 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.46 2011/11/23 23:50:46 mrg Exp $");
 
 #include <sys/types.h>
 #include <sys/param.h>
@@ -204,6 +204,7 @@ umidi_attach(device_t parent, device_t s
 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
 
+	KERNEL_LOCK(1, curlwp);
 	err = alloc_all_endpoints(sc);
 	if (err!=USBD_NORMAL_COMPLETION) {
 		aprint_error_dev(self,
@@ -236,6 +237,7 @@ umidi_attach(device_t parent, device_t s
 		aprint_error_dev(self,
 		    "attach_all_mididevs failed. (err=%d)\n", err);
 	}
+	KERNEL_UNLOCK_ONE(curlwp);
 
 #ifdef UMIDI_DEBUG
 	dump_sc(sc);
@@ -291,6 +293,7 @@ umidi_detach(device_t self, int flags)
 
 	DPRINTFN(1,("umidi_detach\n"));
 
+	KERNEL_LOCK(1, curlwp);
 	sc->sc_dying = 1;
 	detach_all_mididevs(sc, flags);
 	free_all_mididevs(sc);
@@ -299,6 +302,7 @@ umidi_detach(device_t self, int flags)
 
 	usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
 			   sc->sc_dev);
+	KERNEL_UNLOCK_ONE(curlwp);
 
 	mutex_destroy(&sc->sc_lock);
 	mutex_destroy(&sc->sc_intr_lock);
@@ -354,16 +358,13 @@ bad:
 void
 umidi_close(void *addr)
 {
-	int s;
 	struct umidi_mididev *mididev = addr;
 
-	s = splusb();
 	if ((mididev->flags & FWRITE) && mididev->out_jack)
 		close_out_jack(mididev->out_jack);
 	if ((mididev->flags & FREAD) && mididev->in_jack)
 		close_in_jack(mididev->in_jack);
 	mididev->opened = 0;
-	splx(s);
 }
 
 int
@@ -539,7 +540,7 @@ alloc_all_endpoints(struct umidi_softc *
 	} else {
 		err = alloc_all_endpoints_genuine(sc);
 	}
-	if (err!=USBD_NORMAL_COMPLETION)
+	if (err != USBD_NORMAL_COMPLETION)
 		return err;
 
 	ep = sc->sc_endpoints;
@@ -560,8 +561,9 @@ static void
 free_all_endpoints(struct umidi_softc *sc)
 {
 	int i;
+
 	for (i=0; i<sc->sc_in_num_endpoints+sc->sc_out_num_endpoints; i++)
-	    free_pipe(&sc->sc_endpoints[i]);
+		free_pipe(&sc->sc_endpoints[i]);
 	if (sc->sc_endpoints != NULL)
 		free(sc->sc_endpoints, M_USBDEV);
 	sc->sc_endpoints = sc->sc_out_ep = sc->sc_in_ep = NULL;
@@ -967,14 +969,13 @@ alloc_all_jacks(struct umidi_softc *sc)
 static void
 free_all_jacks(struct umidi_softc *sc)
 {
-	int s;
 
-	s = splaudio();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	if (sc->sc_out_jacks) {
 		free(sc->sc_jacks, M_USBDEV);
 		sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
 	}
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 }
 
 static usbd_status
@@ -1076,8 +1077,8 @@ static usbd_status
 open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
 {
 	struct umidi_endpoint *ep = jack->endpoint;
+	struct umidi_softc *sc = ep->sc;
 	umidi_packet_bufp end;
-	int s;
 	int err;
 
 	if (jack->opened)
@@ -1087,7 +1088,7 @@ open_out_jack(struct umidi_jack *jack, v
 	jack->u.out.intr = intr;
 	jack->midiman_ppkt = NULL;
 	end = ep->buffer + ep->buffer_size / sizeof *ep->buffer;
-	s = splusb();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	jack->opened = 1;
 	ep->num_open++;
 	/*
@@ -1101,11 +1102,11 @@ open_out_jack(struct umidi_jack *jack, v
 		if ( err ) {
 			ep->num_open--;
 			jack->opened = 0;
-			splx(s);
+			mutex_spin_exit(&sc->sc_intr_lock);
 			return USBD_IOERROR;
 		}
 	}
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 
 	return USBD_NORMAL_COMPLETION;
 }
@@ -1137,14 +1138,15 @@ static void
 close_out_jack(struct umidi_jack *jack)
 {
 	struct umidi_endpoint *ep;
-	int s;
+	struct umidi_softc *sc;
 	u_int16_t mask;
 	int err;
 
 	if (jack->opened) {
 		ep = jack->endpoint;
+		sc = ep->sc;
 		mask = 1 << (jack->cable_number);
-		s = splusb();
+		mutex_spin_enter(&sc->sc_intr_lock);
 		while ( mask & (ep->this_schedule | ep->next_schedule) ) {
 			err = tsleep(ep, PWAIT|PCATCH, "umi dr", mstohz(10));
 			if ( err )
@@ -1154,7 +1156,7 @@ close_out_jack(struct umidi_jack *jack)
 		jack->endpoint->num_open--;
 		ep->this_schedule &= ~mask;
 		ep->next_schedule &= ~mask;
-		splx(s);
+		mutex_spin_exit(&sc->sc_intr_lock);
 	}
 }
 
@@ -1428,11 +1430,13 @@ start_output_transfer(struct umidi_endpo
 	length = (ep->next_slot - ep->buffer) * sizeof *ep->buffer;
 	DPRINTFN(200,("umidi out transfer: start %p end %p length %u\n",
 	    ep->buffer, ep->next_slot, length));
+	KERNEL_LOCK(1, curlwp);
 	usbd_setup_xfer(ep->xfer, ep->pipe,
 			(usbd_private_handle)ep,
 			ep->buffer, length,
 			USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr);
 	rv = usbd_transfer(ep->xfer);
+	KERNEL_UNLOCK_ONE(curlwp);
 	
 	/*
 	 * Once the transfer is scheduled, no more adding to partial
@@ -1485,7 +1489,6 @@ out_jack_output(struct umidi_jack *out_j
 	struct umidi_endpoint *ep = out_jack->endpoint;
 	struct umidi_softc *sc = ep->sc;
 	unsigned char *packet;
-	int s;
 	int plen;
 	int poff;
 
@@ -1503,7 +1506,7 @@ out_jack_output(struct umidi_jack *out_j
 	    umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec,
 	    ep, out_jack->cable_number, len, cin));
 	
-	s = splusb();
+	mutex_spin_enter(&sc->sc_intr_lock);
 	packet = *ep->next_slot++;
 	KASSERT(ep->buffer_size >=
 	    (ep->next_slot - ep->buffer) * sizeof *ep->buffer);
@@ -1551,7 +1554,7 @@ out_jack_output(struct umidi_jack *out_j
 		ep->soliciting = 1;
 		softint_schedule(ep->solicit_cookie);
 	}
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 	
 	return 0;
 }
@@ -1670,7 +1673,7 @@ out_intr(usbd_xfer_handle xfer, usbd_pri
 	wakeup(ep);
 	/*
 	 * Do not want anyone else to see armed <- 0 before soliciting <- 1.
-	 * Running at splusb so the following should happen to be safe.
+	 * Running at IPL_USB so the following should happen to be safe.
 	 */
 	ep->armed = 0;
 	if ( !ep->soliciting ) {
@@ -1700,7 +1703,7 @@ static void
 out_solicit(void *arg)
 {
 	struct umidi_endpoint *ep = arg;
-	int s;
+	struct umidi_softc *sc = ep->sc;
 	umidi_packet_bufp end;
 	u_int16_t which;
 	struct umidi_jack *jack;
@@ -1708,12 +1711,12 @@ out_solicit(void *arg)
 	end = ep->buffer + ep->buffer_size / sizeof *ep->buffer;
 	
 	for ( ;; ) {
-		s = splusb();
+		mutex_spin_enter(&sc->sc_intr_lock);
 		if ( end - ep->next_slot <= ep->num_open - ep->num_scheduled )
-			break; /* at splusb */
+			break; /* at IPL_USB */
 		if ( ep->this_schedule == 0 ) {
 			if ( ep->next_schedule == 0 )
-				break; /* at splusb */
+				break; /* at IPL_USB */
 			ep->this_schedule = ep->next_schedule;
 			ep->next_schedule = 0;
 		}
@@ -1732,7 +1735,7 @@ out_solicit(void *arg)
 		which &= (~which)+1; /* now mask of least set bit */
 		ep->this_schedule &= ~which;
 		-- ep->num_scheduled;
-		splx(s);
+		mutex_spin_exit(&sc->sc_intr_lock);
 
 		-- which; /* now 1s below mask - count 1s to get index */
 		which -= ((which >> 1) & 0x5555);/* SWAR credit aggregate.org */
@@ -1741,13 +1744,15 @@ out_solicit(void *arg)
 		which +=  (which >> 8);
 		which &= 0x1f; /* the bit index a/k/a jack number */
 		
+		KERNEL_LOCK(1, curlwp);
 		jack = ep->jacks[which];
 		if (jack->u.out.intr)
 			(*jack->u.out.intr)(jack->arg);
+		KERNEL_UNLOCK_ONE(curlwp);
 	}
-	/* splusb at loop exit */
+	/* intr lock held at loop exit */
 	if ( !ep->armed  &&  ep->next_slot > ep->buffer )
 		ep->armed = (USBD_IN_PROGRESS == start_output_transfer(ep));
 	ep->soliciting = 0;
-	splx(s);
+	mutex_spin_exit(&sc->sc_intr_lock);
 }

Reply via email to