Sun Jan 11 14:13:25 2015 UTC ()
Pull up following revision(s) (requested by mrg in ticket #407):
	sys/dev/midivar.h: revision 1.20
	sys/dev/usb/umidivar.h: file removal
	sys/dev/midi.c: revision 1.82
	sys/dev/midi.c: revision 1.83
	sys/dev/usb/FILES: revision 1.13
	sys/dev/midi_if.h: revision 1.26
	sys/dev/sequencer.c: revision 1.60
	sys/dev/sequencer.c: revision 1.61
	sys/dev/sequencer.c: revision 1.62
	sys/dev/sequencer.c: revision 1.63
	sys/dev/usb/umidi_quirks.c: revision 1.19
	sys/dev/usb/umidi.c: revision 1.66
	sys/dev/usb/umidi.c: revision 1.67
	sys/dev/usb/umidi.c: revision 1.68
	sys/dev/usb/umidireg.h: file removal
	sys/dev/sequencervar.h: revision 1.17
fix the midi_if documentation to properly describe the locks that will
be held during various operations.
various umidi clean ups:
- move the contents of umidi{reg,var}.h into umidi.c directly as they
  are not referenced by any other file.
- remove the useless include of umidi{reg,var}.h from umidi_quirks.c.
- add reference counting and wait/broadcast support to the IO paths.
- fix the error handling in midi_attach() and midi_open().
- sprinkle KASSERT() in several places.
- drop the local interrupt lock before calling into various parts of
  the USB code.  fixes lockdebug issues, and likely hangs.
- rename "binded" member as "bound".
with these most of the panics and problems i've seen are gone.  there
is still one lockdebug panic to deal with that happens when unplugging
umidi while midiplay(1) is running.
various clean ups for midi and sequencer:
midi specific:
- add reference counting for midi operations, and ensure that
  detach waits for other threads to complete before tearing
  down the device completely.
- in detach, halt midi callouts before destroying them
- re-check sc->dying after sleeping in midiread()
- in real_writebytes(), make sure we're open and not dying
- make sure we drop the interrupt lock before calling any code
  that may want to check thread locks.  this is now safe due to
  the above changes.
sequencer specific:
- avoid caching the midi softc in the sequencer softc.  instead,
  every time we want to use it, look it up again and make sure
  it still exists.
this fixes various crashes i've seen in the usb midi code when
detaching the umidi while it is active.
use __func__ in some debug messages.
- check sc->dying after sleeping in several more places, and
  convert it into EIO error where necessary.
- remove a wrong additional mutex_exit() call.
- make sure to check sc->dying under the device lock.
- fix a confusion between midi(4) unit and connected to sequencer
  devices.
- minor comment/debug clean ups.
fixes problems attempting to read or write from the right midi(4)
device using the sequencer(4) device when one or more of the
non-final devices fails to open with midiseq_open().
fix !AUDIO_DEBUG build.
CID/1261465: Dereference after NULL check.
CID/1261467: Unreachable code
actually fix one of the previous:  don't test for NULL after deref.


(martin)
diff -r1.81 -r1.81.2.1 src/sys/dev/midi.c
diff -r1.25 -r1.25.14.1 src/sys/dev/midi_if.h
diff -r1.19 -r1.19.14.1 src/sys/dev/midivar.h
diff -r1.59 -r1.59.2.1 src/sys/dev/sequencer.c
diff -r1.16 -r1.16.10.1 src/sys/dev/sequencervar.h
diff -r1.12 -r1.12.22.1 src/sys/dev/usb/FILES
diff -r1.65 -r1.65.12.1 src/sys/dev/usb/umidi.c
diff -r1.18 -r1.18.14.1 src/sys/dev/usb/umidi_quirks.c
diff -r1.8 -r0 src/sys/dev/usb/umidireg.h
diff -r1.19 -r0 src/sys/dev/usb/umidivar.h

cvs diff -r1.81 -r1.81.2.1 src/sys/dev/midi.c (expand / switch to unified diff)

--- src/sys/dev/midi.c 2014/07/25 08:10:35 1.81
+++ src/sys/dev/midi.c 2015/01/11 14:13:25 1.81.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: midi.c,v 1.81 2014/07/25 08:10:35 dholland Exp $ */ 1/* $NetBSD: midi.c,v 1.81.2.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org), (MIDI FST and Active 8 * by Lennart Augustsson (augustss@NetBSD.org), (MIDI FST and Active
9 * Sense handling) Chapman Flack (chap@NetBSD.org), and Andrew Doran. 9 * Sense handling) Chapman Flack (chap@NetBSD.org), and Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -21,27 +21,27 @@ @@ -21,27 +21,27 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: midi.c,v 1.81 2014/07/25 08:10:35 dholland Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: midi.c,v 1.81.2.1 2015/01/11 14:13:25 martin Exp $");
35 35
36#include "midi.h" 36#include "midi.h"
37#include "sequencer.h" 37#include "sequencer.h"
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/ioctl.h> 40#include <sys/ioctl.h>
41#include <sys/fcntl.h> 41#include <sys/fcntl.h>
42#include <sys/vnode.h> 42#include <sys/vnode.h>
43#include <sys/select.h> 43#include <sys/select.h>
44#include <sys/poll.h> 44#include <sys/poll.h>
45#include <sys/proc.h> 45#include <sys/proc.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/callout.h> 47#include <sys/callout.h>
@@ -194,26 +194,31 @@ midiactivate(device_t self, enum devact  @@ -194,26 +194,31 @@ midiactivate(device_t self, enum devact
194 194
195int 195int
196mididetach(device_t self, int flags) 196mididetach(device_t self, int flags)
197{ 197{
198 struct midi_softc *sc = device_private(self); 198 struct midi_softc *sc = device_private(self);
199 int maj, mn; 199 int maj, mn;
200 200
201 DPRINTFN(2,("%s: sc=%p flags=%d\n", __func__, sc, flags)); 201 DPRINTFN(2,("%s: sc=%p flags=%d\n", __func__, sc, flags));
202 202
203 pmf_device_deregister(self); 203 pmf_device_deregister(self);
204 204
205 mutex_enter(sc->lock); 205 mutex_enter(sc->lock);
206 sc->dying = 1; 206 sc->dying = 1;
 207
 208 if (--sc->refcnt >= 0) {
 209 /* Wake anything? */
 210 (void)cv_timedwait(&sc->detach_cv, sc->lock, hz * 60);
 211 }
207 cv_broadcast(&sc->wchan); 212 cv_broadcast(&sc->wchan);
208 cv_broadcast(&sc->rchan); 213 cv_broadcast(&sc->rchan);
209 mutex_exit(sc->lock); 214 mutex_exit(sc->lock);
210 215
211 /* locate the major number */ 216 /* locate the major number */
212 maj = cdevsw_lookup_major(&midi_cdevsw); 217 maj = cdevsw_lookup_major(&midi_cdevsw);
213 218
214 /* 219 /*
215 * Nuke the vnodes for any open instances (calls close). 220 * Nuke the vnodes for any open instances (calls close).
216 * Will wait until any activity on the device nodes has ceased. 221 * Will wait until any activity on the device nodes has ceased.
217 * 222 *
218 * XXXAD NOT YET. 223 * XXXAD NOT YET.
219 * 224 *
@@ -226,28 +231,37 @@ mididetach(device_t self, int flags) @@ -226,28 +231,37 @@ mididetach(device_t self, int flags)
226 evcnt_detach(&sc->xmt.bytesDiscarded); 231 evcnt_detach(&sc->xmt.bytesDiscarded);
227 evcnt_detach(&sc->xmt.incompleteMessages); 232 evcnt_detach(&sc->xmt.incompleteMessages);
228 } 233 }
229 if (sc->props & MIDI_PROP_CAN_INPUT) { 234 if (sc->props & MIDI_PROP_CAN_INPUT) {
230 evcnt_detach(&sc->rcv.bytesDiscarded); 235 evcnt_detach(&sc->rcv.bytesDiscarded);
231 evcnt_detach(&sc->rcv.incompleteMessages); 236 evcnt_detach(&sc->rcv.incompleteMessages);
232 } 237 }
233 238
234 if (sc->sih != NULL) { 239 if (sc->sih != NULL) {
235 softint_disestablish(sc->sih); 240 softint_disestablish(sc->sih);
236 sc->sih = NULL; 241 sc->sih = NULL;
237 } 242 }
238 243
 244 mutex_enter(sc->lock);
 245 callout_halt(&sc->xmt_asense_co, sc->lock);
 246 callout_halt(&sc->rcv_asense_co, sc->lock);
 247 mutex_exit(sc->lock);
 248
 249 callout_destroy(&sc->xmt_asense_co);
 250 callout_destroy(&sc->rcv_asense_co);
 251
239 cv_destroy(&sc->wchan); 252 cv_destroy(&sc->wchan);
240 cv_destroy(&sc->rchan); 253 cv_destroy(&sc->rchan);
 254 cv_destroy(&sc->detach_cv);
241 255
242 return (0); 256 return (0);
243} 257}
244 258
245void 259void
246midi_attach(struct midi_softc *sc) 260midi_attach(struct midi_softc *sc)
247{ 261{
248 struct midi_info mi; 262 struct midi_info mi;
249 kmutex_t *dummy; 263 kmutex_t *dummy;
250 static int first = 1; 264 static int first = 1;
251 265
252 if (first) { 266 if (first) {
253 mutex_init(&hwif_softc_lock, MUTEX_DEFAULT, IPL_NONE); 267 mutex_init(&hwif_softc_lock, MUTEX_DEFAULT, IPL_NONE);
@@ -256,29 +270,31 @@ midi_attach(struct midi_softc *sc) @@ -256,29 +270,31 @@ midi_attach(struct midi_softc *sc)
256 270
257 sc->hw_if->get_locks(sc->hw_hdl, &sc->lock, &dummy); 271 sc->hw_if->get_locks(sc->hw_hdl, &sc->lock, &dummy);
258 272
259 callout_init(&sc->xmt_asense_co, CALLOUT_MPSAFE); 273 callout_init(&sc->xmt_asense_co, CALLOUT_MPSAFE);
260 callout_init(&sc->rcv_asense_co, CALLOUT_MPSAFE); 274 callout_init(&sc->rcv_asense_co, CALLOUT_MPSAFE);
261 callout_setfunc(&sc->xmt_asense_co, midi_xmt_asense, sc); 275 callout_setfunc(&sc->xmt_asense_co, midi_xmt_asense, sc);
262 callout_setfunc(&sc->rcv_asense_co, midi_rcv_asense, sc); 276 callout_setfunc(&sc->rcv_asense_co, midi_rcv_asense, sc);
263 277
264 sc->sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, 278 sc->sih = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE,
265 midi_softint, sc); 279 midi_softint, sc);
266 280
267 cv_init(&sc->rchan, "midird"); 281 cv_init(&sc->rchan, "midird");
268 cv_init(&sc->wchan, "midiwr"); 282 cv_init(&sc->wchan, "midiwr");
 283 cv_init(&sc->detach_cv, "mididet");
269 284
270 sc->dying = 0; 285 sc->dying = 0;
271 sc->isopen = 0; 286 sc->isopen = 0;
 287 sc->refcnt = 0;
272 288
273 mutex_enter(&hwif_softc_lock); 289 mutex_enter(&hwif_softc_lock);
274 mutex_enter(sc->lock); 290 mutex_enter(sc->lock);
275 hwif_softc = sc; 291 hwif_softc = sc;
276 sc->hw_if->getinfo(sc->hw_hdl, &mi); 292 sc->hw_if->getinfo(sc->hw_hdl, &mi);
277 hwif_softc = NULL; 293 hwif_softc = NULL;
278 mutex_exit(sc->lock); 294 mutex_exit(sc->lock);
279 mutex_exit(&hwif_softc_lock); 295 mutex_exit(&hwif_softc_lock);
280 296
281 sc->props = mi.props; 297 sc->props = mi.props;
282 298
283 if (!(sc->props & MIDI_PROP_NO_OUTPUT)) { 299 if (!(sc->props & MIDI_PROP_NO_OUTPUT)) {
284 evcnt_attach_dynamic(&sc->xmt.bytesDiscarded, 300 evcnt_attach_dynamic(&sc->xmt.bytesDiscarded,
@@ -854,26 +870,28 @@ static int @@ -854,26 +870,28 @@ static int
854midiclose(dev_t dev, int flags, int ifmt, struct lwp *l) 870midiclose(dev_t dev, int flags, int ifmt, struct lwp *l)
855{ 871{
856 struct midi_softc *sc; 872 struct midi_softc *sc;
857 const struct midi_hw_if *hw; 873 const struct midi_hw_if *hw;
858 874
859 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev)); 875 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));
860 hw = sc->hw_if; 876 hw = sc->hw_if;
861 877
862 DPRINTFN(3,("midiclose %p\n", sc)); 878 DPRINTFN(3,("midiclose %p\n", sc));
863 879
864 mutex_enter(sc->lock); 880 mutex_enter(sc->lock);
865 /* midi_start_output(sc); anything buffered => pbus already set! */ 881 /* midi_start_output(sc); anything buffered => pbus already set! */
866 while (sc->pbus) { 882 while (sc->pbus) {
 883 if (sc->dying)
 884 break;
867 DPRINTFN(8,("midiclose sleep ...\n")); 885 DPRINTFN(8,("midiclose sleep ...\n"));
868 cv_wait(&sc->wchan, sc->lock); 886 cv_wait(&sc->wchan, sc->lock);
869 } 887 }
870 sc->isopen = 0; 888 sc->isopen = 0;
871 callout_halt(&sc->xmt_asense_co, sc->lock); 889 callout_halt(&sc->xmt_asense_co, sc->lock);
872 callout_halt(&sc->rcv_asense_co, sc->lock); 890 callout_halt(&sc->rcv_asense_co, sc->lock);
873 hw->close(sc->hw_hdl); 891 hw->close(sc->hw_hdl);
874 sc->seqopen = 0; 892 sc->seqopen = 0;
875 sc->seq_md = 0; 893 sc->seq_md = 0;
876 mutex_exit(sc->lock); 894 mutex_exit(sc->lock);
877 895
878 return 0; 896 return 0;
879} 897}
@@ -942,35 +960,43 @@ midiread(dev_t dev, struct uio *uio, int @@ -942,35 +960,43 @@ midiread(dev_t dev, struct uio *uio, int
942 /* move the bytes */ 960 /* move the bytes */
943 if (appetite > 0) {  961 if (appetite > 0) {
944 first = 0; /* we know we won't return empty-handed */ 962 first = 0; /* we know we won't return empty-handed */
945 /* do two uiomoves if data wrap around end of buf */ 963 /* do two uiomoves if data wrap around end of buf */
946 if (buf_cur + appetite > buf_end) { 964 if (buf_cur + appetite > buf_end) {
947 DPRINTFN(8, 965 DPRINTFN(8,
948 ("midiread: uiomove cc=%td (prewrap)\n", 966 ("midiread: uiomove cc=%td (prewrap)\n",
949 buf_end - buf_cur)); 967 buf_end - buf_cur));
950 mutex_exit(sc->lock); 968 mutex_exit(sc->lock);
951 error = uiomove(buf_cur, buf_end - buf_cur, uio); 969 error = uiomove(buf_cur, buf_end - buf_cur, uio);
952 mutex_enter(sc->lock); 970 mutex_enter(sc->lock);
953 if (error) 971 if (error)
954 break; 972 break;
 973 if (sc->dying) {
 974 error = EIO;
 975 break;
 976 }
955 appetite -= buf_end - buf_cur; 977 appetite -= buf_end - buf_cur;
956 buf_cur = mb->buf; 978 buf_cur = mb->buf;
957 } 979 }
958 DPRINTFN(8, ("midiread: uiomove cc=%d\n", appetite)); 980 DPRINTFN(8, ("midiread: uiomove cc=%d\n", appetite));
959 mutex_exit(sc->lock); 981 mutex_exit(sc->lock);
960 error = uiomove(buf_cur, appetite, uio); 982 error = uiomove(buf_cur, appetite, uio);
961 mutex_enter(sc->lock); 983 mutex_enter(sc->lock);
962 if (error) 984 if (error)
963 break; 985 break;
 986 if (sc->dying) {
 987 error = EIO;
 988 break;
 989 }
964 buf_cur += appetite; 990 buf_cur += appetite;
965 } 991 }
966  992
967 MIDI_BUF_WRAP(idx); 993 MIDI_BUF_WRAP(idx);
968 MIDI_BUF_WRAP(buf); 994 MIDI_BUF_WRAP(buf);
969 MIDI_BUF_CONSUMER_WBACK(mb,idx); 995 MIDI_BUF_CONSUMER_WBACK(mb,idx);
970 MIDI_BUF_CONSUMER_WBACK(mb,buf); 996 MIDI_BUF_CONSUMER_WBACK(mb,buf);
971 if (0 == uio->uio_resid) /* if read satisfied, we're done */ 997 if (0 == uio->uio_resid) /* if read satisfied, we're done */
972 break; 998 break;
973 MIDI_BUF_CONSUMER_REFRESH(mb,idx); 999 MIDI_BUF_CONSUMER_REFRESH(mb,idx);
974 if (idx_cur == idx_lim) { /* need to wait for data? */ 1000 if (idx_cur == idx_lim) { /* need to wait for data? */
975 if (!first || sc->rcv_eof) /* never block reader if */ 1001 if (!first || sc->rcv_eof) /* never block reader if */
976 break; /* any data already in hand */ 1002 break; /* any data already in hand */
@@ -1243,33 +1269,33 @@ midi_intr_out(struct midi_softc *sc) @@ -1243,33 +1269,33 @@ midi_intr_out(struct midi_softc *sc)
1243 while (idx_cur != idx_lim) { 1269 while (idx_cur != idx_lim) {
1244 if (sc->hw_if_ext) { 1270 if (sc->hw_if_ext) {
1245 error = midi_msg_out(sc, &idx_cur, &idx_lim, 1271 error = midi_msg_out(sc, &idx_cur, &idx_lim,
1246 &buf_cur, &buf_lim); 1272 &buf_cur, &buf_lim);
1247 if (!error ) /* no EINPROGRESS from extended hw_if */ 1273 if (!error ) /* no EINPROGRESS from extended hw_if */
1248 armed = 1; 1274 armed = 1;
1249 break; 1275 break;
1250 } 1276 }
1251 /* or, lacking hw_if_ext ... */ 1277 /* or, lacking hw_if_ext ... */
1252 msglen = MB_IDX_LEN(*idx_cur); 1278 msglen = MB_IDX_LEN(*idx_cur);
1253 error = sc->hw_if->output(sc->hw_hdl, *buf_cur); 1279 error = sc->hw_if->output(sc->hw_hdl, *buf_cur);
1254 if (error && error != EINPROGRESS) 1280 if (error && error != EINPROGRESS)
1255 break; 1281 break;
1256 ++ buf_cur; 1282 ++buf_cur;
1257 MIDI_BUF_WRAP(buf); 1283 MIDI_BUF_WRAP(buf);
1258 -- msglen; 1284 --msglen;
1259 if (msglen) 1285 if (msglen)
1260 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur),msglen); 1286 *idx_cur = PACK_MB_IDX(MB_IDX_CAT(*idx_cur),msglen);
1261 else { 1287 else {
1262 ++ idx_cur; 1288 ++idx_cur;
1263 MIDI_BUF_WRAP(idx); 1289 MIDI_BUF_WRAP(idx);
1264 } 1290 }
1265 if (!error) { 1291 if (!error) {
1266 armed = 1; 1292 armed = 1;
1267 break; 1293 break;
1268 } 1294 }
1269 } 1295 }
1270 MIDI_BUF_CONSUMER_WBACK(mb,idx); 1296 MIDI_BUF_CONSUMER_WBACK(mb,idx);
1271 MIDI_BUF_CONSUMER_WBACK(mb,buf); 1297 MIDI_BUF_CONSUMER_WBACK(mb,buf);
1272 if (!armed) { 1298 if (!armed) {
1273 sc->pbus = 0; 1299 sc->pbus = 0;
1274 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD); 1300 callout_schedule(&sc->xmt_asense_co, MIDI_XMT_ASENSE_PERIOD);
1275 } 1301 }
@@ -1296,115 +1322,128 @@ midi_start_output(struct midi_softc *sc) @@ -1296,115 +1322,128 @@ midi_start_output(struct midi_softc *sc)
1296 return midi_intr_out(sc); 1322 return midi_intr_out(sc);
1297 return midi_poll_out(sc); 1323 return midi_poll_out(sc);
1298} 1324}
1299 1325
1300static int 1326static int
1301real_writebytes(struct midi_softc *sc, u_char *ibuf, int cc) 1327real_writebytes(struct midi_softc *sc, u_char *ibuf, int cc)
1302{ 1328{
1303 u_char *iend; 1329 u_char *iend;
1304 struct midi_buffer *mb; 1330 struct midi_buffer *mb;
1305 int arming, count, got; 1331 int arming, count, got;
1306 enum fst_form form; 1332 enum fst_form form;
1307 MIDI_BUF_DECLARE(idx); 1333 MIDI_BUF_DECLARE(idx);
1308 MIDI_BUF_DECLARE(buf); 1334 MIDI_BUF_DECLARE(buf);
 1335 int error;
1309 1336
1310 KASSERT(mutex_owned(sc->lock)); 1337 KASSERT(mutex_owned(sc->lock));
1311 1338
 1339 if (sc->dying || !sc->isopen)
 1340 return EIO;
 1341
 1342 sc->refcnt++;
 1343
1312 iend = ibuf + cc; 1344 iend = ibuf + cc;
1313 mb = &sc->outbuf; 1345 mb = &sc->outbuf;
1314 arming = 0; 1346 arming = 0;
1315  1347
1316 /* 1348 /*
1317 * If the hardware uses the extended hw_if, pass it canonicalized 1349 * If the hardware uses the extended hw_if, pass it canonicalized
1318 * messages (or compressed ones if it specifically requests, using 1350 * messages (or compressed ones if it specifically requests, using
1319 * VCOMP form so the bottom half can still pass the op and chan along); 1351 * VCOMP form so the bottom half can still pass the op and chan along);
1320 * if it does not, send it compressed messages (using COMPR form as 1352 * if it does not, send it compressed messages (using COMPR form as
1321 * there is no need to preserve the status for the bottom half). 1353 * there is no need to preserve the status for the bottom half).
1322 */ 1354 */
1323 if (NULL == sc->hw_if_ext) 1355 if (NULL == sc->hw_if_ext)
1324 form = FST_COMPR; 1356 form = FST_COMPR;
1325 else if (sc->hw_if_ext->compress) 1357 else if (sc->hw_if_ext->compress)
1326 form = FST_VCOMP; 1358 form = FST_VCOMP;
1327 else 1359 else
1328 form = FST_CANON; 1360 form = FST_CANON;
1329 1361
1330 MIDI_BUF_PRODUCER_INIT(mb,idx); 1362 MIDI_BUF_PRODUCER_INIT(mb,idx);
1331 MIDI_BUF_PRODUCER_INIT(mb,buf); 1363 MIDI_BUF_PRODUCER_INIT(mb,buf);
1332 
1333 if (sc->dying) 
1334 return EIO; 
1335  1364
1336 while (ibuf < iend) { 1365 while (ibuf < iend) {
1337 got = midi_fst(&sc->xmt, *ibuf, form); 1366 got = midi_fst(&sc->xmt, *ibuf, form);
1338 ++ ibuf; 1367 ++ibuf;
1339 switch ( got) { 1368 switch ( got) {
1340 case FST_MORE: 1369 case FST_MORE:
1341 continue; 1370 continue;
1342 case FST_ERR: 1371 case FST_ERR:
1343 case FST_HUH: 1372 case FST_HUH:
1344 return EPROTO; 1373 error = EPROTO;
 1374 goto out;
1345 case FST_CHN: 1375 case FST_CHN:
1346 case FST_CHV: /* only occurs in VCOMP form */ 1376 case FST_CHV: /* only occurs in VCOMP form */
1347 case FST_COM: 1377 case FST_COM:
1348 case FST_RT: 1378 case FST_RT:
1349 case FST_SYX: 1379 case FST_SYX:
1350 case FST_SXP: 1380 case FST_SXP:
1351 break; /* go add to buffer */ 1381 break; /* go add to buffer */
1352#if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC) 1382#if defined(AUDIO_DEBUG) || defined(DIAGNOSTIC)
1353 default: 1383 default:
1354 printf("midi_wr: midi_fst returned %d?!\n", got); 1384 printf("midi_wr: midi_fst returned %d?!\n", got);
1355#endif 1385#endif
1356 } 1386 }
1357 count = sc->xmt.end - sc->xmt.pos; 1387 count = sc->xmt.end - sc->xmt.pos;
1358 if (0 == count ) /* can happen with stray 0xf7; see midi_fst */ 1388 if (0 == count ) /* can happen with stray 0xf7; see midi_fst */
1359 continue; 1389 continue;
1360 /* 1390 /*
1361 * return EWOULDBLOCK if the data passed will not fit in 1391 * return EWOULDBLOCK if the data passed will not fit in
1362 * the buffer; the caller should have taken steps to avoid that. 1392 * the buffer; the caller should have taken steps to avoid that.
1363 * If got==FST_SXP we lose the new status byte, but we're losing 1393 * If got==FST_SXP we lose the new status byte, but we're losing
1364 * anyway, so c'est la vie. 1394 * anyway, so c'est la vie.
1365 */ 1395 */
1366 if (idx_cur == idx_lim || count > buf_lim - buf_cur) { 1396 if (idx_cur == idx_lim || count > buf_lim - buf_cur) {
1367 MIDI_BUF_PRODUCER_REFRESH(mb,idx); /* get the most */ 1397 MIDI_BUF_PRODUCER_REFRESH(mb,idx); /* get the most */
1368 MIDI_BUF_PRODUCER_REFRESH(mb,buf); /* current facts */ 1398 MIDI_BUF_PRODUCER_REFRESH(mb,buf); /* current facts */
1369 if (idx_cur == idx_lim || count > buf_lim - buf_cur) 1399 if (idx_cur == idx_lim || count > buf_lim - buf_cur) {
1370 return EWOULDBLOCK; /* caller's problem */ 1400 error = EWOULDBLOCK; /* caller's problem */
 1401 goto out;
 1402 }
1371 } 1403 }
1372 *idx_cur++ = PACK_MB_IDX(got,count); 1404 *idx_cur++ = PACK_MB_IDX(got,count);
1373 MIDI_BUF_WRAP(idx); 1405 MIDI_BUF_WRAP(idx);
1374 while (count) { 1406 while (count) {
1375 *buf_cur++ = *(sc->xmt.pos)++; 1407 *buf_cur++ = *(sc->xmt.pos)++;
1376 MIDI_BUF_WRAP(buf); 1408 MIDI_BUF_WRAP(buf);
1377 -- count; 1409 -- count;
1378 } 1410 }
1379 if (FST_SXP == got) 1411 if (FST_SXP == got)
1380 -- ibuf; /* again with same status byte */ 1412 -- ibuf; /* again with same status byte */
1381 } 1413 }
1382 MIDI_BUF_PRODUCER_WBACK(mb,buf); 1414 MIDI_BUF_PRODUCER_WBACK(mb,buf);
1383 MIDI_BUF_PRODUCER_WBACK(mb,idx); 1415 MIDI_BUF_PRODUCER_WBACK(mb,idx);
1384 /* 1416 /*
1385 * If the output transfer is not already busy, and there is a message 1417 * If the output transfer is not already busy, and there is a message
1386 * buffered, mark it busy, stop the Active Sense callout (what if we're 1418 * buffered, mark it busy, stop the Active Sense callout (what if we're
1387 * too late and it's expired already? No big deal, an extra Active Sense 1419 * too late and it's expired already? No big deal, an extra Active Sense
1388 * never hurt anybody) and start the output transfer once we're out of 1420 * never hurt anybody) and start the output transfer once we're out of
1389 * the critical section (pbus==1 will stop anyone else doing the same). 1421 * the critical section (pbus==1 will stop anyone else doing the same).
1390 */ 1422 */
1391 MIDI_BUF_CONSUMER_INIT(mb,idx); /* check what consumer's got to read */ 1423 MIDI_BUF_CONSUMER_INIT(mb,idx); /* check what consumer's got to read */
1392 if (!sc->pbus && idx_cur < idx_lim) { 1424 if (!sc->pbus && idx_cur < idx_lim) {
1393 sc->pbus = 1; 1425 sc->pbus = 1;
1394 callout_stop(&sc->xmt_asense_co); 1426 callout_stop(&sc->xmt_asense_co);
1395 arming = 1; 1427 arming = 1;
1396 } 1428 }
1397 return arming ? midi_start_output(sc) : 0; 1429
 1430 error = arming ? midi_start_output(sc) : 0;
 1431
 1432out:
 1433 if (--sc->refcnt < 0)
 1434 cv_broadcast(&sc->detach_cv);
 1435
 1436 return error;
1398} 1437}
1399 1438
1400static int 1439static int
1401midiwrite(dev_t dev, struct uio *uio, int ioflag) 1440midiwrite(dev_t dev, struct uio *uio, int ioflag)
1402{ 1441{
1403 struct midi_softc *sc; 1442 struct midi_softc *sc;
1404 struct midi_buffer *mb; 1443 struct midi_buffer *mb;
1405 int error; 1444 int error;
1406 u_char inp[256]; 1445 u_char inp[256];
1407 MIDI_BUF_DECLARE(idx); 1446 MIDI_BUF_DECLARE(idx);
1408 MIDI_BUF_DECLARE(buf); 1447 MIDI_BUF_DECLARE(buf);
1409 size_t idxspace; 1448 size_t idxspace;
1410 size_t bufspace; 1449 size_t bufspace;
@@ -1412,66 +1451,70 @@ midiwrite(dev_t dev, struct uio *uio, in @@ -1412,66 +1451,70 @@ midiwrite(dev_t dev, struct uio *uio, in
1412 int pollout = 0; 1451 int pollout = 0;
1413 1452
1414 (void)buf_end; (void)idx_end; 1453 (void)buf_end; (void)idx_end;
1415 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev)); 1454 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));
1416 1455
1417 DPRINTFN(6,("midiwrite: %p, unit=%d, count=%lu\n", sc, (int)minor(dev), 1456 DPRINTFN(6,("midiwrite: %p, unit=%d, count=%lu\n", sc, (int)minor(dev),
1418 (unsigned long)uio->uio_resid)); 1457 (unsigned long)uio->uio_resid));
1419 1458
1420 mutex_enter(sc->lock); 1459 mutex_enter(sc->lock);
1421 if (sc->dying) { 1460 if (sc->dying) {
1422 mutex_exit(sc->lock); 1461 mutex_exit(sc->lock);
1423 return EIO; 1462 return EIO;
1424 } 1463 }
 1464
 1465 sc->refcnt++;
 1466
