Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb complete the port to audiomp: take kernel lock ...
details: https://anonhg.NetBSD.org/src/rev/ec9d26bc562f
branches: trunk
changeset: 771507:ec9d26bc562f
user: mrg <mrg%NetBSD.org@localhost>
date: Wed Nov 23 23:50:46 2011 +0000
description:
complete the port to audiomp: take kernel lock in a few places for
USB (like uaudio), kill most of the spl* uses.
diffstat:
sys/dev/usb/umidi.c | 61 ++++++++++++++++++++++++++++------------------------
1 files changed, 33 insertions(+), 28 deletions(-)
diffs (265 lines):
diff -r 346b5db7733a -r ec9d26bc562f sys/dev/usb/umidi.c
--- a/sys/dev/usb/umidi.c Wed Nov 23 23:12:48 2011 +0000
+++ b/sys/dev/usb/umidi.c Wed Nov 23 23:50:46 2011 +0000
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
ep->soliciting = 1;
softint_schedule(ep->solicit_cookie);
}
- splx(s);
+ mutex_spin_exit(&sc->sc_intr_lock);
return 0;
}
@@ -1670,7 +1673,7 @@
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 @@
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 @@
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 @@
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 @@
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);
}
Home |
Main Index |
Thread Index |
Old Index