Index: arch/macppc/dev/awacs.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/awacs.c,v retrieving revision 1.40 diff -p -r1.40 awacs.c *** arch/macppc/dev/awacs.c 20 Feb 2011 07:40:24 -0000 1.40 --- arch/macppc/dev/awacs.c 21 Nov 2011 23:56:31 -0000 *************** __KERNEL_RCSID(0, "$NetBSD: awacs.c,v 1. *** 32,41 **** #include #include #include - #include #include #include #include #include #include --- 32,42 ---- #include #include #include #include #include #include + #include + #include #include #include *************** struct awacs_softc { *** 85,91 **** int vol_l, vol_r; int sc_bass, sc_treble; lwp_t *sc_thread; ! int sc_event; int sc_output_wanted; int sc_need_parallel_output; #if NSGSMIX > 0 --- 86,92 ---- int vol_l, vol_r; int sc_bass, sc_treble; lwp_t *sc_thread; ! kcondvar_t sc_event; int sc_output_wanted; int sc_need_parallel_output; #if NSGSMIX > 0 *************** struct awacs_softc { *** 108,113 **** --- 109,117 ---- #define AWACS_NFORMATS 2 struct audio_format sc_formats[AWACS_NFORMATS]; + + kmutex_t sc_lock; + kmutex_t sc_intr_lock; }; static int awacs_match(device_t, struct cfdata *, void *); *************** static int awacs_query_devinfo(void *, m *** 134,139 **** --- 138,144 ---- static size_t awacs_round_buffersize(void *, int, size_t); static paddr_t awacs_mappage(void *, void *, off_t, int); static int awacs_get_props(void *); + static void awacs_get_locks(void *, kmutex_t **, kmutex_t **); static inline u_int awacs_read_reg(struct awacs_softc *, int); static inline void awacs_write_reg(struct awacs_softc *, int, int); *************** const struct audio_hw_if awacs_hw_if = { *** 185,190 **** --- 190,197 ---- awacs_trigger_output, awacs_trigger_input, NULL, + NULL, + awacs_get_locks, }; struct audio_device awacs_device = { *************** awacs_attach(device_t parent, device_t s *** 374,381 **** } intr_establish(cirq, cirq_type, IPL_BIO, awacs_status_intr, sc); ! intr_establish(oirq, oirq_type, IPL_AUDIO, awacs_intr, sc); ! intr_establish(iirq, iirq_type, IPL_AUDIO, awacs_intr, sc); /* check if the chip is a screamer */ sc->sc_screamer = (of_compatible(ca->ca_node, screamer) != -1); --- 381,393 ---- } intr_establish(cirq, cirq_type, IPL_BIO, awacs_status_intr, sc); ! intr_establish(oirq, oirq_type, IPL_SCHED, awacs_intr, sc); ! intr_establish(iirq, iirq_type, IPL_SCHED, awacs_intr, sc); ! ! mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); ! mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); ! ! cv_init(&sc->sc_event, "awacs_wait"); /* check if the chip is a screamer */ sc->sc_screamer = (of_compatible(ca->ca_node, screamer) != -1); *************** awacs_setup_sgsmix(device_t cookie) *** 570,580 **** sc->sc_codecctl1 &= ~AWACS_MUTE_HEADPHONE; awacs_write_codec(sc, sc->sc_codecctl1); awacs_select_output(sc, sc->sc_output_mask); awacs_set_volume(sc, sc->vol_l, sc->vol_r); awacs_set_bass(sc, 128); awacs_set_treble(sc, 128); ! wakeup(&sc->sc_event); #endif return 0; } --- 582,594 ---- sc->sc_codecctl1 &= ~AWACS_MUTE_HEADPHONE; awacs_write_codec(sc, sc->sc_codecctl1); + mutex_enter(&sc->sc_intr_lock); awacs_select_output(sc, sc->sc_output_mask); awacs_set_volume(sc, sc->vol_l, sc->vol_r); awacs_set_bass(sc, 128); awacs_set_treble(sc, 128); ! cv_signal(&sc->sc_event); ! mutex_exit(&sc->sc_intr_lock); #endif return 0; } *************** awacs_intr(void *v) *** 618,623 **** --- 632,638 ---- int status; sc = v; + mutex_spin_enter(&sc->sc_intr_lock); cmd = sc->sc_odmacmd; count = sc->sc_opages; /* Fill used buffer(s). */ *************** awacs_intr(void *v) *** 632,637 **** --- 647,653 ---- } cmd++; } + mutex_spin_exit(&sc->sc_intr_lock); return 1; } *************** awacs_set_port(void *h, mixer_ctrl_t *mc *** 838,848 **** --- 854,868 ---- /* No change necessary? */ if (mc->un.mask == sc->sc_output_mask) return 0; + mutex_enter(&sc->sc_intr_lock); awacs_select_output(sc, mc->un.mask); + mutex_exit(&sc->sc_intr_lock); return 0; case AWACS_VOL_MASTER: + mutex_enter(&sc->sc_intr_lock); awacs_set_volume(sc, l, r); + mutex_exit(&sc->sc_intr_lock); return 0; case AWACS_INPUT_SELECT: *************** awacs_set_port(void *h, mixer_ctrl_t *mc *** 883,893 **** --- 903,917 ---- #if NSGSMIX > 0 case AWACS_BASS: + mutex_enter(&sc->sc_intr_lock); awacs_set_bass(sc, l); + mutex_exit(&sc->sc_intr_lock); return 0; case AWACS_TREBLE: + mutex_enter(&sc->sc_intr_lock); awacs_set_treble(sc, l); + mutex_exit(&sc->sc_intr_lock); return 0; #endif } *************** awacs_trigger_input(void *h, void *start *** 1142,1147 **** --- 1166,1180 ---- DPRINTF("awacs_trigger_input called\n"); return 1; } + + static void + awacs_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) + { + struct awacs_softc *sc = opaque; + + *intr = &sc->sc_intr_lock; + *thread = &sc->sc_lock; + } static void awacs_select_output(struct awacs_softc *sc, int mask) *************** awacs_status_intr(void *cookie) *** 1369,1382 **** struct awacs_softc *sc = cookie; int mask; mask = awacs_check_headphones(sc) ? OUTPUT_HEADPHONES : OUTPUT_SPEAKER; if (mask != sc->sc_output_mask) { sc->sc_output_wanted = mask; ! wakeup(&sc->sc_event); } /* clear the interrupt */ awacs_write_reg(sc, AWACS_SOUND_CTRL, sc->sc_soundctl | AWACS_PORTCHG); return 1; } --- 1402,1417 ---- struct awacs_softc *sc = cookie; int mask; + mutex_exit(&sc->sc_intr_lock); mask = awacs_check_headphones(sc) ? OUTPUT_HEADPHONES : OUTPUT_SPEAKER; if (mask != sc->sc_output_mask) { sc->sc_output_wanted = mask; ! cv_signal(&sc->sc_event); } /* clear the interrupt */ awacs_write_reg(sc, AWACS_SOUND_CTRL, sc->sc_soundctl | AWACS_PORTCHG); + mutex_exit(&sc->sc_intr_lock); return 1; } *************** awacs_thread(void *cookie) *** 1386,1392 **** struct awacs_softc *sc = cookie; while (1) { ! tsleep(&sc->sc_event, PWAIT, "awacs_wait", hz); if (sc->sc_output_wanted == sc->sc_output_mask) continue; --- 1421,1428 ---- struct awacs_softc *sc = cookie; while (1) { ! mutex_enter(&sc->sc_intr_lock); ! cv_timedwait(&sc->sc_event, &sc->sc_intr_lock, hz); if (sc->sc_output_wanted == sc->sc_output_mask) continue; *************** awacs_thread(void *cookie) *** 1394,1398 **** --- 1430,1435 ---- DPRINTF("%s: switching to %s\n", device_xname(sc->sc_dev), (sc->sc_output_wanted & OUTPUT_SPEAKER) ? "speaker" : "headphones"); + mutex_exit(&sc->sc_intr_lock); } } Index: arch/macppc/dev/snapper.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/snapper.c,v retrieving revision 1.36 diff -p -r1.36 snapper.c *** arch/macppc/dev/snapper.c 12 Nov 2010 12:26:29 -0000 1.36 --- arch/macppc/dev/snapper.c 21 Nov 2011 23:56:31 -0000 *************** struct snapper_softc { *** 111,116 **** --- 111,119 ---- unsigned char dbdma_cmdspace[sizeof(struct dbdma_command) * 40 + 15]; struct dbdma_command *sc_odmacmd; struct dbdma_command *sc_idmacmd; + + kmutex_t sc_lock; + kmutex_t sc_intr_lock; }; static int snapper_match(device_t, struct cfdata *, void *); *************** static int snapper_trigger_output(void * *** 134,139 **** --- 137,143 ---- void *, const audio_params_t *); static int snapper_trigger_input(void *, void *, void *, int, void (*)(void *), void *, const audio_params_t *); + static void snapper_get_locks(void *, kmutex_t **, kmutex_t **); static void snapper_set_volume(struct snapper_softc *, u_int, u_int); static int snapper_set_rate(struct snapper_softc *); static void snapper_set_treble(struct snapper_softc *, u_int); *************** struct snapper_codecvar { *** 161,167 **** }; static stream_filter_t *snapper_filter_factory ! (int (*)(stream_fetcher_t *, audio_stream_t *, int)); static void snapper_filter_dtor(stream_filter_t *); /* XXX We can't access the hw device softc from our audio --- 165,171 ---- }; static stream_filter_t *snapper_filter_factory ! (int (*)(struct audio_softc *sc, stream_fetcher_t *, audio_stream_t *, int)); static void snapper_filter_dtor(stream_filter_t *); /* XXX We can't access the hw device softc from our audio *************** static u_int snapper_vol_l = 128, snappe *** 172,178 **** /* XXX why doesn't auconv define this? */ #define DEFINE_FILTER(name) \ static int \ ! name##_fetch_to(stream_fetcher_t *, audio_stream_t *, int); \ stream_filter_t * name(struct audio_softc *, \ const audio_params_t *, const audio_params_t *); \ stream_filter_t * \ --- 176,182 ---- /* XXX why doesn't auconv define this? */ #define DEFINE_FILTER(name) \ static int \ ! name##_fetch_to(struct audio_softc *, stream_fetcher_t *, audio_stream_t *, int); \ stream_filter_t * name(struct audio_softc *, \ const audio_params_t *, const audio_params_t *); \ stream_filter_t * \ *************** name(struct audio_softc *sc, const audio *** 182,188 **** return snapper_filter_factory(name##_fetch_to); \ } \ static int \ ! name##_fetch_to(stream_fetcher_t *self, audio_stream_t *dst, int max_used) DEFINE_FILTER(snapper_volume) { --- 186,192 ---- return snapper_filter_factory(name##_fetch_to); \ } \ static int \ ! name##_fetch_to(struct audio_softc *sc, stream_fetcher_t *self, audio_stream_t *dst, int max_used) DEFINE_FILTER(snapper_volume) { *************** DEFINE_FILTER(snapper_volume) *** 193,199 **** this = (stream_filter_t *)self; max_used = (max_used + 1) & ~1; ! if ((err = this->prev->fetch_to(this->prev, this->src, max_used))) return err; m = (dst->end - dst->start) & ~1; m = min(m, max_used); --- 197,203 ---- this = (stream_filter_t *)self; max_used = (max_used + 1) & ~1; ! if ((err = this->prev->fetch_to(sc, this->prev, this->src, max_used))) return err; m = (dst->end - dst->start) & ~1; m = min(m, max_used); *************** DEFINE_FILTER(snapper_fixphase) *** 226,232 **** panic("snapper_fixphase"); #endif max_used = (max_used + 3) & ~2; ! if ((err = this->prev->fetch_to(this->prev, this->src, max_used))) return err; /* work in stereo frames (4 bytes) */ --- 230,236 ---- panic("snapper_fixphase"); #endif max_used = (max_used + 3) & ~2; ! if ((err = this->prev->fetch_to(sc, this->prev, this->src, max_used))) return err; /* work in stereo frames (4 bytes) */ *************** DEFINE_FILTER(snapper_fixphase) *** 245,251 **** } static stream_filter_t * ! snapper_filter_factory(int (*fetch_to)(stream_fetcher_t *, audio_stream_t *, int)) { struct snapper_codecvar *this; --- 249,255 ---- } static stream_filter_t * ! snapper_filter_factory(int (*fetch_to)(struct audio_softc *sc, stream_fetcher_t *, audio_stream_t *, int)) { struct snapper_codecvar *this; *************** const struct audio_hw_if snapper_hw_if = *** 299,305 **** snapper_trigger_output, snapper_trigger_input, NULL, ! NULL }; struct audio_device snapper_device = { --- 303,310 ---- snapper_trigger_output, snapper_trigger_input, NULL, ! NULL, ! snapper_get_locks, }; struct audio_device snapper_device = { *************** snapper_attach(device_t parent, device_t *** 782,793 **** oirq_type = intr[3] ? IST_LEVEL : IST_EDGE; iirq_type = intr[5] ? IST_LEVEL : IST_EDGE; ! /* intr_establish(cirq, cirq_type, IPL_AUDIO, snapper_intr, sc); */ ! intr_establish(oirq, oirq_type, IPL_AUDIO, snapper_intr, sc); ! intr_establish(iirq, iirq_type, IPL_AUDIO, snapper_intr, sc); aprint_normal(": irq %d,%d,%d\n", cirq, oirq, iirq); /* PMF event handler */ pmf_device_register(sc->sc_dev, NULL, NULL); --- 787,801 ---- oirq_type = intr[3] ? IST_LEVEL : IST_EDGE; iirq_type = intr[5] ? IST_LEVEL : IST_EDGE; ! /* intr_establish(cirq, cirq_type, IPL_BIO, snapper_intr, sc); */ ! intr_establish(oirq, oirq_type, IPL_SCHED, snapper_intr, sc); ! intr_establish(iirq, iirq_type, IPL_SCHED, snapper_intr, sc); aprint_normal(": irq %d,%d,%d\n", cirq, oirq, iirq); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); + /* PMF event handler */ pmf_device_register(sc->sc_dev, NULL, NULL); *************** snapper_intr(void *v) *** 847,852 **** --- 855,861 ---- int status; sc = v; + mutex_spin_enter(&sc->sc_intr_lock); cmd = sc->sc_odmacmd; count = sc->sc_opages; /* Fill used buffer(s). */ *************** snapper_intr(void *v) *** 873,879 **** } cmd++; } ! return 1; } --- 882,888 ---- } cmd++; } ! mutex_spin_exit(&sc->sc_intr_lock); return 1; } *************** snapper_trigger_input(void *h, void *sta *** 1461,1466 **** --- 1470,1484 ---- } static void + snapper_get_locks(void *opaque, kmutex_t **intr, kmutex_t **thread) + { + struct snapper_softc *sc = opaque; + + *intr = &sc->sc_intr_lock; + *thread = &sc->sc_lock; + } + + static void snapper_set_volume(struct snapper_softc *sc, u_int left, u_int right) { u_char regs[6]; *************** snapper_init(struct snapper_softc *sc, i *** 2098,2104 **** DPRINTF(" audio-hw-reset %p\n", audio_hw_reset); if (headphone_detect_intr != -1) ! intr_establish(headphone_detect_intr, IST_EDGE, IPL_AUDIO, snapper_cint, sc); sc->sc_rate = 44100; /* default rate */ --- 2116,2122 ---- DPRINTF(" audio-hw-reset %p\n", audio_hw_reset); if (headphone_detect_intr != -1) ! intr_establish(headphone_detect_intr, IST_EDGE, IPL_SCHED, snapper_cint, sc); sc->sc_rate = 44100; /* default rate */