1425 mb = &sc->outbuf; 1467 mb = &sc->outbuf;
1426 error = 0; 1468 error = 0;
1427 while (uio->uio_resid > 0 && !error) { 1469 while (uio->uio_resid > 0 && !error) {
1428 /* 1470 /*
1429 * block if necessary for the minimum buffer space to guarantee 1471 * block if necessary for the minimum buffer space to guarantee
1430 * we can write something. 1472 * we can write something.
1431 */ 1473 */
1432 MIDI_BUF_PRODUCER_INIT(mb,idx); /* init can't go above loop; */ 1474 MIDI_BUF_PRODUCER_INIT(mb,idx); /* init can't go above loop; */
1433 MIDI_BUF_PRODUCER_INIT(mb,buf); /* real_writebytes moves cur */ 1475 MIDI_BUF_PRODUCER_INIT(mb,buf); /* real_writebytes moves cur */
1434 for (;;) { 1476 for (;;) {
1435 idxspace = MIDI_BUF_PRODUCER_REFRESH(mb,idx) - idx_cur; 1477 idxspace = MIDI_BUF_PRODUCER_REFRESH(mb,idx) - idx_cur;
1436 bufspace = MIDI_BUF_PRODUCER_REFRESH(mb,buf) - buf_cur; 1478 bufspace = MIDI_BUF_PRODUCER_REFRESH(mb,buf) - buf_cur;
1437 if (idxspace >= 1 && bufspace >= 3 && !pollout) 1479 if (idxspace >= 1 && bufspace >= 3 && !pollout)
1438 break; 1480 break;
1439 DPRINTFN(8,("midi_write: sleep idx=%zd buf=%zd\n",  1481 DPRINTFN(8,("midi_write: sleep idx=%zd buf=%zd\n",
1440 idxspace, bufspace)); 1482 idxspace, bufspace));
1441 if (ioflag & IO_NDELAY) { 1483 if (ioflag & IO_NDELAY) {
1442 /* 1484 /*
1443 * If some amount has already been transferred, 1485 * If some amount has already been transferred,
1444 * the common syscall code will automagically 1486 * the common syscall code will automagically
1445 * convert this to success with a short count. 1487 * convert this to success with a short count.
1446 */ 1488 */
1447 mutex_exit(sc->lock); 1489 error = EWOULDBLOCK;
1448 return EWOULDBLOCK; 1490 goto out;
1449 } 1491 }
1450 if (pollout) { 1492 if (pollout) {
1451 mutex_exit(sc->lock); 1493 mutex_exit(sc->lock);
1452 yield(); /* see midi_poll_output */ 1494 yield(); /* see midi_poll_output */
1453 mutex_enter(sc->lock); 1495 mutex_enter(sc->lock);
1454 pollout = 0; 1496 pollout = 0;
1455 } else 1497 } else
1456 error = cv_wait_sig(&sc->wchan, sc->lock); 1498 error = cv_wait_sig(&sc->wchan, sc->lock);
 1499 if (sc->dying)
 1500 error = EIO;
1457 if (error) { 1501 if (error) {
1458 /* 1502 /*
1459 * Similarly, the common code will handle 1503 * Similarly, the common code will handle
1460 * EINTR and ERESTART properly here, changing to 1504 * EINTR and ERESTART properly here, changing to
1461 * a short count if something transferred. 1505 * a short count if something transferred.
1462 */ 1506 */
1463 mutex_exit(sc->lock); 1507 goto out;
1464 return error; 
1465 } 1508 }
1466 } 1509 }
1467 1510
1468 /* 1511 /*
1469 * The number of bytes we can safely extract from the uio 1512 * The number of bytes we can safely extract from the uio
1470 * depends on the available idx and buf space. Worst case, 1513 * depends on the available idx and buf space. Worst case,
1471 * every byte is a message so 1 idx is required per byte. 1514 * every byte is a message so 1 idx is required per byte.
1472 * Worst case, the first byte completes a 3-byte msg in prior 1515 * Worst case, the first byte completes a 3-byte msg in prior
1473 * state, and every subsequent byte is a Program Change or 1516 * state, and every subsequent byte is a Program Change or
1474 * Channel Pressure msg with running status and expands to 2 1517 * Channel Pressure msg with running status and expands to 2
1475 * bytes, so the buf space reqd is 3+2(n-1) or 2n+1. So limit 1518 * bytes, so the buf space reqd is 3+2(n-1) or 2n+1. So limit
1476 * the transfer to the min of idxspace and (bufspace-1)>>1. 1519 * the transfer to the min of idxspace and (bufspace-1)>>1.
1477 */ 1520 */
@@ -1482,192 +1525,220 @@ midiwrite(dev_t dev, struct uio *uio, in @@ -1482,192 +1525,220 @@ midiwrite(dev_t dev, struct uio *uio, in
1482 xfrcount = sizeof inp; 1525 xfrcount = sizeof inp;
1483 if (xfrcount > uio->uio_resid) 1526 if (xfrcount > uio->uio_resid)
1484 xfrcount = uio->uio_resid; 1527 xfrcount = uio->uio_resid;
1485 1528
1486 mutex_exit(sc->lock); 1529 mutex_exit(sc->lock);
1487 error = uiomove(inp, xfrcount, uio); 1530 error = uiomove(inp, xfrcount, uio);
1488 mutex_enter(sc->lock); 1531 mutex_enter(sc->lock);
1489#ifdef MIDI_DEBUG 1532#ifdef MIDI_DEBUG
1490 if (error) 1533 if (error)
1491 printf("midi_write:(1) uiomove failed %d; " 1534 printf("midi_write:(1) uiomove failed %d; "
1492 "xfrcount=%zu inp=%p\n", 1535 "xfrcount=%zu inp=%p\n",
1493 error, xfrcount, inp); 1536 error, xfrcount, inp);
1494#endif 1537#endif
1495 if ( error ) 1538 if (error)
1496 break; 1539 break;
1497  1540
1498 /* 1541 /*
1499 * The number of bytes we extracted being calculated to 1542 * The number of bytes we extracted being calculated to
1500 * definitely fit in the buffer even with canonicalization, 1543 * definitely fit in the buffer even with canonicalization,
1501 * there is no excuse for real_writebytes to return EWOULDBLOCK. 1544 * there is no excuse for real_writebytes to return EWOULDBLOCK.
1502 */ 1545 */
1503 error = real_writebytes(sc, inp, xfrcount); 1546 error = real_writebytes(sc, inp, xfrcount);
1504 KASSERT(error != EWOULDBLOCK); 1547 KASSERT(error != EWOULDBLOCK);
1505 if (error) 1548 if (error)
1506 break; 1549 break;
1507 1550
1508 /* 1551 /*
1509 * If this is a polling device and we just sent a buffer, let's 1552 * If this is a polling device and we just sent a buffer, let's
1510 * not send another without giving some other process a chance. 1553 * not send another without giving some other process a chance.
1511 */ 1554 */
1512 if ((sc->props & MIDI_PROP_OUT_INTR) == 0) 1555 if ((sc->props & MIDI_PROP_OUT_INTR) == 0)
1513 pollout = 1; 1556 pollout = 1;
1514 DPRINTFN(8,("midiwrite: uio_resid now %zu, props=%d\n", 1557 DPRINTFN(8,("midiwrite: uio_resid now %zu, props=%d\n",
1515 uio->uio_resid, sc->props)); 1558 uio->uio_resid, sc->props));
1516 } 1559 }
 1560
 1561out:
 1562 if (--sc->refcnt < 0)
 1563 cv_broadcast(&sc->detach_cv);
 1564
1517 mutex_exit(sc->lock); 1565 mutex_exit(sc->lock);
1518 return error; 1566 return error;
1519} 1567}
1520 1568
1521/* 1569/*
1522 * This write routine is only called from sequencer code and expects 1570 * This write routine is only called from sequencer code and expects
1523 * a write that is smaller than the MIDI buffer. 1571 * a write that is smaller than the MIDI buffer.
1524 */ 1572 */
1525int 1573int
1526midi_writebytes(int unit, u_char *bf, int cc) 1574midi_writebytes(int unit, u_char *bf, int cc)
1527{ 1575{
1528 struct midi_softc *sc = 1576 struct midi_softc *sc =
1529 device_lookup_private(&midi_cd, unit); 1577 device_lookup_private(&midi_cd, unit);
1530 int error; 1578 int error;
1531 1579
 1580 if (!sc)
 1581 return EIO;
 1582
1532 DPRINTFN(7, ("midi_writebytes: %p, unit=%d, cc=%d %#02x %#02x %#02x\n", 1583 DPRINTFN(7, ("midi_writebytes: %p, unit=%d, cc=%d %#02x %#02x %#02x\n",
1533 sc, unit, cc, bf[0], bf[1], bf[2])); 1584 sc, unit, cc, bf[0], bf[1], bf[2]));
1534 1585
1535 mutex_enter(sc->lock); 1586 mutex_enter(sc->lock);
1536 error = real_writebytes(sc, bf, cc); 1587 if (sc->dying)
 1588 error = EIO;
 1589 else
 1590 error = real_writebytes(sc, bf, cc);
1537 mutex_exit(sc->lock); 1591 mutex_exit(sc->lock);
1538 1592
1539 return error; 1593 return error;
1540} 1594}
1541 1595
1542static int 1596static int
1543midiioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 1597midiioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
1544{ 1598{
1545 struct midi_softc *sc; 1599 struct midi_softc *sc;
1546 const struct midi_hw_if *hw; 1600 const struct midi_hw_if *hw;
1547 int error; 1601 int error;
1548 MIDI_BUF_DECLARE(buf); 1602 MIDI_BUF_DECLARE(buf);
1549 1603
1550 (void)buf_end; 1604 (void)buf_end;
1551 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));; 1605 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));
1552 if (sc->dying) 1606
 1607 mutex_enter(sc->lock);
 1608 if (sc->dying) {
 1609 mutex_exit(sc->lock);
1553 return EIO; 1610 return EIO;
 1611 }
1554 hw = sc->hw_if; 1612 hw = sc->hw_if;
1555 error = 0; 1613 error = 0;
1556 1614
 1615 sc->refcnt++;
 1616
1557 DPRINTFN(5,("midiioctl: %p cmd=0x%08lx\n", sc, cmd)); 1617 DPRINTFN(5,("midiioctl: %p cmd=0x%08lx\n", sc, cmd));
1558 1618
1559 switch (cmd) { 1619 switch (cmd) {
1560 case FIONBIO: 1620 case FIONBIO:
1561 /* All handled in the upper layer. */ 1621 /* All handled in the upper layer. */
1562 break; 1622 break;
1563  1623
1564 case FIONREAD: 1624 case FIONREAD:
1565 /* 1625 /*
1566 * This code relies on the current implementation of midi_in 1626 * This code relies on the current implementation of midi_in
1567 * always updating buf and idx together in a critical section, 1627 * always updating buf and idx together in a critical section,
1568 * so buf always ends at a message boundary. Document this 1628 * so buf always ends at a message boundary. Document this
1569 * ioctl as always returning a value such that the last message 1629 * ioctl as always returning a value such that the last message
1570 * included is complete (SysEx the only exception), and then 1630 * included is complete (SysEx the only exception), and then
1571 * make sure the implementation doesn't regress. NB that 1631 * make sure the implementation doesn't regress. NB that
1572 * means if this ioctl returns n and the proc then issues a 1632 * means if this ioctl returns n and the proc then issues a
1573 * read of n, n bytes will be read, but if the proc issues a 1633 * read of n, n bytes will be read, but if the proc issues a
1574 * read of m < n, fewer than m bytes may be read to ensure the 1634 * read of m < n, fewer than m bytes may be read to ensure the
1575 * read ends at a message boundary. 1635 * read ends at a message boundary.
1576 */ 1636 */
1577 mutex_enter(sc->lock); 
1578 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf); 1637 MIDI_BUF_CONSUMER_INIT(&sc->inbuf,buf);
1579 *(int *)addr = buf_lim - buf_cur; 1638 *(int *)addr = buf_lim - buf_cur;
1580 mutex_exit(sc->lock); 
1581 break; 1639 break;
1582 1640
1583 case FIOASYNC: 1641 case FIOASYNC:
 1642 mutex_exit(sc->lock);
1584 mutex_enter(proc_lock); 1643 mutex_enter(proc_lock);
1585 if (*(int *)addr) { 1644 if (*(int *)addr) {
1586 if (sc->async) { 1645 if (sc->async) {
1587 error = EBUSY; 1646 error = EBUSY;
1588 } else { 1647 } else {
1589 sc->async = curproc->p_pid; 1648 sc->async = curproc->p_pid;
1590 } 1649 }
1591 DPRINTFN(5,("midi_ioctl: FIOASYNC %d\n", 1650 DPRINTFN(5,("midi_ioctl: FIOASYNC %d\n",
1592 curproc->p_pid)); 1651 curproc->p_pid));
1593 } else { 1652 } else {
1594 sc->async = 0; 1653 sc->async = 0;
1595 } 1654 }
1596 mutex_exit(proc_lock); 1655 mutex_exit(proc_lock);
 1656 mutex_enter(sc->lock);
1597 break; 1657 break;
1598 1658
1599#if 0 1659#if 0
1600 case MIDI_PRETIME: 1660 case MIDI_PRETIME:
1601 /* XXX OSS 1661 /* XXX OSS
1602 * This should set up a read timeout, but that's 1662 * This should set up a read timeout, but that's
1603 * why we have poll(), so there's nothing yet. */ 1663 * why we have poll(), so there's nothing yet. */
1604 error = EINVAL; 1664 error = EINVAL;
1605 break; 1665 break;
1606#endif 1666#endif
1607 1667
1608#ifdef MIDI_SAVE 1668#ifdef MIDI_SAVE
1609 case MIDI_GETSAVE: 1669 case MIDI_GETSAVE:
 1670 mutex_exit(sc->lock);
1610 error = copyout(&midisave, *(void **)addr, sizeof midisave); 1671 error = copyout(&midisave, *(void **)addr, sizeof midisave);
 1672 mutex_enter(sc->lock);
1611 break; 1673 break;
1612#endif 1674#endif
1613 1675
1614 default: 1676 default:
1615 if (hw->ioctl != NULL) { 1677 if (hw->ioctl != NULL) {
1616 mutex_enter(sc->lock); 
1617 error = hw->ioctl(sc->hw_hdl, cmd, addr, flag, l); 1678 error = hw->ioctl(sc->hw_hdl, cmd, addr, flag, l);
1618 mutex_exit(sc->lock); 
1619 } else { 1679 } else {
1620 error = EINVAL; 1680 error = EINVAL;
1621 } 1681 }
1622 break; 1682 break;
1623 } 1683 }
 1684
 1685 if (--sc->refcnt < 0)
 1686 cv_broadcast(&sc->detach_cv);
 1687 mutex_exit(sc->lock);
1624 return error; 1688 return error;
1625} 1689}
1626 1690
1627static int 1691static int
1628midipoll(dev_t dev, int events, struct lwp *l) 1692midipoll(dev_t dev, int events, struct lwp *l)
1629{ 1693{
1630 struct midi_softc *sc; 1694 struct midi_softc *sc;
1631 int revents; 1695 int revents;
1632 MIDI_BUF_DECLARE(idx); 1696 MIDI_BUF_DECLARE(idx);
1633 MIDI_BUF_DECLARE(buf); 1697 MIDI_BUF_DECLARE(buf);
1634 1698
1635 (void)buf_end; (void)idx_end; 1699 (void)buf_end; (void)idx_end;
1636 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev)); 1700 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));
1637 revents = 0; 1701 revents = 0;
1638 1702
1639 DPRINTFN(6,("midipoll: %p events=0x%x\n", sc, events)); 1703 DPRINTFN(6,("midipoll: %p events=0x%x\n", sc, events));
1640 1704
1641 mutex_enter(sc->lock); 1705 mutex_enter(sc->lock);
1642 if (sc->dying) { 1706 if (sc->dying) {
1643 mutex_exit(sc->lock); 1707 mutex_exit(sc->lock);
1644 return POLLHUP; 1708 return POLLHUP;
1645 } 1709 }
 1710
 1711 sc->refcnt++;
 1712
1646 if ((events & (POLLIN | POLLRDNORM)) != 0) { 1713 if ((events & (POLLIN | POLLRDNORM)) != 0) {
1647 MIDI_BUF_CONSUMER_INIT(&sc->inbuf, idx); 1714 MIDI_BUF_CONSUMER_INIT(&sc->inbuf, idx);
1648 if (idx_cur < idx_lim) 1715 if (idx_cur < idx_lim)
1649 revents |= events & (POLLIN | POLLRDNORM); 1716 revents |= events & (POLLIN | POLLRDNORM);
1650 else 1717 else
1651 selrecord(l, &sc->rsel); 1718 selrecord(l, &sc->rsel);
1652 } 1719 }
1653 if ((events & (POLLOUT | POLLWRNORM)) != 0) { 1720 if ((events & (POLLOUT | POLLWRNORM)) != 0) {
1654 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, idx); 1721 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, idx);
1655 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, buf); 1722 MIDI_BUF_PRODUCER_INIT(&sc->outbuf, buf);
1656 if (idx_lim - idx_cur >= 1 && buf_lim - buf_cur >= 3) 1723 if (idx_lim - idx_cur >= 1 && buf_lim - buf_cur >= 3)
1657 revents |= events & (POLLOUT | POLLWRNORM); 1724 revents |= events & (POLLOUT | POLLWRNORM);
1658 else 1725 else
1659 selrecord(l, &sc->wsel); 1726 selrecord(l, &sc->wsel);
1660 } 1727 }
 1728
 1729 if (--sc->refcnt < 0)
 1730 cv_broadcast(&sc->detach_cv);
 1731
1661 mutex_exit(sc->lock); 1732 mutex_exit(sc->lock);
1662 1733
1663 return revents; 1734 return revents;
1664} 1735}
1665 1736
1666static void 1737static void
1667filt_midirdetach(struct knote *kn) 1738filt_midirdetach(struct knote *kn)
1668{ 1739{
1669 struct midi_softc *sc = kn->kn_hook; 1740 struct midi_softc *sc = kn->kn_hook;
1670 1741
1671 mutex_enter(sc->lock); 1742 mutex_enter(sc->lock);
1672 SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext); 1743 SLIST_REMOVE(&sc->rsel.sel_klist, kn, knote, kn_selnext);
1673 mutex_exit(sc->lock); 1744 mutex_exit(sc->lock);
@@ -1699,68 +1770,85 @@ filt_midiwdetach(struct knote *kn) @@ -1699,68 +1770,85 @@ filt_midiwdetach(struct knote *kn)
1699 1770
1700 mutex_enter(sc->lock); 1771 mutex_enter(sc->lock);
1701 SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext); 1772 SLIST_REMOVE(&sc->wsel.sel_klist, kn, knote, kn_selnext);
1702 mutex_exit(sc->lock); 1773 mutex_exit(sc->lock);
1703} 1774}
1704 1775
1705static int 1776static int
1706filt_midiwrite(struct knote *kn, long hint) 1777filt_midiwrite(struct knote *kn, long hint)
1707{ 1778{
1708 struct midi_softc *sc = kn->kn_hook; 1779 struct midi_softc *sc = kn->kn_hook;
1709 MIDI_BUF_DECLARE(idx); 1780 MIDI_BUF_DECLARE(idx);
1710 MIDI_BUF_DECLARE(buf); 1781 MIDI_BUF_DECLARE(buf);
1711 1782
 1783 mutex_exit(sc->lock);
 1784 sc->refcnt++;
 1785 mutex_enter(sc->lock);
 1786
1712 (void)idx_end; (void)buf_end; 1787 (void)idx_end; (void)buf_end;
1713 if (hint != NOTE_SUBMIT) 1788 if (hint != NOTE_SUBMIT)
1714 mutex_enter(sc->lock); 1789 mutex_enter(sc->lock);
1715 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,idx); 1790 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,idx);
1716 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,buf); 1791 MIDI_BUF_PRODUCER_INIT(&sc->outbuf,buf);
1717 kn->kn_data = ((buf_lim - buf_cur)-1)>>1; 1792 kn->kn_data = ((buf_lim - buf_cur)-1)>>1;
1718 if (kn->kn_data > idx_lim - idx_cur) 1793 if (kn->kn_data > idx_lim - idx_cur)
1719 kn->kn_data = idx_lim - idx_cur; 1794 kn->kn_data = idx_lim - idx_cur;
1720 if (hint != NOTE_SUBMIT) 1795 if (hint != NOTE_SUBMIT)
1721 mutex_exit(sc->lock); 1796 mutex_exit(sc->lock);
 1797
 1798 // XXXMRG -- move this up, avoid the relock?
 1799 mutex_enter(sc->lock);
 1800 if (--sc->refcnt < 0)
 1801 cv_broadcast(&sc->detach_cv);
 1802 mutex_exit(sc->lock);
 1803
1722 return (kn->kn_data > 0); 1804 return (kn->kn_data > 0);
1723} 1805}
1724 1806
1725static const struct filterops midiwrite_filtops = 1807static const struct filterops midiwrite_filtops =
1726 { 1, NULL, filt_midiwdetach, filt_midiwrite }; 1808 { 1, NULL, filt_midiwdetach, filt_midiwrite };
1727 1809
1728int 1810int
1729midikqfilter(dev_t dev, struct knote *kn) 1811midikqfilter(dev_t dev, struct knote *kn)
1730{ 1812{
1731 struct midi_softc *sc = 1813 struct midi_softc *sc =
1732 device_lookup_private(&midi_cd, MIDIUNIT(dev)); 1814 device_lookup_private(&midi_cd, MIDIUNIT(dev));
1733 struct klist *klist; 1815 struct klist *klist;
1734 1816
 1817 mutex_exit(sc->lock);
 1818 sc->refcnt++;
 1819 mutex_enter(sc->lock);
 1820
1735 switch (kn->kn_filter) { 1821 switch (kn->kn_filter) {
1736 case EVFILT_READ: 1822 case EVFILT_READ:
1737 klist = &sc->rsel.sel_klist; 1823 klist = &sc->rsel.sel_klist;
1738 kn->kn_fop = &midiread_filtops; 1824 kn->kn_fop = &midiread_filtops;
1739 break; 1825 break;
1740 1826
1741 case EVFILT_WRITE: 1827 case EVFILT_WRITE:
1742 klist = &sc->wsel.sel_klist; 1828 klist = &sc->wsel.sel_klist;
1743 kn->kn_fop = &midiwrite_filtops; 1829 kn->kn_fop = &midiwrite_filtops;
1744 break; 1830 break;
1745 1831
1746 default: 1832 default:
1747 return (EINVAL); 1833 return (EINVAL);
1748 } 1834 }
1749 1835
1750 kn->kn_hook = sc; 1836 kn->kn_hook = sc;
1751 1837
1752 mutex_enter(sc->lock); 1838 mutex_enter(sc->lock);
1753 SLIST_INSERT_HEAD(klist, kn, kn_selnext); 1839 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 1840 if (--sc->refcnt < 0)
 1841 cv_broadcast(&sc->detach_cv);
1754 mutex_exit(sc->lock); 1842 mutex_exit(sc->lock);
1755 1843
1756 return (0); 1844 return (0);
1757} 1845}
1758 1846
1759void 1847void
1760midi_getinfo(dev_t dev, struct midi_info *mi) 1848midi_getinfo(dev_t dev, struct midi_info *mi)
1761{ 1849{
1762 struct midi_softc *sc; 1850 struct midi_softc *sc;
1763 1851
1764 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev)); 1852 sc = device_lookup_private(&midi_cd, MIDIUNIT(dev));
1765 if (sc == NULL) 1853 if (sc == NULL)
1766 return; 1854 return;

cvs diff -r1.25 -r1.25.14.1 src/sys/dev/midi_if.h (expand / switch to unified diff)

--- src/sys/dev/midi_if.h 2012/04/09 10:18:16 1.25
+++ src/sys/dev/midi_if.h 2015/01/11 14:13:25 1.25.14.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: midi_if.h,v 1.25 2012/04/09 10:18:16 plunky Exp $ */ 1/* $NetBSD: midi_if.h,v 1.25.14.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org). 8 * by Lennart Augustsson (augustss@NetBSD.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -40,31 +40,31 @@ struct midi_info { @@ -40,31 +40,31 @@ struct midi_info {
40}; 40};
41#define MIDI_PROP_OUT_INTR 1 41#define MIDI_PROP_OUT_INTR 1
42#define MIDI_PROP_CAN_INPUT 2 42#define MIDI_PROP_CAN_INPUT 2
43#define MIDI_PROP_NO_OUTPUT 4 43#define MIDI_PROP_NO_OUTPUT 4
44 44
45/* 45/*
46 * XXX expand 46 * XXX expand
47 * 47 *
48 * List of hardware interface methods, and when locks are held by each 48 * List of hardware interface methods, and when locks are held by each
49 * called by this module: 49 * called by this module:
50 * 50 *
51 * METHOD INTR NOTES 51 * METHOD INTR NOTES
52 * ----------------------- ------- ------------------------- 52 * ----------------------- ------- -------------------------
53 * open -  53 * open held
54 * close -  54 * close held
55 * output -  55 * output held
56 * getinfo - Called at attach time 56 * getinfo held Called at attach time
57 * ioctl -  57 * ioctl held
58 * get_locks - Called at attach time 58 * get_locks - Called at attach time
59 */ 59 */
60 60
61struct midi_softc; 61struct midi_softc;
62 62
63struct midi_hw_if { 63struct midi_hw_if {
64 int (*open)(void *, int, /* open hardware */ 64 int (*open)(void *, int, /* open hardware */
65 void (*)(void *, int), /* input callback */ 65 void (*)(void *, int), /* input callback */
66 void (*)(void *), /* output callback */ 66 void (*)(void *), /* output callback */
67 void *); 67 void *);
68 void (*close)(void *); /* close hardware */ 68 void (*close)(void *); /* close hardware */
69 int (*output)(void *, int); /* output a byte */ 69 int (*output)(void *, int); /* output a byte */
70 void (*getinfo)(void *, struct midi_info *); 70 void (*getinfo)(void *, struct midi_info *);

cvs diff -r1.19 -r1.19.14.1 src/sys/dev/midivar.h (expand / switch to unified diff)

--- src/sys/dev/midivar.h 2012/04/05 20:25:53 1.19
+++ src/sys/dev/midivar.h 2015/01/11 14:13:25 1.19.14.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: midivar.h,v 1.19 2012/04/05 20:25:53 plunky Exp $ */ 1/* $NetBSD: midivar.h,v 1.19.14.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org) and (midi FST refactoring and 8 * by Lennart Augustsson (augustss@NetBSD.org) and (midi FST refactoring and
9 * Active Sense) Chapman Flack (chap@NetBSD.org). 9 * Active Sense) Chapman Flack (chap@NetBSD.org).
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -179,26 +179,28 @@ struct midi_state { @@ -179,26 +179,28 @@ struct midi_state {
179}; 179};
180 180
181struct midi_softc { 181struct midi_softc {
182 device_t dev; /* Hardware device struct */ 182 device_t dev; /* Hardware device struct */
183 void *hw_hdl; /* Hardware driver handle */ 183 void *hw_hdl; /* Hardware driver handle */
184 const struct midi_hw_if *hw_if; /* Hardware interface */ 184 const struct midi_hw_if *hw_if; /* Hardware interface */
185 const struct midi_hw_if_ext *hw_if_ext; /* see midi_if.h */ 185 const struct midi_hw_if_ext *hw_if_ext; /* see midi_if.h */
186 int isopen; /* Open indicator */ 186 int isopen; /* Open indicator */
187 int flags; /* Open flags */ 187 int flags; /* Open flags */
188 int dying; 188 int dying;
189 struct midi_buffer outbuf; 189 struct midi_buffer outbuf;
190 struct midi_buffer inbuf; 190 struct midi_buffer inbuf;
191 int props; 191 int props;
 192 int refcnt;
 193 kcondvar_t detach_cv;
192 kcondvar_t rchan; 194 kcondvar_t rchan;
193 kcondvar_t wchan; 195 kcondvar_t wchan;
194 kmutex_t *lock; 196 kmutex_t *lock;
195 int pbus; 197 int pbus;
196 int rcv_expect_asense; 198 int rcv_expect_asense;
197 int rcv_quiescent; 199 int rcv_quiescent;
198 int rcv_eof; 200 int rcv_eof;
199 struct selinfo wsel; /* write selector */ 201 struct selinfo wsel; /* write selector */
200 struct selinfo rsel; /* read selector */ 202 struct selinfo rsel; /* read selector */
201 pid_t async; /* process who wants audio SIGIO */ 203 pid_t async; /* process who wants audio SIGIO */
202 void *sih; 204 void *sih;
203 205
204 struct callout xmt_asense_co; 206 struct callout xmt_asense_co;

cvs diff -r1.59 -r1.59.2.1 src/sys/dev/sequencer.c (expand / switch to unified diff)

--- src/sys/dev/sequencer.c 2014/07/25 08:10:35 1.59
+++ src/sys/dev/sequencer.c 2015/01/11 14:13:25 1.59.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sequencer.c,v 1.59 2014/07/25 08:10:35 dholland Exp $ */ 1/* $NetBSD: sequencer.c,v 1.59.2.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org) and by Andrew Doran. 8 * by Lennart Augustsson (augustss@NetBSD.org) and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -45,27 +45,27 @@ @@ -45,27 +45,27 @@
45 * o MIDI softc locks. These can be spinlocks and there can be many of 45 * o MIDI softc locks. These can be spinlocks and there can be many of
46 * them, because we can open many MIDI devices. We take these only in two 46 * them, because we can open many MIDI devices. We take these only in two
47 * places: when enabling redirection from the MIDI device and when 47 * places: when enabling redirection from the MIDI device and when
48 * disabling it (open/close). midiseq_in() is called by the MIDI driver 48 * disabling it (open/close). midiseq_in() is called by the MIDI driver
49 * with its own lock held when passing data into this module. To avoid 49 * with its own lock held when passing data into this module. To avoid
50 * lock order and context problems, we package the received message as a 50 * lock order and context problems, we package the received message as a
51 * sequencer_pcqitem_t and put onto a producer-consumer queue. A soft 51 * sequencer_pcqitem_t and put onto a producer-consumer queue. A soft
52 * interrupt is scheduled to dequeue and decode the message later where we 52 * interrupt is scheduled to dequeue and decode the message later where we
53 * can safely acquire the sequencer device's sc_lock. PCQ is lockless for 53 * can safely acquire the sequencer device's sc_lock. PCQ is lockless for
54 * multiple producer, single consumer settings like this one. 54 * multiple producer, single consumer settings like this one.
55 */ 55 */
56 56
57#include <sys/cdefs.h> 57#include <sys/cdefs.h>
58__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.59 2014/07/25 08:10:35 dholland Exp $"); 58__KERNEL_RCSID(0, "$NetBSD: sequencer.c,v 1.59.2.1 2015/01/11 14:13:25 martin Exp $");
59 59
60#include "sequencer.h" 60#include "sequencer.h"
61 61
62#include <sys/param.h> 62#include <sys/param.h>
63#include <sys/ioctl.h> 63#include <sys/ioctl.h>
64#include <sys/fcntl.h> 64#include <sys/fcntl.h>
65#include <sys/vnode.h> 65#include <sys/vnode.h>
66#include <sys/select.h> 66#include <sys/select.h>
67#include <sys/poll.h> 67#include <sys/poll.h>
68#include <sys/kmem.h> 68#include <sys/kmem.h>
69#include <sys/proc.h> 69#include <sys/proc.h>
70#include <sys/systm.h> 70#include <sys/systm.h>
71#include <sys/syslog.h> 71#include <sys/syslog.h>
@@ -164,91 +164,96 @@ const struct cdevsw sequencer_cdevsw = { @@ -164,91 +164,96 @@ const struct cdevsw sequencer_cdevsw = {
164 .d_ioctl = sequencerioctl, 164 .d_ioctl = sequencerioctl,
165 .d_stop = nostop, 165 .d_stop = nostop,
166 .d_tty = notty, 166 .d_tty = notty,
167 .d_poll = sequencerpoll, 167 .d_poll = sequencerpoll,
168 .d_mmap = nommap, 168 .d_mmap = nommap,
169 .d_kqfilter = sequencerkqfilter, 169 .d_kqfilter = sequencerkqfilter,
170 .d_discard = nodiscard, 170 .d_discard = nodiscard,
171 .d_flag = D_OTHER | D_MPSAFE 171 .d_flag = D_OTHER | D_MPSAFE
172}; 172};
173static LIST_HEAD(, sequencer_softc) sequencers = LIST_HEAD_INITIALIZER(sequencers); 173static LIST_HEAD(, sequencer_softc) sequencers = LIST_HEAD_INITIALIZER(sequencers);
174static kmutex_t sequencer_lock; 174static kmutex_t sequencer_lock;
175 175
176static void 176static void
177sequencerdestroy(struct sequencer_softc *sc) { 177sequencerdestroy(struct sequencer_softc *sc)
 178{
 179 callout_halt(&sc->sc_callout, &sc->lock);
178 callout_destroy(&sc->sc_callout); 180 callout_destroy(&sc->sc_callout);
179 softint_disestablish(sc->sih); 181 softint_disestablish(sc->sih);
180 cv_destroy(&sc->rchan); 182 cv_destroy(&sc->rchan);
181 cv_destroy(&sc->wchan); 183 cv_destroy(&sc->wchan);
182 cv_destroy(&sc->lchan); 184 cv_destroy(&sc->lchan);
183 if (sc->pcq) 185 if (sc->pcq)
184 pcq_destroy(sc->pcq); 186 pcq_destroy(sc->pcq);
185 kmem_free(sc, sizeof(*sc)); 187 kmem_free(sc, sizeof(*sc));
186} 188}
187 189
188static struct sequencer_softc * 190static struct sequencer_softc *
189sequencercreate(int unit) { 191sequencercreate(int unit)
 192{
190 struct sequencer_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 193 struct sequencer_softc *sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
191 if (sc == NULL) { 194 if (sc == NULL) {
192#ifdef DIAGNOSTIC 195#ifdef DIAGNOSTIC
193 printf("%s: out of memory\n", __func__); 196 printf("%s: out of memory\n", __func__);
194#endif 197#endif
195 return NULL; 198 return NULL;
196 } 199 }
197 sc->sc_unit = unit; 200 sc->sc_unit = unit;
198 callout_init(&sc->sc_callout, CALLOUT_MPSAFE); 201 callout_init(&sc->sc_callout, CALLOUT_MPSAFE);
199 sc->sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, 202 sc->sih = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE,
200 seq_softintr, sc); 203 seq_softintr, sc);
201 mutex_init(&sc->lock, MUTEX_DEFAULT, IPL_NONE); 204 mutex_init(&sc->lock, MUTEX_DEFAULT, IPL_NONE);
202 cv_init(&sc->rchan, "midiseqr"); 205 cv_init(&sc->rchan, "midiseqr");
203 cv_init(&sc->wchan, "midiseqw"); 206 cv_init(&sc->wchan, "midiseqw");
204 cv_init(&sc->lchan, "midiseql"); 207 cv_init(&sc->lchan, "midiseql");
205 sc->pcq = pcq_create(SEQ_MAXQ, KM_SLEEP); 208 sc->pcq = pcq_create(SEQ_MAXQ, KM_SLEEP);
206 if (sc->pcq == NULL) { 209 if (sc->pcq == NULL) {
207 sequencerdestroy(sc); 210 sequencerdestroy(sc);
208 return NULL; 211 return NULL;
209 } 212 }
210 return sc; 213 return sc;
211} 214}
212 215
213 216
214static struct sequencer_softc * 217static struct sequencer_softc *
215sequencerget(int unit) { 218sequencerget(int unit)
 219{
216 struct sequencer_softc *sc; 220 struct sequencer_softc *sc;
217 if (unit < 0) { 221 if (unit < 0) {
218#ifdef DIAGNOSTIC 222#ifdef DIAGNOSTIC
219 panic("%s: unit %d!", __func__, unit); 223 panic("%s: unit %d!", __func__, unit);
220#endif 224#endif
221 return NULL; 225 return NULL;
222 } 226 }
223 mutex_enter(&sequencer_lock); 227 mutex_enter(&sequencer_lock);
224 LIST_FOREACH(sc, &sequencers, sc_link) { 228 LIST_FOREACH(sc, &sequencers, sc_link) {
225 if (sc->sc_unit == unit) { 229 if (sc->sc_unit == unit) {
226 mutex_exit(&sequencer_lock); 230 mutex_exit(&sequencer_lock);
227 return sc; 231 return sc;
228 } 232 }
229 } 233 }
230 mutex_exit(&sequencer_lock); 234 mutex_exit(&sequencer_lock);
231 if ((sc = sequencercreate(unit)) == NULL) 235 if ((sc = sequencercreate(unit)) == NULL)
232 return NULL; 236 return NULL;
233 mutex_enter(&sequencer_lock); 237 mutex_enter(&sequencer_lock);
234 LIST_INSERT_HEAD(&sequencers, sc, sc_link); 238 LIST_INSERT_HEAD(&sequencers, sc, sc_link);
235 mutex_exit(&sequencer_lock); 239 mutex_exit(&sequencer_lock);
236 return sc; 240 return sc;
237} 241}
238 242
239#ifdef notyet 243#ifdef notyet
240static void  244static void
241sequencerput(struct sequencer_softc *sc) { 245sequencerput(struct sequencer_softc *sc)
 246{
242 mutex_enter(&sequencer_lock); 247 mutex_enter(&sequencer_lock);
243 LIST_REMOVE(sc, sc_link); 248 LIST_REMOVE(sc, sc_link);
244 mutex_exit(&sequencer_lock); 249 mutex_exit(&sequencer_lock);
245 sequencerdestroy(sc); 250 sequencerdestroy(sc);
246} 251}
247#endif 252#endif
248 253
249void 254void
250sequencerattach(int n) 255sequencerattach(int n)
251{ 256{
252 mutex_init(&sequencer_lock, MUTEX_DEFAULT, IPL_NONE); 257 mutex_init(&sequencer_lock, MUTEX_DEFAULT, IPL_NONE);
253} 258}
254 259
@@ -284,27 +289,27 @@ sequencer_enter(dev_t dev, struct sequen @@ -284,27 +289,27 @@ sequencer_enter(dev_t dev, struct sequen
284 sequencer_exit(sc); 289 sequencer_exit(sc);
285 return EIO; 290 return EIO;
286 } 291 }
287 *scp = sc; 292 *scp = sc;
288 return 0; 293 return 0;
289} 294}
290 295
291static int 296static int
292sequenceropen(dev_t dev, int flags, int ifmt, struct lwp *l) 297sequenceropen(dev_t dev, int flags, int ifmt, struct lwp *l)
293{ 298{
294 struct sequencer_softc *sc; 299 struct sequencer_softc *sc;
295 struct midi_dev *md; 300 struct midi_dev *md;
296 struct midi_softc *msc; 301 struct midi_softc *msc;
297 int error, unit; 302 int error, unit, mdno;
298 303
299 DPRINTF(("sequenceropen\n")); 304 DPRINTF(("sequenceropen\n"));
300 305
301 if ((error = sequencer_enter(dev, &sc)) != 0) 306 if ((error = sequencer_enter(dev, &sc)) != 0)
302 return error; 307 return error;
303 if (sc->isopen != 0) { 308 if (sc->isopen != 0) {
304 sequencer_exit(sc); 309 sequencer_exit(sc);
305 return EBUSY; 310 return EBUSY;
306 } 311 }
307 312
308 if (SEQ_IS_OLD(SEQUENCERUNIT(dev))) 313 if (SEQ_IS_OLD(SEQUENCERUNIT(dev)))
309 sc->mode = SEQ_OLD; 314 sc->mode = SEQ_OLD;
310 else 315 else
@@ -327,39 +332,48 @@ sequenceropen(dev_t dev, int flags, int  @@ -327,39 +332,48 @@ sequenceropen(dev_t dev, int flags, int
327 SEQ_QINIT(&sc->outq); 332 SEQ_QINIT(&sc->outq);
328 sc->lowat = SEQ_MAXQ / 2; 333 sc->lowat = SEQ_MAXQ / 2;
329 334
330 if (sc->ndevs > 0) { 335 if (sc->ndevs > 0) {
331 mutex_exit(&sc->lock); 336 mutex_exit(&sc->lock);
332 sc->devs = kmem_alloc(sc->ndevs * sizeof(struct midi_dev *), 337 sc->devs = kmem_alloc(sc->ndevs * sizeof(struct midi_dev *),
333 KM_SLEEP); 338 KM_SLEEP);
334 for (unit = 0; unit < sc->ndevs; unit++) { 339 for (unit = 0; unit < sc->ndevs; unit++) {
335 md = midiseq_open(unit, flags); 340 md = midiseq_open(unit, flags);
336 if (md) { 341 if (md) {
337 sc->devs[sc->nmidi++] = md; 342 sc->devs[sc->nmidi++] = md;
338 md->seq = sc; 343 md->seq = sc;
339 md->doingsysex = 0; 344 md->doingsysex = 0;
 345 DPRINTF(("%s: midi unit %d opened as seq %p\n",
 346 __func__, unit, md));
 347 } else {
 348 DPRINTF(("%s: midi unit %d not opened as seq\n",
 349 __func__, unit));
340 } 350 }
341 } 351 }
342 mutex_enter(&sc->lock); 352 mutex_enter(&sc->lock);
343 } else { 353 } else {
344 sc->devs = NULL; 354 sc->devs = NULL;
345 } 355 }
346 356
347 /* Only now redirect input from MIDI devices. */ 357 /* Only now redirect input from MIDI devices. */
348 for (unit = 0; unit < sc->nmidi; unit++) { 358 for (mdno = 0; mdno < sc->nmidi; mdno++) {
349 msc = sc->devs[unit]->msc; 359 extern struct cfdriver midi_cd;
350 mutex_enter(msc->lock); 360
351 msc->seqopen = 1; 361 msc = device_lookup_private(&midi_cd, sc->devs[mdno]->unit);
352 mutex_exit(msc->lock); 362 if (msc) {
 363 mutex_enter(msc->lock);
 364 msc->seqopen = 1;
 365 mutex_exit(msc->lock);
 366 }
353 } 367 }
354 368
355 seq_reset(sc); 369 seq_reset(sc);
356 sequencer_exit(sc); 370 sequencer_exit(sc);
357 371
358 DPRINTF(("%s: mode=%d, nmidi=%d\n", __func__, sc->mode, sc->nmidi)); 372 DPRINTF(("%s: mode=%d, nmidi=%d\n", __func__, sc->mode, sc->nmidi));
359 return 0; 373 return 0;
360} 374}
361 375
362static int 376static int
363seq_drain(struct sequencer_softc *sc) 377seq_drain(struct sequencer_softc *sc)
364{ 378{
365 int error; 379 int error;
@@ -419,58 +433,62 @@ seq_startoutput(struct sequencer_softc * @@ -419,58 +433,62 @@ seq_startoutput(struct sequencer_softc *
419 while (!SEQ_QEMPTY(q) && !sc->timeout) { 433 while (!SEQ_QEMPTY(q) && !sc->timeout) {
420 SEQ_QGET(q, cmd); 434 SEQ_QGET(q, cmd);
421 seq_do_command(sc, &cmd); 435 seq_do_command(sc, &cmd);
422 } 436 }
423} 437}
424 438
425static int 439static int
426sequencerclose(dev_t dev, int flags, int ifmt, struct lwp *l) 440sequencerclose(dev_t dev, int flags, int ifmt, struct lwp *l)
427{ 441{
428 struct sequencer_softc *sc; 442 struct sequencer_softc *sc;
429 struct midi_softc *msc; 443 struct midi_softc *msc;
430 int unit, error; 444 int unit, error;
431 445
432 DPRINTF(("sequencerclose: %"PRIx64"\n", dev)); 446 DPRINTF(("%s: %"PRIx64"\n", __func__, dev));
433 447
434 if ((error = sequencer_enter(dev, &sc)) != 0) 448 if ((error = sequencer_enter(dev, &sc)) != 0)
435 return error; 449 return error;
436 seq_drain(sc); 450 seq_drain(sc);
437 if (sc->timeout) { 451 if (sc->timeout) {
438 callout_halt(&sc->sc_callout, &sc->lock); 452 callout_halt(&sc->sc_callout, &sc->lock);
439 sc->timeout = 0; 453 sc->timeout = 0;
440 } 454 }
441 /* Bin input from MIDI devices. */ 455 /* Bin input from MIDI devices. */
442 for (unit = 0; unit < sc->nmidi; unit++) { 456 for (unit = 0; unit < sc->nmidi; unit++) {
443 msc = sc->devs[unit]->msc; 457 extern struct cfdriver midi_cd;
444 mutex_enter(msc->lock); 458
445 msc->seqopen = 0; 459 msc = device_lookup_private(&midi_cd, unit);
446 mutex_exit(msc->lock); 460 if (msc) {
 461 mutex_enter(msc->lock);
 462 msc->seqopen = 0;
 463 mutex_exit(msc->lock);
 464 }
447 } 465 }
448 mutex_exit(&sc->lock); 466 mutex_exit(&sc->lock);
449 467
450 for (unit = 0; unit < sc->nmidi; unit++) 468 for (unit = 0; unit < sc->nmidi; unit++)
451 if (sc->devs[unit] != NULL) 469 if (sc->devs[unit] != NULL)
452 midiseq_close(sc->devs[unit]); 470 midiseq_close(sc->devs[unit]);
453 if (sc->devs != NULL) { 471 if (sc->devs != NULL) {
454 KASSERT(sc->ndevs > 0); 472 KASSERT(sc->ndevs > 0);
455 kmem_free(sc->devs, sc->ndevs * sizeof(struct midi_dev *)); 473 kmem_free(sc->devs, sc->ndevs * sizeof(struct midi_dev *));
456 sc->devs = NULL; 474 sc->devs = NULL;
457 } 475 }
458 476
459 mutex_enter(&sc->lock); 477 mutex_enter(&sc->lock);
460 sc->isopen = 0; 478 sc->isopen = 0;
461 sequencer_exit(sc); 479 sequencer_exit(sc);
462 480
463 DPRINTF(("sequencerclose: %"PRIx64" done\n", dev)); 481 DPRINTF(("%s: %"PRIx64" done\n", __func__, dev));
464 482
465 return (0); 483 return (0);
466} 484}
467 485
468static int 486static int
469seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd) 487seq_input_event(struct sequencer_softc *sc, seq_event_t *cmd)
470{ 488{
471 struct sequencer_queue *q; 489 struct sequencer_queue *q;
472 490
473 KASSERT(mutex_owned(&sc->lock)); 491 KASSERT(mutex_owned(&sc->lock));
474 492
475 DPRINTFN(2, ("seq_input_event: %02x %02x %02x %02x %02x " 493 DPRINTFN(2, ("seq_input_event: %02x %02x %02x %02x %02x "
476 "%02x %02x %02x\n", cmd->tag, 494 "%02x %02x %02x\n", cmd->tag,
@@ -550,41 +568,41 @@ seq_softintr(void *addr) @@ -550,41 +568,41 @@ seq_softintr(void *addr)
550 default: /* this is now the point where MIDI_ACKs disappear */ 568 default: /* this is now the point where MIDI_ACKs disappear */
551 mutex_exit(&sc->lock); 569 mutex_exit(&sc->lock);
552 return; 570 return;
553 } 571 }
554 microtime(&now); 572 microtime(&now);
555 if (!sc->timer.running) 573 if (!sc->timer.running)
556 now = sc->timer.stoptime; 574 now = sc->timer.stoptime;
557 SUBTIMEVAL(&now, &sc->timer.reftime); 575 SUBTIMEVAL(&now, &sc->timer.reftime);
558 t = now.tv_sec * 1000000 + now.tv_usec; 576 t = now.tv_sec * 1000000 + now.tv_usec;
559 t /= sc->timer.usperdiv; 577 t /= sc->timer.usperdiv;
560 t += sc->timer.divs_lastchange; 578 t += sc->timer.divs_lastchange;
561 if (t != sc->input_stamp) { 579 if (t != sc->input_stamp) {
562 seq_input_event(sc, &SEQ_MK_TIMING(WAIT_ABS, .divisions=t)); 580 seq_input_event(sc, &SEQ_MK_TIMING(WAIT_ABS, .divisions=t));
563 sc->input_stamp = t; /* XXX wha hoppen if timer is reset? */ 581 sc->input_stamp = t; /* XXX what happens if timer is reset? */
564 } 582 }
565 seq_input_event(sc, &ev); 583 seq_input_event(sc, &ev);
566 mutex_exit(&sc->lock); 584 mutex_exit(&sc->lock);
567} 585}
568 586
569static int 587static int
570sequencerread(dev_t dev, struct uio *uio, int ioflag) 588sequencerread(dev_t dev, struct uio *uio, int ioflag)
571{ 589{
572 struct sequencer_softc *sc; 590 struct sequencer_softc *sc;
573 struct sequencer_queue *q; 591 struct sequencer_queue *q;
574 seq_event_t ev; 592 seq_event_t ev;
575 int error; 593 int error;
576 594
577 DPRINTFN(20, ("sequencerread: %"PRIx64", count=%d, ioflag=%x\n", 595 DPRINTFN(2, ("sequencerread: %"PRIx64", count=%d, ioflag=%x\n",
578 dev, (int)uio->uio_resid, ioflag)); 596 dev, (int)uio->uio_resid, ioflag));
579 597
580 if ((error = sequencer_enter(dev, &sc)) != 0) 598 if ((error = sequencer_enter(dev, &sc)) != 0)
581 return error; 599 return error;
582 q = &sc->inq; 600 q = &sc->inq;
583 601
584 if (sc->mode == SEQ_OLD) { 602 if (sc->mode == SEQ_OLD) {
585 sequencer_exit(sc); 603 sequencer_exit(sc);
586 DPRINTFN(-1,("sequencerread: old read\n")); 604 DPRINTFN(-1,("sequencerread: old read\n"));
587 return EINVAL; /* XXX unimplemented */ 605 return EINVAL; /* XXX unimplemented */
588 } 606 }
589 while (SEQ_QEMPTY(q)) { 607 while (SEQ_QEMPTY(q)) {
590 if (ioflag & IO_NDELAY) { 608 if (ioflag & IO_NDELAY) {
@@ -691,27 +709,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo @@ -691,27 +709,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo
691 709
692 if ((error = sequencer_enter(dev, &sc)) != 0) 710 if ((error = sequencer_enter(dev, &sc)) != 0)
693 return error; 711 return error;
694 switch (cmd) { 712 switch (cmd) {
695 case FIONBIO: 713 case FIONBIO:
696 /* All handled in the upper FS layer. */ 714 /* All handled in the upper FS layer. */
697 break; 715 break;
698 716
699 case FIOASYNC: 717 case FIOASYNC:
700 if (*(int *)addr) { 718 if (*(int *)addr) {
701 if (sc->async != 0) 719 if (sc->async != 0)
702 return EBUSY; 720 return EBUSY;
703 sc->async = curproc->p_pid; 721 sc->async = curproc->p_pid;
704 DPRINTF(("sequencer_ioctl: FIOASYNC %d\n", 722 DPRINTF(("%s: FIOASYNC %d\n", __func__,
705 sc->async)); 723 sc->async));
706 } else { 724 } else {
707 sc->async = 0; 725 sc->async = 0;
708 } 726 }
709 break; 727 break;
710 728
711 case SEQUENCER_RESET: 729 case SEQUENCER_RESET:
712 seq_reset(sc); 730 seq_reset(sc);
713 break; 731 break;
714 732
715 case SEQUENCER_PANIC: 733 case SEQUENCER_PANIC:
716 seq_reset(sc); 734 seq_reset(sc);
717 /* Do more? OSS doesn't */ 735 /* Do more? OSS doesn't */
@@ -777,26 +795,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo @@ -777,26 +795,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo
777 break; 795 break;
778 796
779 case SEQUENCER_TMR_STOP: 797 case SEQUENCER_TMR_STOP:
780 error = seq_do_timing(sc, &SEQ_MK_TIMING(STOP)); 798 error = seq_do_timing(sc, &SEQ_MK_TIMING(STOP));
781 break; 799 break;
782 800
783 case SEQUENCER_TMR_CONTINUE: 801 case SEQUENCER_TMR_CONTINUE:
784 error = seq_do_timing(sc, &SEQ_MK_TIMING(CONTINUE)); 802 error = seq_do_timing(sc, &SEQ_MK_TIMING(CONTINUE));
785 break; 803 break;
786 804
787 case SEQUENCER_TMR_TEMPO: 805 case SEQUENCER_TMR_TEMPO:
788 error = seq_do_timing(sc, 806 error = seq_do_timing(sc,
789 &SEQ_MK_TIMING(TEMPO, .bpm=*(int *)addr)); 807 &SEQ_MK_TIMING(TEMPO, .bpm=*(int *)addr));
 808 RECALC_USPERDIV(&sc->timer);
790 if (error == 0) 809 if (error == 0)
791 *(int *)addr = sc->timer.tempo_beatpermin; 810 *(int *)addr = sc->timer.tempo_beatpermin;
792 break; 811 break;
793 812
794 case SEQUENCER_TMR_SOURCE: 813 case SEQUENCER_TMR_SOURCE:
795 *(int *)addr = SEQUENCER_TMR_INTERNAL; 814 *(int *)addr = SEQUENCER_TMR_INTERNAL;
796 break; 815 break;
797 816
798 case SEQUENCER_TMR_METRONOME: 817 case SEQUENCER_TMR_METRONOME:
799 /* noop */ 818 /* noop */
800 break; 819 break;
801 820
802 case SEQUENCER_THRESHOLD: 821 case SEQUENCER_THRESHOLD:
@@ -830,27 +849,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo @@ -830,27 +849,27 @@ sequencerioctl(dev_t dev, u_long cmd, vo
830 sequencer_exit(sc); 849 sequencer_exit(sc);
831 850
832 return error; 851 return error;
833} 852}
834 853
835static int 854static int
836sequencerpoll(dev_t dev, int events, struct lwp *l) 855sequencerpoll(dev_t dev, int events, struct lwp *l)
837{ 856{
838 struct sequencer_softc *sc; 857 struct sequencer_softc *sc;
839 int revents = 0; 858 int revents = 0;
840 if ((sc = sequencerget(SEQUENCERUNIT(dev))) == NULL) 859 if ((sc = sequencerget(SEQUENCERUNIT(dev))) == NULL)
841 return ENXIO; 860 return ENXIO;
842 861
843 DPRINTF(("sequencerpoll: %p events=0x%x\n", sc, events)); 862 DPRINTF(("%s: %p events=0x%x\n", __func__, sc, events));
844 863
845 mutex_enter(&sc->lock); 864 mutex_enter(&sc->lock);
846 if (events & (POLLIN | POLLRDNORM)) 865 if (events & (POLLIN | POLLRDNORM))
847 if ((sc->flags&FREAD) && !SEQ_QEMPTY(&sc->inq)) 866 if ((sc->flags&FREAD) && !SEQ_QEMPTY(&sc->inq))
848 revents |= events & (POLLIN | POLLRDNORM); 867 revents |= events & (POLLIN | POLLRDNORM);
849 868
850 if (events & (POLLOUT | POLLWRNORM)) 869 if (events & (POLLOUT | POLLWRNORM))
851 if ((sc->flags&FWRITE) && SEQ_QLEN(&sc->outq) < sc->lowat) 870 if ((sc->flags&FWRITE) && SEQ_QLEN(&sc->outq) < sc->lowat)
852 revents |= events & (POLLOUT | POLLWRNORM); 871 revents |= events & (POLLOUT | POLLWRNORM);
853 872
854 if (revents == 0) { 873 if (revents == 0) {
855 if ((sc->flags&FREAD) && (events & (POLLIN | POLLRDNORM))) 874 if ((sc->flags&FREAD) && (events & (POLLIN | POLLRDNORM)))
856 selrecord(l, &sc->rsel); 875 selrecord(l, &sc->rsel);
@@ -961,27 +980,27 @@ sequencerkqfilter(dev_t dev, struct knot @@ -961,27 +980,27 @@ sequencerkqfilter(dev_t dev, struct knot
961 mutex_exit(&sc->lock); 980 mutex_exit(&sc->lock);
962 981
963 return (0); 982 return (0);
964} 983}
965 984
966static void 985static void
967seq_reset(struct sequencer_softc *sc) 986seq_reset(struct sequencer_softc *sc)
968{ 987{
969 int i, chn; 988 int i, chn;
970 struct midi_dev *md; 989 struct midi_dev *md;
971 990
972 KASSERT(mutex_owned(&sc->lock)); 991 KASSERT(mutex_owned(&sc->lock));
973 992
974 if ( !(sc->flags & FWRITE) ) 993 if (!(sc->flags & FWRITE))
975 return; 994 return;
976 for (i = 0; i < sc->nmidi; i++) { 995 for (i = 0; i < sc->nmidi; i++) {
977 md = sc->devs[i]; 996 md = sc->devs[i];
978 midiseq_reset(md); 997 midiseq_reset(md);
979 for (chn = 0; chn < MAXCHAN; chn++) { 998 for (chn = 0; chn < MAXCHAN; chn++) {
980 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE, 999 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE,
981 .controller=MIDI_CTRL_NOTES_OFF)); 1000 .controller=MIDI_CTRL_NOTES_OFF));
982 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE, 1001 midiseq_ctlchange(md, chn, &SEQ_MK_CHN(CTL_CHANGE,
983 .controller=MIDI_CTRL_RESET)); 1002 .controller=MIDI_CTRL_RESET));
984 midiseq_pitchbend(md, chn, &SEQ_MK_CHN(PITCH_BEND, 1003 midiseq_pitchbend(md, chn, &SEQ_MK_CHN(PITCH_BEND,
985 .value=MIDI_BEND_NEUTRAL)); 1004 .value=MIDI_BEND_NEUTRAL));
986 } 1005 }
987 } 1006 }
@@ -1104,27 +1123,27 @@ seq_do_local(struct sequencer_softc *sc, @@ -1104,27 +1123,27 @@ seq_do_local(struct sequencer_softc *sc,
1104 1123
1105static int 1124static int
1106seq_do_sysex(struct sequencer_softc *sc, seq_event_t *b) 1125seq_do_sysex(struct sequencer_softc *sc, seq_event_t *b)
1107{ 1126{
1108 int dev, i; 1127 int dev, i;
1109 struct midi_dev *md; 1128 struct midi_dev *md;
1110 uint8_t *bf = b->sysex.buffer; 1129 uint8_t *bf = b->sysex.buffer;
1111 1130
1112 KASSERT(mutex_owned(&sc->lock)); 1131 KASSERT(mutex_owned(&sc->lock));
1113 1132
1114 dev = b->sysex.device; 1133 dev = b->sysex.device;
1115 if (dev < 0 || dev >= sc->nmidi) 1134 if (dev < 0 || dev >= sc->nmidi)
1116 return (ENXIO); 1135 return (ENXIO);
1117 DPRINTF(("seq_do_sysex: dev=%d\n", dev)); 1136 DPRINTF(("%s: dev=%d\n", __func__, dev));
1118 md = sc->devs[dev]; 1137 md = sc->devs[dev];
1119 1138
1120 if (!md->doingsysex) { 1139 if (!md->doingsysex) {
1121 midiseq_out(md, (uint8_t[]){MIDI_SYSEX_START}, 1, 0); 1140 midiseq_out(md, (uint8_t[]){MIDI_SYSEX_START}, 1, 0);
1122 md->doingsysex = 1; 1141 md->doingsysex = 1;
1123 } 1142 }
1124 1143
1125 for (i = 0; i < 6 && bf[i] != 0xff; i++) 1144 for (i = 0; i < 6 && bf[i] != 0xff; i++)
1126 ; 1145 ;
1127 midiseq_out(md, bf, i, 0); 1146 midiseq_out(md, bf, i, 0);
1128 if (i < 6 || (i > 0 && bf[i-1] == MIDI_SYSEX_END)) 1147 if (i < 6 || (i > 0 && bf[i-1] == MIDI_SYSEX_END))
1129 md->doingsysex = 0; 1148 md->doingsysex = 0;
1130 return 0; 1149 return 0;
@@ -1156,27 +1175,27 @@ seq_timer_waitabs(struct sequencer_softc @@ -1156,27 +1175,27 @@ seq_timer_waitabs(struct sequencer_softc
1156#ifdef DIAGNOSTIC 1175#ifdef DIAGNOSTIC
1157 if (ticks > 20 * hz) { 1176 if (ticks > 20 * hz) {
1158 /* Waiting more than 20s */ 1177 /* Waiting more than 20s */
1159 printf("seq_timer_waitabs: funny ticks=%d, " 1178 printf("seq_timer_waitabs: funny ticks=%d, "
1160 "usec=%lld\n", ticks, usec); 1179 "usec=%lld\n", ticks, usec);
1161 } 1180 }
1162#endif 1181#endif
1163 sc->timeout = 1; 1182 sc->timeout = 1;
1164 callout_reset(&sc->sc_callout, ticks, 1183 callout_reset(&sc->sc_callout, ticks,
1165 seq_timeout, sc); 1184 seq_timeout, sc);
1166 } 1185 }
1167#ifdef SEQUENCER_DEBUG 1186#ifdef SEQUENCER_DEBUG
1168 else if (tick < 0) 1187 else if (tick < 0)
1169 DPRINTF(("seq_timer_waitabs: ticks = %d\n", ticks)); 1188 DPRINTF(("%s: ticks = %d\n", __func__, ticks));
1170#endif 1189#endif
1171} 1190}
1172 1191
1173static int 1192static int
1174seq_do_timing(struct sequencer_softc *sc, seq_event_t *b) 1193seq_do_timing(struct sequencer_softc *sc, seq_event_t *b)
1175{ 1194{
1176 struct syn_timer *t = &sc->timer; 1195 struct syn_timer *t = &sc->timer;
1177 struct timeval when; 1196 struct timeval when;
1178 int error; 1197 int error;
1179 1198
1180 KASSERT(mutex_owned(&sc->lock)); 1199 KASSERT(mutex_owned(&sc->lock));
1181 1200
1182 error = 0; 1201 error = 0;
@@ -1217,31 +1236,31 @@ seq_do_timing(struct sequencer_softc *sc @@ -1217,31 +1236,31 @@ seq_do_timing(struct sequencer_softc *sc
1217 t->divs_lastchange = t->divs_lastevent; 1236 t->divs_lastchange = t->divs_lastevent;
1218 microtime(&t->reftime); 1237 microtime(&t->reftime);
1219 RECALC_USPERDIV(t); 1238 RECALC_USPERDIV(t);
1220 break; 1239 break;
1221 case TMR_ECHO: 1240 case TMR_ECHO:
1222 error = seq_input_event(sc, b); 1241 error = seq_input_event(sc, b);
1223 break; 1242 break;
1224 case TMR_RESET: 1243 case TMR_RESET:
1225 t->divs_lastevent = t->divs_lastchange = 0; 1244 t->divs_lastevent = t->divs_lastchange = 0;
1226 microtime(&t->reftime); 1245 microtime(&t->reftime);
1227 break; 1246 break;
1228 case TMR_SPP: 1247 case TMR_SPP:
1229 case TMR_TIMESIG: 1248 case TMR_TIMESIG:
1230 DPRINTF(("seq_do_timing: unimplemented %02x\n", b->timing.op)); 1249 DPRINTF(("%s: unimplemented %02x\n", __func__, b->timing.op));
1231 error = EINVAL; /* not quite accurate... */ 1250 error = EINVAL; /* not quite accurate... */
1232 break; 1251 break;
1233 default: 1252 default:
1234 DPRINTF(("seq_timer: unknown %02x\n", b->timing.op)); 1253 DPRINTF(("%s: unknown %02x\n", __func__, b->timing.op));
1235 error = EINVAL; 1254 error = EINVAL;
1236 break; 1255 break;
1237 } 1256 }
1238 return (error); 1257 return (error);
1239} 1258}
1240 1259
1241static int 1260static int
1242seq_do_fullsize(struct sequencer_softc *sc, seq_event_t *b, struct uio *uio) 1261seq_do_fullsize(struct sequencer_softc *sc, seq_event_t *b, struct uio *uio)
1243{ 1262{
1244 struct sysex_info sysex; 1263 struct sysex_info sysex;
1245 u_int dev; 1264 u_int dev;
1246 1265
1247#ifdef DIAGNOSTIC 1266#ifdef DIAGNOSTIC
@@ -1335,27 +1354,27 @@ seq_to_new(seq_event_t *ev, struct uio * @@ -1335,27 +1354,27 @@ seq_to_new(seq_event_t *ev, struct uio *
1335 */ 1354 */
1336 *ev = SEQ_MK_TIMING(RESET); 1355 *ev = SEQ_MK_TIMING(RESET);
1337 break; 1356 break;
1338 case SEQOLD_PGMCHANGE: 1357 case SEQOLD_PGMCHANGE:
1339 *ev = SEQ_MK_CHN(PGM_CHANGE, 1358 *ev = SEQ_MK_CHN(PGM_CHANGE,
1340 .device=0, .channel=chan, .program=note); 1359 .device=0, .channel=chan, .program=note);
1341 break; 1360 break;
1342 case SEQOLD_MIDIPUTC: 1361 case SEQOLD_MIDIPUTC:
1343 break; /* interpret in normal mode */ 1362 break; /* interpret in normal mode */
1344 case SEQOLD_ECHO: 1363 case SEQOLD_ECHO:
1345 case SEQOLD_PRIVATE: 1364 case SEQOLD_PRIVATE:
1346 case SEQOLD_EXTENDED: 1365 case SEQOLD_EXTENDED:
1347 default: 1366 default:
1348 DPRINTF(("seq_to_new: not impl 0x%02x\n", cmd)); 1367 DPRINTF(("%s: not impl 0x%02x\n", __func__, cmd));
1349 return EINVAL; 1368 return EINVAL;
1350 /* In case new-style events show up */ 1369 /* In case new-style events show up */
1351 case SEQ_TIMING: 1370 case SEQ_TIMING:
1352 case SEQ_CHN_VOICE: 1371 case SEQ_CHN_VOICE:
1353 case SEQ_CHN_COMMON: 1372 case SEQ_CHN_COMMON:
1354 case SEQ_FULLSIZE: 1373 case SEQ_FULLSIZE:
1355 break; 1374 break;
1356 } 1375 }
1357 return 0; 1376 return 0;
1358} 1377}
1359 1378
1360/**********************************************/ 1379/**********************************************/
1361 1380
@@ -1410,27 +1429,26 @@ midiseq_open(int unit, int flags) @@ -1410,27 +1429,26 @@ midiseq_open(int unit, int flags)
1410 /* Only after we have acquired reference via VOP_OPEN(). */ 1429 /* Only after we have acquired reference via VOP_OPEN(). */
1411 midi_getinfo(dev, &mi); 1430 midi_getinfo(dev, &mi);
1412 oflags = flags; 1431 oflags = flags;
1413 if ((mi.props & MIDI_PROP_CAN_INPUT) == 0) 1432 if ((mi.props & MIDI_PROP_CAN_INPUT) == 0)
1414 flags &= ~FREAD; 1433 flags &= ~FREAD;
1415 if ((flags & (FREAD|FWRITE)) == 0) { 1434 if ((flags & (FREAD|FWRITE)) == 0) {
1416 VOP_CLOSE(vp, oflags, kauth_cred_get()); 1435 VOP_CLOSE(vp, oflags, kauth_cred_get());
1417 vrele(vp); 1436 vrele(vp);
1418 return NULL; 1437 return NULL;
1419 } 1438 }
1420 1439
1421 sc = device_lookup_private(&midi_cd, unit); 1440 sc = device_lookup_private(&midi_cd, unit);
1422 md = kmem_zalloc(sizeof(*md), KM_SLEEP); 1441 md = kmem_zalloc(sizeof(*md), KM_SLEEP);
1423 md->msc = sc; 
1424 md->unit = unit; 1442 md->unit = unit;
1425 md->name = mi.name; 1443 md->name = mi.name;
1426 md->subtype = 0; 1444 md->subtype = 0;
1427 md->nr_voices = 128; /* XXX */ 1445 md->nr_voices = 128; /* XXX */
1428 md->instr_bank_size = 128; /* XXX */ 1446 md->instr_bank_size = 128; /* XXX */
1429 md->vp = vp; 1447 md->vp = vp;
1430 if (mi.props & MIDI_PROP_CAN_INPUT) 1448 if (mi.props & MIDI_PROP_CAN_INPUT)
1431 md->capabilities |= SYNTH_CAP_INPUT; 1449 md->capabilities |= SYNTH_CAP_INPUT;
1432 sc->seq_md = md; 1450 sc->seq_md = md;
1433 return (md); 1451 return (md);
1434} 1452}
1435 1453
1436static void 1454static void
@@ -1441,28 +1459,28 @@ midiseq_close(struct midi_dev *md) @@ -1441,28 +1459,28 @@ midiseq_close(struct midi_dev *md)
1441 kmem_free(md, sizeof(*md)); 1459 kmem_free(md, sizeof(*md));
1442} 1460}
1443 1461
1444static void 1462static void
1445midiseq_reset(struct midi_dev *md) 1463midiseq_reset(struct midi_dev *md)
1446{ 1464{
1447 /* XXX send GM reset? */ 1465 /* XXX send GM reset? */
1448 DPRINTFN(3, ("midiseq_reset: %d\n", md->unit)); 1466 DPRINTFN(3, ("midiseq_reset: %d\n", md->unit));
1449} 1467}
1450 1468
1451static int 1469static int
1452midiseq_out(struct midi_dev *md, u_char *bf, u_int cc, int chk) 1470midiseq_out(struct midi_dev *md, u_char *bf, u_int cc, int chk)
1453{ 1471{
1454 DPRINTFN(5, ("midiseq_out: m=%p, unit=%d, bf[0]=0x%02x, cc=%d\n", 1472 DPRINTFN(5, ("midiseq_out: md=%p, unit=%d, bf[0]=0x%02x, cc=%d\n",
1455 md->msc, md->unit, bf[0], cc)); 1473 md, md->unit, bf[0], cc));
1456 1474
1457 /* midi(4) does running status compression where appropriate. */ 1475 /* midi(4) does running status compression where appropriate. */
1458 return midi_writebytes(md->unit, bf, cc); 1476 return midi_writebytes(md->unit, bf, cc);
1459} 1477}
1460 1478
1461/* 1479/*
1462 * If the writing process hands us a hidden note-off in a note-on event, 1480 * If the writing process hands us a hidden note-off in a note-on event,
1463 * we will simply write it that way; no need to special case it here, 1481 * we will simply write it that way; no need to special case it here,
1464 * as midi(4) will always canonicalize or compress as appropriate anyway. 1482 * as midi(4) will always canonicalize or compress as appropriate anyway.
1465 */ 1483 */
1466static int 1484static int
1467midiseq_noteon(struct midi_dev *md, int chan, int key, seq_event_t *ev) 1485midiseq_noteon(struct midi_dev *md, int chan, int key, seq_event_t *ev)
1468{ 1486{

cvs diff -r1.16 -r1.16.10.1 src/sys/dev/sequencervar.h (expand / switch to unified diff)

--- src/sys/dev/sequencervar.h 2013/04/27 22:12:42 1.16
+++ src/sys/dev/sequencervar.h 2015/01/11 14:13:25 1.16.10.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sequencervar.h,v 1.16 2013/04/27 22:12:42 christos Exp $ */ 1/* $NetBSD: sequencervar.h,v 1.16.10.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org). 8 * by Lennart Augustsson (augustss@NetBSD.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -58,27 +58,26 @@ struct sequencer_queue { @@ -58,27 +58,26 @@ struct sequencer_queue {
58#define SEQ_QLEN(q) ((q)->count) 58#define SEQ_QLEN(q) ((q)->count)
59 59
60struct sequencer_softc; 60struct sequencer_softc;
61 61
62#define MAXCHAN 16 62#define MAXCHAN 16
63struct midi_dev { 63struct midi_dev {
64 const char *name; 64 const char *name;
65 int subtype; 65 int subtype;
66 int capabilities; 66 int capabilities;
67 int nr_voices; 67 int nr_voices;
68 int instr_bank_size; 68 int instr_bank_size;
69 int unit; 69 int unit;
70 struct sequencer_softc *seq; 70 struct sequencer_softc *seq;
71 struct midi_softc *msc; 
72 char doingsysex; /* doing a SEQ_SYSEX */ 71 char doingsysex; /* doing a SEQ_SYSEX */
73 vnode_t *vp; 72 vnode_t *vp;
74}; 73};
75 74
76struct sequencer_softc { 75struct sequencer_softc {
77 callout_t sc_callout; 76 callout_t sc_callout;
78 kmutex_t lock; 77 kmutex_t lock;
79 kcondvar_t wchan; 78 kcondvar_t wchan;
80 kcondvar_t rchan; 79 kcondvar_t rchan;
81 kcondvar_t lchan; 80 kcondvar_t lchan;
82 int dvlock; 81 int dvlock;
83 int dying; 82 int dying;
84 u_int isopen; /* Open indicator */ 83 u_int isopen; /* Open indicator */

cvs diff -r1.12 -r1.12.22.1 src/sys/dev/usb/FILES (expand / switch to unified diff)

--- src/sys/dev/usb/FILES 2012/01/17 03:49:20 1.12
+++ src/sys/dev/usb/FILES 2015/01/11 14:13:25 1.12.22.1
@@ -45,28 +45,26 @@ ukbdmap.c wscons key mapping for ukbd @@ -45,28 +45,26 @@ ukbdmap.c wscons key mapping for ukbd
45ukbdvar.h API for ukbd.c 45ukbdvar.h API for ukbd.c
46ulpt.c USB printer class driver 46ulpt.c USB printer class driver
47umass.c USB mass storage wire protocol driver 47umass.c USB mass storage wire protocol driver
48umass_isdata.c In-System Design ATA over bulk-only driver 48umass_isdata.c In-System Design ATA over bulk-only driver
49umass_isdata.h and definitions for it 49umass_isdata.h and definitions for it
50umass_quirks.c Table of strange umass devices 50umass_quirks.c Table of strange umass devices
51umass_quirks.h and definitions for it 51umass_quirks.h and definitions for it
52umass_scsipi.c umass command protocol driver 52umass_scsipi.c umass command protocol driver
53umass_scsipi.h and definitions for it 53umass_scsipi.h and definitions for it
54umassvar.h definitions for umass.c 54umassvar.h definitions for umass.c
55umidi.c USB MIDI driver 55umidi.c USB MIDI driver
56umidi_quirks.c Strange MIDI devices 56umidi_quirks.c Strange MIDI devices
57umidi_quirks.h and definitions for it 57umidi_quirks.h and definitions for it
58umidireg.h Protocol definitions for umidi.c 
59umidivar.h definitions for umidi.c 
60umodem.c USB modem (CDC ACM) driver 58umodem.c USB modem (CDC ACM) driver
61ums.c USB mouse driver 59ums.c USB mouse driver
62urio.c USB Diamond Rio500 driver 60urio.c USB Diamond Rio500 driver
63urio.h USB Diamond Rio500 defines 61urio.h USB Diamond Rio500 defines
64usb.c usb (bus) device driver 62usb.c usb (bus) device driver
65usb.h general USB defines 63usb.h general USB defines
66usb_mem.c memory allocation for DMAable memory 64usb_mem.c memory allocation for DMAable memory
67usb_mem.h API for usb_mem.c 65usb_mem.h API for usb_mem.c
68usb_quirks.c table of non-conforming USB devices and their problems 66usb_quirks.c table of non-conforming USB devices and their problems
69usb_quirks.h API for usb_quirks.c 67usb_quirks.h API for usb_quirks.c
70usb_subr.c various subroutines used by USB code 68usb_subr.c various subroutines used by USB code
71usbcdc.h USB CDC class definitions 69usbcdc.h USB CDC class definitions
72usbdevs data base of known device 70usbdevs data base of known device

cvs diff -r1.65 -r1.65.12.1 src/sys/dev/usb/umidi.c (expand / switch to unified diff)

--- src/sys/dev/usb/umidi.c 2013/01/22 21:29:53 1.65
+++ src/sys/dev/usb/umidi.c 2015/01/11 14:13:25 1.65.12.1
@@ -1,16 +1,17 @@ @@ -1,16 +1,17 @@
1/* $NetBSD: umidi.c,v 1.65 2013/01/22 21:29:53 jmcneill Exp $ */ 1/* $NetBSD: umidi.c,v 1.65.12.1 2015/01/11 14:13:25 martin Exp $ */
 2
2/* 3/*
3 * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001, 2012, 2014 The NetBSD Foundation, Inc.
4 * All rights reserved. 5 * All rights reserved.
5 * 6 *
6 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
7 * by Takuya SHIOZAKI (tshiozak@NetBSD.org), (full-size transfers, extended 8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org), (full-size transfers, extended
8 * hw_if) Chapman Flack (chap@NetBSD.org), and Matthew R. Green 9 * hw_if) Chapman Flack (chap@NetBSD.org), and Matthew R. Green
9 * (mrg@eterna.com.au). 10 * (mrg@eterna.com.au).
10 * 11 *
11 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
13 * are met: 14 * are met:
14 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
@@ -21,56 +22,205 @@ @@ -21,56 +22,205 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
31 */ 32 */
32 33
33#include <sys/cdefs.h> 34#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.65 2013/01/22 21:29:53 jmcneill Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.65.12.1 2015/01/11 14:13:25 martin Exp $");
35 36
36#include <sys/types.h> 37#include <sys/types.h>
37#include <sys/param.h> 38#include <sys/param.h>
38#include <sys/systm.h> 39#include <sys/systm.h>
39#include <sys/kernel.h> 40#include <sys/kernel.h>
40#include <sys/kmem.h> 41#include <sys/kmem.h>
41#include <sys/device.h> 42#include <sys/device.h>
42#include <sys/ioctl.h> 43#include <sys/ioctl.h>
43#include <sys/conf.h> 44#include <sys/conf.h>
44#include <sys/file.h> 45#include <sys/file.h>
45#include <sys/select.h> 46#include <sys/select.h>
46#include <sys/proc.h> 47#include <sys/proc.h>
47#include <sys/vnode.h> 48#include <sys/vnode.h>
48#include <sys/poll.h> 49#include <sys/poll.h>
49#include <sys/intr.h> 50#include <sys/intr.h>
50 51
51#include <dev/usb/usb.h> 52#include <dev/usb/usb.h>
52#include <dev/usb/usbdi.h> 53#include <dev/usb/usbdi.h>
53#include <dev/usb/usbdi_util.h> 54#include <dev/usb/usbdi_util.h>
54 55
55#include <dev/auconv.h> 56#include <dev/auconv.h>
56#include <dev/usb/usbdevs.h> 57#include <dev/usb/usbdevs.h>
57#include <dev/usb/uaudioreg.h> 
58#include <dev/usb/umidireg.h> 
59#include <dev/usb/umidivar.h> 
60#include <dev/usb/umidi_quirks.h> 58#include <dev/usb/umidi_quirks.h>
61 
62#include <dev/midi_if.h> 59#include <dev/midi_if.h>
63 60
 61/* Jack Descriptor */
 62#define UMIDI_MS_HEADER 0x01
 63#define UMIDI_IN_JACK 0x02
 64#define UMIDI_OUT_JACK 0x03
 65
 66/* Jack Type */
 67#define UMIDI_EMBEDDED 0x01
 68#define UMIDI_EXTERNAL 0x02
 69
 70/* generic, for iteration */
 71typedef struct {
 72 uByte bLength;
 73 uByte bDescriptorType;
 74 uByte bDescriptorSubtype;
 75} UPACKED umidi_cs_descriptor_t;
 76
 77typedef struct {
 78 uByte bLength;
 79 uByte bDescriptorType;
 80 uByte bDescriptorSubtype;
 81 uWord bcdMSC;
 82 uWord wTotalLength;
 83} UPACKED umidi_cs_interface_descriptor_t;
 84#define UMIDI_CS_INTERFACE_DESCRIPTOR_SIZE 7
 85
 86typedef struct {
 87 uByte bLength;
 88 uByte bDescriptorType;
 89 uByte bDescriptorSubtype;
 90 uByte bNumEmbMIDIJack;
 91} UPACKED umidi_cs_endpoint_descriptor_t;
 92#define UMIDI_CS_ENDPOINT_DESCRIPTOR_SIZE 4
 93
 94typedef struct {
 95 uByte bLength;
 96 uByte bDescriptorType;
 97 uByte bDescriptorSubtype;
 98 uByte bJackType;
 99 uByte bJackID;
 100} UPACKED umidi_jack_descriptor_t;
 101#define UMIDI_JACK_DESCRIPTOR_SIZE 5
 102
 103
 104#define TO_D(p) ((usb_descriptor_t *)(p))
 105#define NEXT_D(desc) TO_D((char *)(desc)+(desc)->bLength)
 106#define TO_IFD(desc) ((usb_interface_descriptor_t *)(desc))
 107#define TO_CSIFD(desc) ((umidi_cs_interface_descriptor_t *)(desc))
 108#define TO_EPD(desc) ((usb_endpoint_descriptor_t *)(desc))
 109#define TO_CSEPD(desc) ((umidi_cs_endpoint_descriptor_t *)(desc))
 110
 111
 112#define UMIDI_PACKET_SIZE 4
 113
 114/*
 115 * hierarchie
 116 *
 117 * <-- parent child -->
 118 *
 119 * umidi(sc) -> endpoint -> jack <- (dynamically assignable) - mididev
 120 * ^ | ^ |
 121 * +-----+ +-----+
 122 */
 123
 124/* midi device */
 125struct umidi_mididev {
 126 struct umidi_softc *sc;
 127 device_t mdev;
 128 /* */
 129 struct umidi_jack *in_jack;
 130 struct umidi_jack *out_jack;
 131 char *label;
 132 size_t label_len;
 133 /* */
 134 int opened;
 135 int closing;
 136 int flags;
 137};
 138
 139/* Jack Information */
 140struct umidi_jack {
 141 struct umidi_endpoint *endpoint;
 142 /* */
 143 int cable_number;
 144 void *arg;
 145 int bound;
 146 int opened;
 147 unsigned char *midiman_ppkt;
 148 union {
 149 struct {
 150 void (*intr)(void *);
 151 } out;
 152 struct {
 153 void (*intr)(void *, int);
 154 } in;
 155 } u;
 156};
 157
 158#define UMIDI_MAX_EPJACKS 16
 159typedef unsigned char (*umidi_packet_bufp)[UMIDI_PACKET_SIZE];
 160/* endpoint data */
 161struct umidi_endpoint {
 162 struct umidi_softc *sc;
 163 /* */
 164 int addr;
 165 usbd_pipe_handle pipe;
 166 usbd_xfer_handle xfer;
 167 umidi_packet_bufp buffer;
 168 umidi_packet_bufp next_slot;
 169 u_int32_t buffer_size;
 170 int num_scheduled;
 171 int num_open;
 172 int num_jacks;
 173 int soliciting;
 174 void *solicit_cookie;
 175 int armed;
 176 struct umidi_jack *jacks[UMIDI_MAX_EPJACKS];
 177 u_int16_t this_schedule; /* see UMIDI_MAX_EPJACKS */
 178 u_int16_t next_schedule;
 179};
 180
 181/* software context */
 182struct umidi_softc {
 183 device_t sc_dev;
 184 usbd_device_handle sc_udev;
 185 usbd_interface_handle sc_iface;
 186 const struct umidi_quirk *sc_quirk;
 187
 188 int sc_dying;
 189
 190 int sc_out_num_jacks;
 191 struct umidi_jack *sc_out_jacks;
 192 int sc_in_num_jacks;
 193 struct umidi_jack *sc_in_jacks;
 194 struct umidi_jack *sc_jacks;
 195
 196 int sc_num_mididevs;
 197 struct umidi_mididev *sc_mididevs;
 198
 199 int sc_out_num_endpoints;
 200 struct umidi_endpoint *sc_out_ep;
 201 int sc_in_num_endpoints;
 202 struct umidi_endpoint *sc_in_ep;
 203 struct umidi_endpoint *sc_endpoints;
 204 size_t sc_endpoints_len;
 205 int cblnums_global;
 206
 207 kmutex_t sc_lock;
 208 kcondvar_t sc_cv;
 209 kcondvar_t sc_detach_cv;
 210
 211 int sc_refcnt;
 212};
 213
64#ifdef UMIDI_DEBUG 214#ifdef UMIDI_DEBUG
65#define DPRINTF(x) if (umididebug) printf x 215#define DPRINTF(x) if (umididebug) printf x
66#define DPRINTFN(n,x) if (umididebug >= (n)) printf x 216#define DPRINTFN(n,x) if (umididebug >= (n)) printf x
67#include <sys/time.h> 217#include <sys/time.h>
68static struct timeval umidi_tv; 218static struct timeval umidi_tv;
69int umididebug = 0; 219int umididebug = 0;
70#else 220#else
71#define DPRINTF(x) 221#define DPRINTF(x)
72#define DPRINTFN(n,x) 222#define DPRINTFN(n,x)
73#endif 223#endif
74 224
75#define UMIDI_ENDPOINT_SIZE(sc) (sizeof(*(sc)->sc_out_ep) * \ 225#define UMIDI_ENDPOINT_SIZE(sc) (sizeof(*(sc)->sc_out_ep) * \
76 (sc->sc_out_num_endpoints + \ 226 (sc->sc_out_num_endpoints + \
@@ -200,69 +350,74 @@ umidi_attach(device_t parent, device_t s @@ -200,69 +350,74 @@ umidi_attach(device_t parent, device_t s
200 aprint_normal_dev(self, "%s\n", devinfop); 350 aprint_normal_dev(self, "%s\n", devinfop);
201 usbd_devinfo_free(devinfop); 351 usbd_devinfo_free(devinfop);
202 352
203 sc->sc_iface = uaa->iface; 353 sc->sc_iface = uaa->iface;
204 sc->sc_udev = uaa->device; 354 sc->sc_udev = uaa->device;
205 355
206 sc->sc_quirk = 356 sc->sc_quirk =
207 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno); 357 umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno);
208 aprint_normal_dev(self, ""); 358 aprint_normal_dev(self, "");
209 umidi_print_quirk(sc->sc_quirk); 359 umidi_print_quirk(sc->sc_quirk);
210 360
211 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); 361 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB);
212 cv_init(&sc->sc_cv, "umidopcl"); 362 cv_init(&sc->sc_cv, "umidopcl");
 363 cv_init(&sc->sc_detach_cv, "umidetcv");
 364 sc->sc_refcnt = 0;
213 365
214 err = alloc_all_endpoints(sc); 366 err = alloc_all_endpoints(sc);
215 if (err != USBD_NORMAL_COMPLETION) { 367 if (err != USBD_NORMAL_COMPLETION) {
216 aprint_error_dev(self, 368 aprint_error_dev(self,
217 "alloc_all_endpoints failed. (err=%d)\n", err); 369 "alloc_all_endpoints failed. (err=%d)\n", err);
218 goto error; 370 goto out;
219 } 371 }
220 err = alloc_all_jacks(sc); 372 err = alloc_all_jacks(sc);
221 if (err != USBD_NORMAL_COMPLETION) { 373 if (err != USBD_NORMAL_COMPLETION) {
222 free_all_endpoints(sc); 
223 aprint_error_dev(self, "alloc_all_jacks failed. (err=%d)\n", 374 aprint_error_dev(self, "alloc_all_jacks failed. (err=%d)\n",
224 err); 375 err);
225 goto error; 376 goto out_free_endpoints;
226 } 377 }
227 aprint_normal_dev(self, "out=%d, in=%d\n", 378 aprint_normal_dev(self, "out=%d, in=%d\n",
228 sc->sc_out_num_jacks, sc->sc_in_num_jacks); 379 sc->sc_out_num_jacks, sc->sc_in_num_jacks);
229 380
230 err = assign_all_jacks_automatically(sc); 381 err = assign_all_jacks_automatically(sc);
231 if (err != USBD_NORMAL_COMPLETION) { 382 if (err != USBD_NORMAL_COMPLETION) {
232 unbind_all_jacks(sc); 
233 free_all_jacks(sc); 
234 free_all_endpoints(sc); 
235 aprint_error_dev(self, 383 aprint_error_dev(self,
236 "assign_all_jacks_automatically failed. (err=%d)\n", err); 384 "assign_all_jacks_automatically failed. (err=%d)\n", err);
237 goto error; 385 goto out_free_jacks;
238 } 386 }
239 err = attach_all_mididevs(sc); 387 err = attach_all_mididevs(sc);
240 if (err != USBD_NORMAL_COMPLETION) { 388 if (err != USBD_NORMAL_COMPLETION) {
241 free_all_jacks(sc); 
242 free_all_endpoints(sc); 
243 aprint_error_dev(self, 389 aprint_error_dev(self,
244 "attach_all_mididevs failed. (err=%d)\n", err); 390 "attach_all_mididevs failed. (err=%d)\n", err);
 391 goto out_free_jacks;
245 } 392 }
246 393
247#ifdef UMIDI_DEBUG 394#ifdef UMIDI_DEBUG
248 dump_sc(sc); 395 dump_sc(sc);
249#endif 396#endif
250 397
251 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, 398 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH,
252 sc->sc_udev, sc->sc_dev); 399 sc->sc_udev, sc->sc_dev);
253 400
254 return; 401 return;
255error: 402
 403out_free_jacks:
 404 unbind_all_jacks(sc);
 405 free_all_jacks(sc);
 406
 407out_free_endpoints:
 408 free_all_endpoints(sc);
 409
 410out:
256 aprint_error_dev(self, "disabled.\n"); 411 aprint_error_dev(self, "disabled.\n");
257 sc->sc_dying = 1; 412 sc->sc_dying = 1;
258 KERNEL_UNLOCK_ONE(curlwp); 413 KERNEL_UNLOCK_ONE(curlwp);
259 return; 414 return;
260} 415}
261 416
262void 417void
263umidi_childdet(device_t self, device_t child) 418umidi_childdet(device_t self, device_t child)
264{ 419{
265 int i; 420 int i;
266 struct umidi_softc *sc = device_private(self); 421 struct umidi_softc *sc = device_private(self);
267 422
268 KASSERT(sc->sc_mididevs != NULL); 423 KASSERT(sc->sc_mididevs != NULL);
@@ -289,175 +444,202 @@ umidi_activate(device_t self, enum devac @@ -289,175 +444,202 @@ umidi_activate(device_t self, enum devac
289 default: 444 default:
290 DPRINTFN(1,("umidi_activate (%d)\n", act)); 445 DPRINTFN(1,("umidi_activate (%d)\n", act));
291 return EOPNOTSUPP; 446 return EOPNOTSUPP;
292 } 447 }
293} 448}
294 449
295int  450int
296umidi_detach(device_t self, int flags) 451umidi_detach(device_t self, int flags)
297{ 452{
298 struct umidi_softc *sc = device_private(self); 453 struct umidi_softc *sc = device_private(self);
299 454
300 DPRINTFN(1,("umidi_detach\n")); 455 DPRINTFN(1,("umidi_detach\n"));
301 456
 457 mutex_enter(&sc->sc_lock);
302 sc->sc_dying = 1; 458 sc->sc_dying = 1;
 459 if (--sc->sc_refcnt >= 0)
 460 usb_detach_wait(sc->sc_dev, &sc->sc_detach_cv, &sc->sc_lock);
 461 mutex_exit(&sc->sc_lock);
 462
303 detach_all_mididevs(sc, flags); 463 detach_all_mididevs(sc, flags);
304 free_all_mididevs(sc); 464 free_all_mididevs(sc);
305 free_all_jacks(sc); 465 free_all_jacks(sc);
306 free_all_endpoints(sc); 466 free_all_endpoints(sc);
307 467
308 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, 468 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
309 sc->sc_dev); 469 sc->sc_dev);
310 470
311 mutex_destroy(&sc->sc_lock); 471 mutex_destroy(&sc->sc_lock);
 472 cv_destroy(&sc->sc_detach_cv);
312 cv_destroy(&sc->sc_cv); 473 cv_destroy(&sc->sc_cv);
313 474
314 return 0; 475 return 0;
315} 476}
316 477
317 478
318/* 479/*
319 * midi_if stuffs 480 * midi_if stuffs
320 */ 481 */
321int 482int
322umidi_open(void *addr, 483umidi_open(void *addr,
323 int flags, 484 int flags,
324 void (*iintr)(void *, int), 485 void (*iintr)(void *, int),
325 void (*ointr)(void *), 486 void (*ointr)(void *),
326 void *arg) 487 void *arg)
327{ 488{
328 struct umidi_mididev *mididev = addr; 489 struct umidi_mididev *mididev = addr;
329 struct umidi_softc *sc = mididev->sc; 490 struct umidi_softc *sc = mididev->sc;
330 usbd_status err; 491 usbd_status err;
331 492
 493 KASSERT(mutex_owned(&sc->sc_lock));
332 DPRINTF(("umidi_open: sc=%p\n", sc)); 494 DPRINTF(("umidi_open: sc=%p\n", sc));
333 495
334 if (!sc) 
335 return ENXIO; 
336 if (mididev->opened) 496 if (mididev->opened)
337 return EBUSY; 497 return EBUSY;
338 if (sc->sc_dying) 498 if (sc->sc_dying)
339 return EIO; 499 return EIO;
340 500
341 mididev->opened = 1; 501 mididev->opened = 1;
342 mididev->closing = 0; 
343 mididev->flags = flags; 502 mididev->flags = flags;
344 if ((mididev->flags & FWRITE) && mididev->out_jack) { 503 if ((mididev->flags & FWRITE) && mididev->out_jack) {
345 err = open_out_jack(mididev->out_jack, arg, ointr); 504 err = open_out_jack(mididev->out_jack, arg, ointr);
346 if ( err != USBD_NORMAL_COMPLETION ) 505 if (err != USBD_NORMAL_COMPLETION)
347 goto bad; 506 goto bad;
348 } 507 }
349 if ((mididev->flags & FREAD) && mididev->in_jack) { 508 if ((mididev->flags & FREAD) && mididev->in_jack) {
350 err = open_in_jack(mididev->in_jack, arg, iintr); 509 err = open_in_jack(mididev->in_jack, arg, iintr);
351 if ( err != USBD_NORMAL_COMPLETION 510 KASSERT(mididev->opened);
352 && err != USBD_IN_PROGRESS ) 511 if (err != USBD_NORMAL_COMPLETION &&
 512 err != USBD_IN_PROGRESS) {
 513 if (mididev->out_jack)
 514 close_out_jack(mididev->out_jack);
353 goto bad; 515 goto bad;
 516 }
354 } 517 }
355 518
356 return 0; 519 return 0;
357bad: 520bad:
358 mididev->opened = 0; 521 mididev->opened = 0;
359 DPRINTF(("umidi_open: usbd_status %d\n", err)); 522 DPRINTF(("umidi_open: usbd_status %d\n", err));
 523 KASSERT(mutex_owned(&sc->sc_lock));
360 return USBD_IN_USE == err ? EBUSY : EIO; 524 return USBD_IN_USE == err ? EBUSY : EIO;
361} 525}
362 526
363void 527void
364umidi_close(void *addr) 528umidi_close(void *addr)
365{ 529{
366 struct umidi_mididev *mididev = addr; 530 struct umidi_mididev *mididev = addr;
 531 struct umidi_softc *sc = mididev->sc;
 532
 533 KASSERT(mutex_owned(&sc->sc_lock));
 534
 535 if (mididev->closing)
 536 return;
367 537
368 mididev->closing = 1; 538 mididev->closing = 1;
369 539
370 mutex_spin_exit(&mididev->sc->sc_lock); 540 sc->sc_refcnt++;
371 541
372 if ((mididev->flags & FWRITE) && mididev->out_jack) 542 if ((mididev->flags & FWRITE) && mididev->out_jack)
373 close_out_jack(mididev->out_jack); 543 close_out_jack(mididev->out_jack);
374 if ((mididev->flags & FREAD) && mididev->in_jack) 544 if ((mididev->flags & FREAD) && mididev->in_jack)
375 close_in_jack(mididev->in_jack); 545 close_in_jack(mididev->in_jack);
376 546
377 mutex_spin_enter(&mididev->sc->sc_lock); 547 if (--sc->sc_refcnt < 0)
 548 usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv);
378 549
379 mididev->opened = 0; 550 mididev->opened = 0;
 551 mididev->closing = 0;
380} 552}
381 553
382int 554int
383umidi_channelmsg(void *addr, int status, int channel, u_char *msg, 555umidi_channelmsg(void *addr, int status, int channel, u_char *msg,
384 int len) 556 int len)
385{ 557{
386 struct umidi_mididev *mididev = addr; 558 struct umidi_mididev *mididev = addr;
387 559
 560 KASSERT(mutex_owned(&mididev->sc->sc_lock));
 561
388 if (!mididev->out_jack || !mididev->opened || mididev->closing) 562 if (!mididev->out_jack || !mididev->opened || mididev->closing)
389 return EIO; 563 return EIO;
390  564
391 return out_jack_output(mididev->out_jack, msg, len, (status>>4)&0xf); 565 return out_jack_output(mididev->out_jack, msg, len, (status>>4)&0xf);
392} 566}
393 567
394int 568int
395umidi_commonmsg(void *addr, int status, u_char *msg, int len) 569umidi_commonmsg(void *addr, int status, u_char *msg, int len)
396{ 570{
397 struct umidi_mididev *mididev = addr; 571 struct umidi_mididev *mididev = addr;
398 int cin; 572 int cin;
399 573
 574 KASSERT(mutex_owned(&mididev->sc->sc_lock));
 575
400 if (!mididev->out_jack || !mididev->opened || mididev->closing) 576 if (!mididev->out_jack || !mididev->opened || mididev->closing)
401 return EIO; 577 return EIO;
402 578
403 switch ( len ) { 579 switch ( len ) {
404 case 1: cin = 5; break; 580 case 1: cin = 5; break;
405 case 2: cin = 2; break; 581 case 2: cin = 2; break;
406 case 3: cin = 3; break; 582 case 3: cin = 3; break;
407 default: return EIO; /* or gcc warns of cin uninitialized */ 583 default: return EIO; /* or gcc warns of cin uninitialized */
408 } 584 }
409  585
410 return out_jack_output(mididev->out_jack, msg, len, cin); 586 return out_jack_output(mididev->out_jack, msg, len, cin);
411} 587}
412 588
413int 589int
414umidi_sysex(void *addr, u_char *msg, int len) 590umidi_sysex(void *addr, u_char *msg, int len)
415{ 591{
416 struct umidi_mididev *mididev = addr; 592 struct umidi_mididev *mididev = addr;
417 int cin; 593 int cin;
418 594
 595 KASSERT(mutex_owned(&mididev->sc->sc_lock));
 596
419 if (!mididev->out_jack || !mididev->opened || mididev->closing) 597 if (!mididev->out_jack || !mididev->opened || mididev->closing)
420 return EIO; 598 return EIO;
421 599
422 switch ( len ) { 600 switch ( len ) {
423 case 1: cin = 5; break; 601 case 1: cin = 5; break;
424 case 2: cin = 6; break; 602 case 2: cin = 6; break;
425 case 3: cin = (msg[2] == 0xf7) ? 7 : 4; break; 603 case 3: cin = (msg[2] == 0xf7) ? 7 : 4; break;
426 default: return EIO; /* or gcc warns of cin uninitialized */ 604 default: return EIO; /* or gcc warns of cin uninitialized */
427 } 605 }
428  606
429 return out_jack_output(mididev->out_jack, msg, len, cin); 607 return out_jack_output(mididev->out_jack, msg, len, cin);
430} 608}
431 609
432int 610int
433umidi_rtmsg(void *addr, int d) 611umidi_rtmsg(void *addr, int d)
434{ 612{
435 struct umidi_mididev *mididev = addr; 613 struct umidi_mididev *mididev = addr;
436 u_char msg = d; 614 u_char msg = d;
437 615
 616 KASSERT(mutex_owned(&mididev->sc->sc_lock));
 617
438 if (!mididev->out_jack || !mididev->opened || mididev->closing) 618 if (!mididev->out_jack || !mididev->opened || mididev->closing)
439 return EIO; 619 return EIO;
440 620
441 return out_jack_output(mididev->out_jack, &msg, 1, 0xf); 621 return out_jack_output(mididev->out_jack, &msg, 1, 0xf);
442} 622}
443 623
444void 624void
445umidi_getinfo(void *addr, struct midi_info *mi) 625umidi_getinfo(void *addr, struct midi_info *mi)
446{ 626{
447 struct umidi_mididev *mididev = addr; 627 struct umidi_mididev *mididev = addr;
448 struct umidi_softc *sc = mididev->sc; 628 struct umidi_softc *sc = mididev->sc;
449 int mm = UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE); 629 int mm = UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE);
450 630
 631 KASSERT(mutex_owned(&sc->sc_lock));
 632
451 mi->name = mididev->label; 633 mi->name = mididev->label;
452 mi->props = MIDI_PROP_OUT_INTR; 634 mi->props = MIDI_PROP_OUT_INTR;
453 if (mididev->in_jack) 635 if (mididev->in_jack)
454 mi->props |= MIDI_PROP_CAN_INPUT; 636 mi->props |= MIDI_PROP_CAN_INPUT;
455 midi_register_hw_if_ext(mm? &umidi_hw_if_mm : &umidi_hw_if_ext); 637 midi_register_hw_if_ext(mm? &umidi_hw_if_mm : &umidi_hw_if_ext);
456} 638}
457 639
458static void 640static void
459umidi_get_locks(void *addr, kmutex_t **thread, kmutex_t **intr) 641umidi_get_locks(void *addr, kmutex_t **thread, kmutex_t **intr)
460{ 642{
461 struct umidi_mididev *mididev = addr; 643 struct umidi_mididev *mididev = addr;
462 struct umidi_softc *sc = mididev->sc; 644 struct umidi_softc *sc = mididev->sc;
463 645
@@ -646,27 +828,27 @@ alloc_all_endpoints_fixed_ep(struct umid @@ -646,27 +828,27 @@ alloc_all_endpoints_fixed_ep(struct umid
646 } 828 }
647 /* 829 /*
648 * MIDISPORT_2X4 inputs on an interrupt rather than a bulk 830 * MIDISPORT_2X4 inputs on an interrupt rather than a bulk
649 * endpoint. The existing input logic in this driver seems 831 * endpoint. The existing input logic in this driver seems
650 * to work successfully if we just stop treating an interrupt 832 * to work successfully if we just stop treating an interrupt
651 * endpoint as illegal (or the in_progress status we get on 833 * endpoint as illegal (or the in_progress status we get on
652 * the initial transfer). It does not seem necessary to 834 * the initial transfer). It does not seem necessary to
653 * actually use the interrupt flavor of alloc_pipe or make 835 * actually use the interrupt flavor of alloc_pipe or make
654 * other serious rearrangements of logic. I like that. 836 * other serious rearrangements of logic. I like that.
655 */ 837 */
656 switch ( UE_GET_XFERTYPE(epd->bmAttributes) ) { 838 switch ( UE_GET_XFERTYPE(epd->bmAttributes) ) {
657 case UE_BULK: 839 case UE_BULK:
658 case UE_INTERRUPT: 840 case UE_INTERRUPT:
659 if ( UE_DIR_IN == UE_GET_DIR(epd->bEndpointAddress) ) 841 if (UE_DIR_IN == UE_GET_DIR(epd->bEndpointAddress))
660 break; 842 break;
661 /*FALLTHROUGH*/ 843 /*FALLTHROUGH*/
662 default: 844 default:
663 aprint_error_dev(sc->sc_dev, 845 aprint_error_dev(sc->sc_dev,
664 "illegal endpoint(in:%d)\n", fp->in_ep[i].ep); 846 "illegal endpoint(in:%d)\n", fp->in_ep[i].ep);
665 err = USBD_INVAL; 847 err = USBD_INVAL;
666 goto error; 848 goto error;
667 } 849 }
668 850
669 ep->sc = sc; 851 ep->sc = sc;
670 ep->addr = epd->bEndpointAddress; 852 ep->addr = epd->bEndpointAddress;
671 ep->num_jacks = fp->in_ep[i].num_jacks; 853 ep->num_jacks = fp->in_ep[i].num_jacks;
672 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks; 854 sc->sc_in_num_jacks += fp->in_ep[i].num_jacks;
@@ -906,38 +1088,38 @@ alloc_all_jacks(struct umidi_softc *sc) @@ -906,38 +1088,38 @@ alloc_all_jacks(struct umidi_softc *sc)
906 /* allocate/initialize structures */ 1088 /* allocate/initialize structures */
907 sc->sc_jacks = kmem_zalloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+ 1089 sc->sc_jacks = kmem_zalloc(sizeof(*sc->sc_out_jacks)*(sc->sc_in_num_jacks+
908 sc->sc_out_num_jacks), KM_SLEEP); 1090 sc->sc_out_num_jacks), KM_SLEEP);
909 if (!sc->sc_jacks) 1091 if (!sc->sc_jacks)
910 return USBD_NOMEM; 1092 return USBD_NOMEM;
911 sc->sc_out_jacks = 1093 sc->sc_out_jacks =
912 sc->sc_out_num_jacks ? sc->sc_jacks : NULL; 1094 sc->sc_out_num_jacks ? sc->sc_jacks : NULL;
913 sc->sc_in_jacks = 1095 sc->sc_in_jacks =
914 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL; 1096 sc->sc_in_num_jacks ? sc->sc_jacks+sc->sc_out_num_jacks : NULL;
915 1097
916 jack = &sc->sc_out_jacks[0]; 1098 jack = &sc->sc_out_jacks[0];
917 for (i = 0; i < sc->sc_out_num_jacks; i++) { 1099 for (i = 0; i < sc->sc_out_num_jacks; i++) {
918 jack->opened = 0; 1100 jack->opened = 0;
919 jack->binded = 0; 1101 jack->bound = 0;
920 jack->arg = NULL; 1102 jack->arg = NULL;
921 jack->u.out.intr = NULL; 1103 jack->u.out.intr = NULL;
922 jack->midiman_ppkt = NULL; 1104 jack->midiman_ppkt = NULL;
923 if (sc->cblnums_global) 1105 if (sc->cblnums_global)
924 jack->cable_number = i; 1106 jack->cable_number = i;
925 jack++; 1107 jack++;
926 } 1108 }
927 jack = &sc->sc_in_jacks[0]; 1109 jack = &sc->sc_in_jacks[0];
928 for (i = 0; i < sc->sc_in_num_jacks; i++) { 1110 for (i = 0; i < sc->sc_in_num_jacks; i++) {
929 jack->opened = 0; 1111 jack->opened = 0;
930 jack->binded = 0; 1112 jack->bound = 0;
931 jack->arg = NULL; 1113 jack->arg = NULL;
932 jack->u.in.intr = NULL; 1114 jack->u.in.intr = NULL;
933 if (sc->cblnums_global) 1115 if (sc->cblnums_global)
934 jack->cable_number = i; 1116 jack->cable_number = i;
935 jack++; 1117 jack++;
936 } 1118 }
937 1119
938 /* assign each jacks to each endpoints */ 1120 /* assign each jacks to each endpoints */
939 jack = &sc->sc_out_jacks[0]; 1121 jack = &sc->sc_out_jacks[0];
940 ep = &sc->sc_out_ep[0]; 1122 ep = &sc->sc_out_ep[0];
941 for (i = 0; i < sc->sc_out_num_endpoints; i++) { 1123 for (i = 0; i < sc->sc_out_num_endpoints; i++) {
942 for (j = 0; j < ep->num_jacks; j++) { 1124 for (j = 0; j < ep->num_jacks; j++) {
943 jack->endpoint = ep; 1125 jack->endpoint = ep;
@@ -980,107 +1162,117 @@ free_all_jacks(struct umidi_softc *sc) @@ -980,107 +1162,117 @@ free_all_jacks(struct umidi_softc *sc)
980 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL; 1162 sc->sc_jacks = sc->sc_in_jacks = sc->sc_out_jacks = NULL;
981 mutex_exit(&sc->sc_lock); 1163 mutex_exit(&sc->sc_lock);
982 1164
983 if (jacks) 1165 if (jacks)
984 kmem_free(jacks, len); 1166 kmem_free(jacks, len);
985} 1167}
986 1168
987static usbd_status 1169static usbd_status
988bind_jacks_to_mididev(struct umidi_softc *sc, 1170bind_jacks_to_mididev(struct umidi_softc *sc,
989 struct umidi_jack *out_jack, 1171 struct umidi_jack *out_jack,
990 struct umidi_jack *in_jack, 1172 struct umidi_jack *in_jack,
991 struct umidi_mididev *mididev) 1173 struct umidi_mididev *mididev)
992{ 1174{
993 if ((out_jack && out_jack->binded) || (in_jack && in_jack->binded)) 1175 if ((out_jack && out_jack->bound) || (in_jack && in_jack->bound))
994 return USBD_IN_USE; 1176 return USBD_IN_USE;
995 if (mididev->out_jack || mididev->in_jack) 1177 if (mididev->out_jack || mididev->in_jack)
996 return USBD_IN_USE; 1178 return USBD_IN_USE;
997 1179
998 if (out_jack) 1180 if (out_jack)
999 out_jack->binded = 1; 1181 out_jack->bound = 1;
1000 if (in_jack) 1182 if (in_jack)
1001 in_jack->binded = 1; 1183 in_jack->bound = 1;
1002 mididev->in_jack = in_jack; 1184 mididev->in_jack = in_jack;
1003 mididev->out_jack = out_jack; 1185 mididev->out_jack = out_jack;
1004 1186
 1187 mididev->closing = 0;
 1188
1005 return USBD_NORMAL_COMPLETION; 1189 return USBD_NORMAL_COMPLETION;
1006} 1190}
1007 1191
1008static void 1192static void
1009unbind_jacks_from_mididev(struct umidi_mididev *mididev) 1193unbind_jacks_from_mididev(struct umidi_mididev *mididev)
1010{ 1194{
 1195 KASSERT(mutex_owned(&mididev->sc->sc_lock));
 1196
 1197 mididev->closing = 1;
1011 1198
1012 if ((mididev->flags & FWRITE) && mididev->out_jack) 1199 if ((mididev->flags & FWRITE) && mididev->out_jack)
1013 close_out_jack(mididev->out_jack); 1200 close_out_jack(mididev->out_jack);
1014 if ((mididev->flags & FREAD) && mididev->in_jack) 1201 if ((mididev->flags & FREAD) && mididev->in_jack)
1015 close_in_jack(mididev->in_jack); 1202 close_in_jack(mididev->in_jack);
1016 1203
1017 if (mididev->out_jack) 1204 if (mididev->out_jack) {
1018 mididev->out_jack->binded = 0; 1205 mididev->out_jack->bound = 0;
1019 if (mididev->in_jack) 1206 mididev->out_jack = NULL;
1020 mididev->in_jack->binded = 0; 1207 }
1021 mididev->out_jack = mididev->in_jack = NULL; 1208 if (mididev->in_jack) {
 1209 mididev->in_jack->bound = 0;
 1210 mididev->in_jack = NULL;
 1211 }
1022} 1212}
1023 1213
1024static void 1214static void
1025unbind_all_jacks(struct umidi_softc *sc) 1215unbind_all_jacks(struct umidi_softc *sc)
1026{ 1216{
1027 int i; 1217 int i;
1028 1218
 1219 mutex_spin_enter(&sc->sc_lock);
1029 if (sc->sc_mididevs) 1220 if (sc->sc_mididevs)
1030 for (i = 0; i < sc->sc_num_mididevs; i++) 1221 for (i = 0; i < sc->sc_num_mididevs; i++)
1031 unbind_jacks_from_mididev(&sc->sc_mididevs[i]); 1222 unbind_jacks_from_mididev(&sc->sc_mididevs[i]);
 1223 mutex_spin_exit(&sc->sc_lock);
1032} 1224}
1033 1225
1034static usbd_status 1226static usbd_status
1035assign_all_jacks_automatically(struct umidi_softc *sc) 1227assign_all_jacks_automatically(struct umidi_softc *sc)
1036{ 1228{
1037 usbd_status err; 1229 usbd_status err;
1038 int i; 1230 int i;
1039 struct umidi_jack *out, *in; 1231 struct umidi_jack *out, *in;
1040 const signed char *asg_spec; 1232 const signed char *asg_spec;
1041 1233
1042 err = 1234 err =
1043 alloc_all_mididevs(sc, 1235 alloc_all_mididevs(sc,
1044 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks)); 1236 max(sc->sc_out_num_jacks, sc->sc_in_num_jacks));
1045 if (err!=USBD_NORMAL_COMPLETION) 1237 if (err!=USBD_NORMAL_COMPLETION)
1046 return err; 1238 return err;
1047 1239
1048 if ( UMQ_ISTYPE(sc, UMQ_TYPE_MD_FIXED)) 1240 if (UMQ_ISTYPE(sc, UMQ_TYPE_MD_FIXED))
1049 asg_spec = umidi_get_quirk_data_from_type(sc->sc_quirk, 1241 asg_spec = umidi_get_quirk_data_from_type(sc->sc_quirk,
1050 UMQ_TYPE_MD_FIXED); 1242 UMQ_TYPE_MD_FIXED);
1051 else 1243 else
1052 asg_spec = NULL; 1244 asg_spec = NULL;
1053 1245
1054 for (i = 0; i < sc->sc_num_mididevs; i++) { 1246 for (i = 0; i < sc->sc_num_mididevs; i++) {
1055 if (asg_spec != NULL) { 1247 if (asg_spec != NULL) {
1056 if (*asg_spec == -1) 1248 if (*asg_spec == -1)
1057 out = NULL; 1249 out = NULL;
1058 else 1250 else
1059 out = &sc->sc_out_jacks[*asg_spec]; 1251 out = &sc->sc_out_jacks[*asg_spec];
1060 ++ asg_spec; 1252 ++ asg_spec;
1061 if (*asg_spec == -1) 1253 if (*asg_spec == -1)
1062 in = NULL; 1254 in = NULL;
1063 else 1255 else
1064 in = &sc->sc_in_jacks[*asg_spec]; 1256 in = &sc->sc_in_jacks[*asg_spec];
1065 ++ asg_spec; 1257 ++ asg_spec;
1066 } else { 1258 } else {
1067 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i] 1259 out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i]
1068 : NULL; 1260 : NULL;
1069 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i] 1261 in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i]
1070 : NULL; 1262 : NULL;
1071 } 1263 }
1072 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]); 1264 err = bind_jacks_to_mididev(sc, out, in, &sc->sc_mididevs[i]);
1073 if (err!=USBD_NORMAL_COMPLETION) { 1265 if (err != USBD_NORMAL_COMPLETION) {
1074 free_all_mididevs(sc); 1266 free_all_mididevs(sc);
1075 return err; 1267 return err;
1076 } 1268 }
1077 } 1269 }
1078 1270
1079 return USBD_NORMAL_COMPLETION; 1271 return USBD_NORMAL_COMPLETION;
1080} 1272}
1081 1273
1082static usbd_status 1274static usbd_status
1083open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *)) 1275open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *))
1084{ 1276{
1085 struct umidi_endpoint *ep = jack->endpoint; 1277 struct umidi_endpoint *ep = jack->endpoint;
1086 struct umidi_softc *sc = ep->sc; 1278 struct umidi_softc *sc = ep->sc;
@@ -1122,146 +1314,177 @@ open_in_jack(struct umidi_jack *jack, vo @@ -1122,146 +1314,177 @@ open_in_jack(struct umidi_jack *jack, vo
1122{ 1314{
1123 usbd_status err = USBD_NORMAL_COMPLETION; 1315 usbd_status err = USBD_NORMAL_COMPLETION;
1124 struct umidi_endpoint *ep = jack->endpoint; 1316 struct umidi_endpoint *ep = jack->endpoint;
1125 1317
1126 KASSERT(mutex_owned(&ep->sc->sc_lock)); 1318 KASSERT(mutex_owned(&ep->sc->sc_lock));
1127 1319
1128 if (jack->opened) 1320 if (jack->opened)
1129 return USBD_IN_USE; 1321 return USBD_IN_USE;
1130 1322
1131 jack->arg = arg; 1323 jack->arg = arg;
1132 jack->u.in.intr = intr; 1324 jack->u.in.intr = intr;
1133 jack->opened = 1; 1325 jack->opened = 1;
1134 if (ep->num_open++ == 0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) { 1326 if (ep->num_open++ == 0 && UE_GET_DIR(ep->addr)==UE_DIR_IN) {
 1327 /*
 1328 * Can't hold the interrupt lock while calling into USB,
 1329 * but we can safely drop it here.
 1330 */
 1331 mutex_exit(&ep->sc->sc_lock);
1135 err = start_input_transfer(ep); 1332 err = start_input_transfer(ep);
1136 if (err != USBD_NORMAL_COMPLETION && 1333 if (err != USBD_NORMAL_COMPLETION &&
1137 err != USBD_IN_PROGRESS) { 1334 err != USBD_IN_PROGRESS) {
1138 ep->num_open--; 1335 ep->num_open--;
1139 } 1336 }
 1337 mutex_enter(&ep->sc->sc_lock);
1140 } 1338 }
1141 1339
1142 return err; 1340 return err;
1143} 1341}
1144 1342
1145static void 1343static void
1146close_out_jack(struct umidi_jack *jack) 1344close_out_jack(struct umidi_jack *jack)
1147{ 1345{
1148 struct umidi_endpoint *ep; 1346 struct umidi_endpoint *ep;
1149 struct umidi_softc *sc; 1347 struct umidi_softc *sc;
1150 u_int16_t mask; 1348 u_int16_t mask;
1151 int err; 1349 int err;
1152 1350
1153 if (jack->opened) { 1351 if (jack->opened) {
1154 ep = jack->endpoint; 1352 ep = jack->endpoint;
1155 sc = ep->sc; 1353 sc = ep->sc;
1156 mutex_spin_enter(&sc->sc_lock); 1354
 1355 KASSERT(mutex_owned(&sc->sc_lock));
1157 mask = 1 << (jack->cable_number); 1356 mask = 1 << (jack->cable_number);
1158 while (mask & (ep->this_schedule | ep->next_schedule)) { 1357 while (mask & (ep->this_schedule | ep->next_schedule)) {
1159 err = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock, 1358 err = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
1160 mstohz(10)); 1359 mstohz(10));
1161 if (err) 1360 if (err)
1162 break; 1361 break;
1163 } 1362 }
1164 /* 1363 /*
1165 * We can re-enter this function from both close() and 1364 * We can re-enter this function from both close() and
1166 * detach(). Make sure only one of them does this part. 1365 * detach(). Make sure only one of them does this part.
1167 */ 1366 */
1168 if (jack->opened) { 1367 if (jack->opened) {
1169 jack->opened = 0; 1368 jack->opened = 0;
1170 jack->endpoint->num_open--; 1369 jack->endpoint->num_open--;
1171 ep->this_schedule &= ~mask; 1370 ep->this_schedule &= ~mask;
1172 ep->next_schedule &= ~mask; 1371 ep->next_schedule &= ~mask;
1173 } 1372 }
1174 mutex_spin_exit(&sc->sc_lock); 
1175 } 1373 }
1176} 1374}
1177 1375
1178static void 1376static void
1179close_in_jack(struct umidi_jack *jack) 1377close_in_jack(struct umidi_jack *jack)
1180{ 1378{
1181 if (jack->opened) { 1379 if (jack->opened) {
 1380 struct umidi_softc *sc = jack->endpoint->sc;
 1381
 1382 KASSERT(mutex_owned(&sc->sc_lock));
 1383
1182 jack->opened = 0; 1384 jack->opened = 0;
1183 if (--jack->endpoint->num_open == 0) { 1385 if (--jack->endpoint->num_open == 0) {
 1386 /*
 1387 * We have to drop the (interrupt) lock so that
 1388 * the USB thread lock can be safely taken by
 1389 * the abort operation. This is safe as this
 1390 * either closing or dying will be set proerly.
 1391 */
 1392 mutex_spin_exit(&sc->sc_lock);
1184 usbd_abort_pipe(jack->endpoint->pipe); 1393 usbd_abort_pipe(jack->endpoint->pipe);
 1394 mutex_spin_enter(&sc->sc_lock);
1185 } 1395 }
1186 } 1396 }
1187} 1397}
1188 1398
1189static usbd_status 1399static usbd_status
1190attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) 1400attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev)
1191{ 1401{
1192 if (mididev->sc) 1402 if (mididev->sc)
1193 return USBD_IN_USE; 1403 return USBD_IN_USE;
1194 1404
1195 mididev->sc = sc; 1405 mididev->sc = sc;
1196  1406
1197 describe_mididev(mididev); 1407 describe_mididev(mididev);
1198 1408
1199 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, sc->sc_dev); 1409 mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, sc->sc_dev);
1200 1410
1201 return USBD_NORMAL_COMPLETION; 1411 return USBD_NORMAL_COMPLETION;
1202} 1412}
1203 1413
1204static usbd_status 1414static usbd_status
1205detach_mididev(struct umidi_mididev *mididev, int flags) 1415detach_mididev(struct umidi_mididev *mididev, int flags)
1206{ 1416{
1207 if (!mididev->sc) 1417 struct umidi_softc *sc = mididev->sc;
 1418
 1419 if (!sc)
1208 return USBD_NO_ADDR; 1420 return USBD_NO_ADDR;
1209 1421
 1422 mutex_spin_enter(&sc->sc_lock);
1210 if (mididev->opened) { 1423 if (mididev->opened) {
1211 umidi_close(mididev); 1424 umidi_close(mididev);
1212 } 1425 }
1213 unbind_jacks_from_mididev(mididev); 1426 unbind_jacks_from_mididev(mididev);
 1427 mutex_spin_exit(&sc->sc_lock);
1214 1428
1215 if (mididev->mdev != NULL) 1429 if (mididev->mdev != NULL)
1216 config_detach(mididev->mdev, flags); 1430 config_detach(mididev->mdev, flags);
1217  1431
1218 if (NULL != mididev->label) { 1432 if (NULL != mididev->label) {
1219 kmem_free(mididev->label, mididev->label_len); 1433 kmem_free(mididev->label, mididev->label_len);
1220 mididev->label = NULL; 1434 mididev->label = NULL;
1221 } 1435 }
1222 1436
1223 mididev->sc = NULL; 1437 mididev->sc = NULL;
1224 1438
1225 return USBD_NORMAL_COMPLETION; 1439 return USBD_NORMAL_COMPLETION;
1226} 1440}
1227 1441
1228static void 1442static void
1229deactivate_mididev(struct umidi_mididev *mididev) 1443deactivate_mididev(struct umidi_mididev *mididev)
1230{ 1444{
1231 if (mididev->out_jack) 1445 if (mididev->out_jack)
1232 mididev->out_jack->binded = 0; 1446 mididev->out_jack->bound = 0;
1233 if (mididev->in_jack) 1447 if (mididev->in_jack)
1234 mididev->in_jack->binded = 0; 1448 mididev->in_jack->bound = 0;
1235} 1449}
1236 1450
1237static usbd_status 1451static usbd_status
1238alloc_all_mididevs(struct umidi_softc *sc, int nmidi) 1452alloc_all_mididevs(struct umidi_softc *sc, int nmidi)
1239{ 1453{
1240 sc->sc_num_mididevs = nmidi; 1454 sc->sc_num_mididevs = nmidi;
1241 sc->sc_mididevs = kmem_zalloc(sizeof(*sc->sc_mididevs)*nmidi, KM_SLEEP); 1455 sc->sc_mididevs = kmem_zalloc(sizeof(*sc->sc_mididevs)*nmidi, KM_SLEEP);
1242 if (!sc->sc_mididevs) 1456 if (!sc->sc_mididevs)
1243 return USBD_NOMEM; 1457 return USBD_NOMEM;
1244 1458
1245 return USBD_NORMAL_COMPLETION; 1459 return USBD_NORMAL_COMPLETION;
1246} 1460}
1247 1461
1248static void 1462static void
1249free_all_mididevs(struct umidi_softc *sc) 1463free_all_mididevs(struct umidi_softc *sc)
1250{ 1464{
1251 if (sc->sc_mididevs) 1465 struct umidi_mididev *mididevs;
1252 kmem_free(sc->sc_mididevs, 1466 size_t len;
1253 sizeof(*sc->sc_mididevs)*sc->sc_num_mididevs); 1467
 1468 mutex_enter(&sc->sc_lock);
 1469 mididevs = sc->sc_mididevs;
 1470 if (mididevs)
 1471 len = sizeof(*sc->sc_mididevs )* sc->sc_num_mididevs;
 1472 sc->sc_mididevs = NULL;
1254 sc->sc_num_mididevs = 0; 1473 sc->sc_num_mididevs = 0;
 1474 mutex_exit(&sc->sc_lock);
 1475
 1476 if (mididevs)
 1477 kmem_free(mididevs, len);
1255} 1478}
1256 1479
1257static usbd_status 1480static usbd_status
1258attach_all_mididevs(struct umidi_softc *sc) 1481attach_all_mididevs(struct umidi_softc *sc)
1259{ 1482{
1260 usbd_status err; 1483 usbd_status err;
1261 int i; 1484 int i;
1262 1485
1263 if (sc->sc_mididevs) 1486 if (sc->sc_mididevs)
1264 for (i = 0; i < sc->sc_num_mididevs; i++) { 1487 for (i = 0; i < sc->sc_num_mididevs; i++) {
1265 err = attach_mididev(sc, &sc->sc_mididevs[i]); 1488 err = attach_mididev(sc, &sc->sc_mididevs[i]);
1266 if (err != USBD_NORMAL_COMPLETION) 1489 if (err != USBD_NORMAL_COMPLETION)
1267 return err; 1490 return err;
@@ -1316,38 +1539,38 @@ describe_mididev(struct umidi_mididev *m @@ -1316,38 +1539,38 @@ describe_mididev(struct umidi_mididev *m
1316 char in_label[16]; 1539 char in_label[16];
1317 char out_label[16]; 1540 char out_label[16];
1318 const char *unit_label; 1541 const char *unit_label;
1319 char *final_label; 1542 char *final_label;
1320 struct umidi_softc *sc; 1543 struct umidi_softc *sc;
1321 int show_ep_in; 1544 int show_ep_in;
1322 int show_ep_out; 1545 int show_ep_out;
1323 size_t len; 1546 size_t len;
1324  1547
1325 sc = md->sc; 1548 sc = md->sc;
1326 show_ep_in = sc-> sc_in_num_endpoints > 1 && !sc->cblnums_global; 1549 show_ep_in = sc-> sc_in_num_endpoints > 1 && !sc->cblnums_global;
1327 show_ep_out = sc->sc_out_num_endpoints > 1 && !sc->cblnums_global; 1550 show_ep_out = sc->sc_out_num_endpoints > 1 && !sc->cblnums_global;
1328  1551
1329 if ( NULL == md->in_jack ) 1552 if (NULL == md->in_jack)
1330 in_label[0] = '\0'; 1553 in_label[0] = '\0';
1331 else if ( show_ep_in ) 1554 else if (show_ep_in)
1332 snprintf(in_label, sizeof in_label, "<%d(%x) ", 1555 snprintf(in_label, sizeof in_label, "<%d(%x) ",
1333 md->in_jack->cable_number, md->in_jack->endpoint->addr); 1556 md->in_jack->cable_number, md->in_jack->endpoint->addr);
1334 else 1557 else
1335 snprintf(in_label, sizeof in_label, "<%d ", 1558 snprintf(in_label, sizeof in_label, "<%d ",
1336 md->in_jack->cable_number); 1559 md->in_jack->cable_number);
1337  1560
1338 if ( NULL == md->out_jack ) 1561 if (NULL == md->out_jack)
1339 out_label[0] = '\0'; 1562 out_label[0] = '\0';
1340 else if ( show_ep_out ) 1563 else if (show_ep_out)
1341 snprintf(out_label, sizeof out_label, ">%d(%x) ", 1564 snprintf(out_label, sizeof out_label, ">%d(%x) ",
1342 md->out_jack->cable_number, md->out_jack->endpoint->addr); 1565 md->out_jack->cable_number, md->out_jack->endpoint->addr);
1343 else 1566 else
1344 snprintf(out_label, sizeof out_label, ">%d ", 1567 snprintf(out_label, sizeof out_label, ">%d ",
1345 md->out_jack->cable_number); 1568 md->out_jack->cable_number);
1346 1569
1347 unit_label = device_xname(sc->sc_dev); 1570 unit_label = device_xname(sc->sc_dev);
1348  1571
1349 len = strlen(in_label) + strlen(out_label) + strlen(unit_label) + 4; 1572 len = strlen(in_label) + strlen(out_label) + strlen(unit_label) + 4;
1350  1573
1351 final_label = kmem_alloc(len, KM_SLEEP); 1574 final_label = kmem_alloc(len, KM_SLEEP);
1352  1575
1353 snprintf(final_label, len, "%s%son %s", 1576 snprintf(final_label, len, "%s%son %s",
@@ -1496,34 +1719,38 @@ if ((unsigned char)(p)[1]!=0xFE) \ @@ -1496,34 +1719,38 @@ if ((unsigned char)(p)[1]!=0xFE) \
1496 * as midi(4) hands us a complete message at a time, we'll never send one 1719 * as midi(4) hands us a complete message at a time, we'll never send one
1497 * in a dribble of short packets. 1720 * in a dribble of short packets.
1498 */ 1721 */
1499 1722
1500static int 1723static int
1501out_jack_output(struct umidi_jack *out_jack, u_char *src, int len, int cin) 1724out_jack_output(struct umidi_jack *out_jack, u_char *src, int len, int cin)
1502{ 1725{
1503 struct umidi_endpoint *ep = out_jack->endpoint; 1726 struct umidi_endpoint *ep = out_jack->endpoint;
1504 struct umidi_softc *sc = ep->sc; 1727 struct umidi_softc *sc = ep->sc;
1505 unsigned char *packet; 1728 unsigned char *packet;
1506 int plen; 1729 int plen;
1507 int poff; 1730 int poff;
1508 1731
 1732 KASSERT(mutex_owned(&sc->sc_lock));
 1733
1509 if (sc->sc_dying) 1734 if (sc->sc_dying)
1510 return EIO; 1735 return EIO;
1511 1736
1512 if (!out_jack->opened) 1737 if (!out_jack->opened)
1513 return ENODEV; /* XXX as it was, is this the right errno? */ 1738 return ENODEV; /* XXX as it was, is this the right errno? */
1514 1739
 1740 sc->sc_refcnt++;
 1741
1515#ifdef UMIDI_DEBUG 1742#ifdef UMIDI_DEBUG
1516 if ( umididebug >= 100 ) 1743 if (umididebug >= 100)
1517 microtime(&umidi_tv); 1744 microtime(&umidi_tv);
1518#endif 1745#endif
1519 DPRINTFN(100, ("umidi out: %"PRIu64".%06"PRIu64"s ep=%p cn=%d len=%d cin=%#x\n", 1746 DPRINTFN(100, ("umidi out: %"PRIu64".%06"PRIu64"s ep=%p cn=%d len=%d cin=%#x\n",
1520 umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec, 1747 umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec,
1521 ep, out_jack->cable_number, len, cin)); 1748 ep, out_jack->cable_number, len, cin));
1522  1749
1523 packet = *ep->next_slot++; 1750 packet = *ep->next_slot++;
1524 KASSERT(ep->buffer_size >= 1751 KASSERT(ep->buffer_size >=
1525 (ep->next_slot - ep->buffer) * sizeof *ep->buffer); 1752 (ep->next_slot - ep->buffer) * sizeof *ep->buffer);
1526 memset(packet, 0, UMIDI_PACKET_SIZE); 1753 memset(packet, 0, UMIDI_PACKET_SIZE);
1527 if (UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE)) { 1754 if (UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE)) {
1528 if (NULL != out_jack->midiman_ppkt) { /* fill out a prev pkt */ 1755 if (NULL != out_jack->midiman_ppkt) { /* fill out a prev pkt */
1529 poff = 0x0f & (out_jack->midiman_ppkt[3]); 1756 poff = 0x0f & (out_jack->midiman_ppkt[3]);
@@ -1546,37 +1773,40 @@ out_jack_output(struct umidi_jack *out_j @@ -1546,37 +1773,40 @@ out_jack_output(struct umidi_jack *out_j
1546 memcpy(packet, src, len); 1773 memcpy(packet, src, len);
1547 packet[3] = MIX_CN_CIN(out_jack->cable_number, len); 1774 packet[3] = MIX_CN_CIN(out_jack->cable_number, len);
1548 DPR_PACKET(out, sc, packet); 1775 DPR_PACKET(out, sc, packet);
1549 if (len < 3) 1776 if (len < 3)
1550 out_jack->midiman_ppkt = packet; 1777 out_jack->midiman_ppkt = packet;
1551 } 1778 }
1552 } else { /* the nice simple USB class-compliant case */ 1779 } else { /* the nice simple USB class-compliant case */
1553 packet[0] = MIX_CN_CIN(out_jack->cable_number, cin); 1780 packet[0] = MIX_CN_CIN(out_jack->cable_number, cin);
1554 memcpy(packet+1, src, len); 1781 memcpy(packet+1, src, len);
1555 DPR_PACKET(out, sc, packet); 1782 DPR_PACKET(out, sc, packet);
1556 } 1783 }
1557 ep->next_schedule |= 1<<(out_jack->cable_number); 1784 ep->next_schedule |= 1<<(out_jack->cable_number);
1558 ++ ep->num_scheduled; 1785 ++ ep->num_scheduled;
1559 if ( !ep->armed && !ep->soliciting ) { 1786 if (!ep->armed && !ep->soliciting) {
1560 /* 1787 /*
1561 * It would be bad to call out_solicit directly here (the 1788 * It would be bad to call out_solicit directly here (the
1562 * caller need not be reentrant) but a soft interrupt allows 1789 * caller need not be reentrant) but a soft interrupt allows
1563 * solicit to run immediately the caller exits its critical 1790 * solicit to run immediately the caller exits its critical
1564 * section, and if the caller has more to write we can get it 1791 * section, and if the caller has more to write we can get it
1565 * before starting the USB transfer, and send a longer one. 1792 * before starting the USB transfer, and send a longer one.
1566 */ 1793 */
1567 ep->soliciting = 1; 1794 ep->soliciting = 1;
1568 softint_schedule(ep->solicit_cookie); 1795 softint_schedule(ep->solicit_cookie);
1569 } 1796 }
 1797
 1798 if (--sc->sc_refcnt < 0)
 1799 usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv);
1570  1800
1571 return 0; 1801 return 0;
1572} 1802}
1573 1803
1574static void 1804static void
1575in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 1805in_intr(usbd_xfer_handle xfer, usbd_private_handle priv,
1576 usbd_status status) 1806 usbd_status status)
1577{ 1807{
1578 int cn, len, i; 1808 int cn, len, i;
1579 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1809 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1580 struct umidi_softc *sc = ep->sc; 1810 struct umidi_softc *sc = ep->sc;
1581 struct umidi_jack *jack; 1811 struct umidi_jack *jack;
1582 unsigned char *packet; 1812 unsigned char *packet;
@@ -1614,27 +1844,27 @@ in_intr(usbd_xfer_handle xfer, usbd_priv @@ -1614,27 +1844,27 @@ in_intr(usbd_xfer_handle xfer, usbd_priv
1614 } 1844 }
1615 /* 0 <= cn <= 15 by inspection of above code */ 1845 /* 0 <= cn <= 15 by inspection of above code */
1616 if (!(jack = ep->jacks[cn]) || cn != jack->cable_number) { 1846 if (!(jack = ep->jacks[cn]) || cn != jack->cable_number) {
1617 DPRINTF(("%s: stray input endpoint %p cable %d len %d: " 1847 DPRINTF(("%s: stray input endpoint %p cable %d len %d: "
1618 "%02X %02X %02X (try CN_SEQ quirk?)\n", 1848 "%02X %02X %02X (try CN_SEQ quirk?)\n",
1619 device_xname(ep->sc->sc_dev), ep, cn, len, 1849 device_xname(ep->sc->sc_dev), ep, cn, len,
1620 (unsigned)data[0], 1850 (unsigned)data[0],
1621 (unsigned)data[1], 1851 (unsigned)data[1],
1622 (unsigned)data[2])); 1852 (unsigned)data[2]));
1623 mutex_exit(&sc->sc_lock); 1853 mutex_exit(&sc->sc_lock);
1624 return; 1854 return;
1625 } 1855 }
1626 1856
1627 if (!jack->binded || !jack->opened) 1857 if (!jack->bound || !jack->opened)
1628 continue; 1858 continue;
1629 1859
1630 DPRINTFN(500,("%s: input endpoint %p cable %d len %d: " 1860 DPRINTFN(500,("%s: input endpoint %p cable %d len %d: "
1631 "%02X %02X %02X\n", 1861 "%02X %02X %02X\n",
1632 device_xname(ep->sc->sc_dev), ep, cn, len, 1862 device_xname(ep->sc->sc_dev), ep, cn, len,
1633 (unsigned)data[0], 1863 (unsigned)data[0],
1634 (unsigned)data[1], 1864 (unsigned)data[1],
1635 (unsigned)data[2])); 1865 (unsigned)data[2]));
1636 1866
1637 if (jack->u.in.intr) { 1867 if (jack->u.in.intr) {
1638 for (i = 0; i < len; i++) { 1868 for (i = 0; i < len; i++) {
1639 (*jack->u.in.intr)(jack->arg, data[i]); 1869 (*jack->u.in.intr)(jack->arg, data[i]);
1640 } 1870 }
@@ -1649,31 +1879,31 @@ in_intr(usbd_xfer_handle xfer, usbd_priv @@ -1649,31 +1879,31 @@ in_intr(usbd_xfer_handle xfer, usbd_priv
1649static void 1879static void
1650out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, 1880out_intr(usbd_xfer_handle xfer, usbd_private_handle priv,
1651 usbd_status status) 1881 usbd_status status)
1652{ 1882{
1653 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; 1883 struct umidi_endpoint *ep = (struct umidi_endpoint *)priv;
1654 struct umidi_softc *sc = ep->sc; 1884 struct umidi_softc *sc = ep->sc;
1655 u_int32_t count; 1885 u_int32_t count;
1656 1886
1657 if (sc->sc_dying) 1887 if (sc->sc_dying)
1658 return; 1888 return;
1659 1889
1660 mutex_enter(&sc->sc_lock); 1890 mutex_enter(&sc->sc_lock);
1661#ifdef UMIDI_DEBUG 1891#ifdef UMIDI_DEBUG
1662 if ( umididebug >= 200 ) 1892 if (umididebug >= 200)
1663 microtime(&umidi_tv); 1893 microtime(&umidi_tv);
1664#endif 1894#endif
1665 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); 1895 usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL);
1666 if ( 0 == count % UMIDI_PACKET_SIZE ) { 1896 if (0 == count % UMIDI_PACKET_SIZE) {
1667 DPRINTFN(200,("%s: %"PRIu64".%06"PRIu64"s out ep %p xfer length %u\n", 1897 DPRINTFN(200,("%s: %"PRIu64".%06"PRIu64"s out ep %p xfer length %u\n",
1668 device_xname(ep->sc->sc_dev), 1898 device_xname(ep->sc->sc_dev),
1669 umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec, ep, count)); 1899 umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec, ep, count));
1670 } else { 1900 } else {
1671 DPRINTF(("%s: output endpoint %p odd transfer length %u\n", 1901 DPRINTF(("%s: output endpoint %p odd transfer length %u\n",
1672 device_xname(ep->sc->sc_dev), ep, count)); 1902 device_xname(ep->sc->sc_dev), ep, count));
1673 } 1903 }
1674 count /= UMIDI_PACKET_SIZE; 1904 count /= UMIDI_PACKET_SIZE;
1675  1905
1676 /* 1906 /*
1677 * If while the transfer was pending we buffered any new messages, 1907 * If while the transfer was pending we buffered any new messages,
1678 * move them to the start of the buffer. 1908 * move them to the start of the buffer.
1679 */ 1909 */
@@ -1751,28 +1981,35 @@ out_solicit_locked(void *arg) @@ -1751,28 +1981,35 @@ out_solicit_locked(void *arg)
1751 1981
1752 --which; /* now 1s below mask - count 1s to get index */ 1982 --which; /* now 1s below mask - count 1s to get index */
1753 which -= ((which >> 1) & 0x5555);/* SWAR credit aggregate.org */ 1983 which -= ((which >> 1) & 0x5555);/* SWAR credit aggregate.org */
1754 which = (((which >> 2) & 0x3333) + (which & 0x3333)); 1984 which = (((which >> 2) & 0x3333) + (which & 0x3333));
1755 which = (((which >> 4) + which) & 0x0f0f); 1985 which = (((which >> 4) + which) & 0x0f0f);
1756 which += (which >> 8); 1986 which += (which >> 8);
1757 which &= 0x1f; /* the bit index a/k/a jack number */ 1987 which &= 0x1f; /* the bit index a/k/a jack number */
1758  1988
1759 jack = ep->jacks[which]; 1989 jack = ep->jacks[which];
1760 if (jack->u.out.intr) 1990 if (jack->u.out.intr)
1761 (*jack->u.out.intr)(jack->arg); 1991 (*jack->u.out.intr)(jack->arg);
1762 } 1992 }
1763 /* intr lock held at loop exit */ 1993 /* intr lock held at loop exit */
1764 if (!ep->armed && ep->next_slot > ep->buffer) 1994 if (!ep->armed && ep->next_slot > ep->buffer) {
 1995 /*
 1996 * Can't hold the interrupt lock while calling into USB,
 1997 * but we can safely drop it here.
 1998 */
 1999 mutex_exit(&ep->sc->sc_lock);
1765 ep->armed = (USBD_IN_PROGRESS == start_output_transfer(ep)); 2000 ep->armed = (USBD_IN_PROGRESS == start_output_transfer(ep));
 2001 mutex_enter(&ep->sc->sc_lock);
 2002 }
1766 ep->soliciting = 0; 2003 ep->soliciting = 0;
1767} 2004}
1768 2005
1769/* Entry point for the softintr. */ 2006/* Entry point for the softintr. */
1770static void 2007static void
1771out_solicit(void *arg) 2008out_solicit(void *arg)
1772{ 2009{
1773 struct umidi_endpoint *ep = arg; 2010 struct umidi_endpoint *ep = arg;
1774 struct umidi_softc *sc = ep->sc; 2011 struct umidi_softc *sc = ep->sc;
1775 2012
1776 mutex_enter(&sc->sc_lock); 2013 mutex_enter(&sc->sc_lock);
1777 out_solicit_locked(arg); 2014 out_solicit_locked(arg);
1778 mutex_exit(&sc->sc_lock); 2015 mutex_exit(&sc->sc_lock);

cvs diff -r1.18 -r1.18.14.1 src/sys/dev/usb/umidi_quirks.c (expand / switch to unified diff)

--- src/sys/dev/usb/umidi_quirks.c 2012/05/18 07:52:54 1.18
+++ src/sys/dev/usb/umidi_quirks.c 2015/01/11 14:13:25 1.18.14.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: umidi_quirks.c,v 1.18 2012/05/18 07:52:54 jdc Exp $ */ 1/* $NetBSD: umidi_quirks.c,v 1.18.14.1 2015/01/11 14:13:25 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org). 8 * by Takuya SHIOZAKI (tshiozak@NetBSD.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,50 +20,48 @@ @@ -20,50 +20,48 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.18 2012/05/18 07:52:54 jdc Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.18.14.1 2015/01/11 14:13:25 martin Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/device.h> 39#include <sys/device.h>
40#include <sys/ioctl.h> 40#include <sys/ioctl.h>
41#include <sys/conf.h> 41#include <sys/conf.h>
42#include <sys/file.h> 42#include <sys/file.h>
43#include <sys/select.h> 43#include <sys/select.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/vnode.h> 45#include <sys/vnode.h>
46#include <sys/poll.h> 46#include <sys/poll.h>
47 47
48#include <dev/usb/usb.h> 48#include <dev/usb/usb.h>
49#include <dev/usb/usbdi.h> 49#include <dev/usb/usbdi.h>
50#include <dev/usb/usbdi_util.h> 50#include <dev/usb/usbdi_util.h>
51 51
52#include <dev/auconv.h> 52#include <dev/auconv.h>
53#include <dev/usb/usbdevs.h> 53#include <dev/usb/usbdevs.h>
54#include <dev/usb/uaudioreg.h> 54#include <dev/usb/uaudioreg.h>
55#include <dev/usb/umidireg.h> 
56#include <dev/usb/umidivar.h> 
57#include <dev/usb/umidi_quirks.h> 55#include <dev/usb/umidi_quirks.h>
58 56
59/* 57/*
60 * quirk codes for UMIDI 58 * quirk codes for UMIDI
61 */ 59 */
62 60
63#ifdef UMIDIQUIRK_DEBUG 61#ifdef UMIDIQUIRK_DEBUG
64#define DPRINTF(x) if (umidiquirkdebug) printf x 62#define DPRINTF(x) if (umidiquirkdebug) printf x
65#define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x 63#define DPRINTFN(n,x) if (umidiquirkdebug >= (n)) printf x
66int umidiquirkdebug = 1; 64int umidiquirkdebug = 1;
67#else 65#else
68#define DPRINTF(x) 66#define DPRINTF(x)
69#define DPRINTFN(n,x) 67#define DPRINTFN(n,x)

File Deleted: src/sys/dev/usb/Attic/umidireg.h

File Deleted: src/sys/dev/usb/Attic/umidivar.h