Page MenuHomeFreeBSD

D28032.id81864.diff
No OneTemporary

D28032.id81864.diff

Index: sys/dev/sound/pcm/channel.h
===================================================================
--- sys/dev/sound/pcm/channel.h
+++ sys/dev/sound/pcm/channel.h
@@ -258,6 +258,7 @@
int chn_reinit(struct pcm_channel *c);
int chn_write(struct pcm_channel *c, struct uio *buf);
int chn_read(struct pcm_channel *c, struct uio *buf);
+u_int32_t chn_prepare(struct pcm_channel *c, int enable);
u_int32_t chn_start(struct pcm_channel *c, int force);
int chn_sync(struct pcm_channel *c, int threshold);
int chn_flush(struct pcm_channel *c);
@@ -367,6 +368,7 @@
#define CHN_F_VCHAN_ADAPTIVE 0x00008000 /* adaptive format/rate selection */
#define CHN_F_VCHAN_DYNAMIC (CHN_F_VCHAN_PASSTHROUGH | CHN_F_VCHAN_ADAPTIVE)
+#define CHN_F_READY 0x01000000
#define CHN_F_VIRTUAL 0x10000000 /* not backed by hardware */
#define CHN_F_BITPERFECT 0x20000000 /* un-cooked, Heh.. */
#define CHN_F_PASSTHROUGH 0x40000000 /* passthrough re-config */
Index: sys/dev/sound/pcm/channel.c
===================================================================
--- sys/dev/sound/pcm/channel.c
+++ sys/dev/sound/pcm/channel.c
@@ -670,6 +670,15 @@
CHN_UNLOCK(c);
}
+u_int32_t
+chn_prepare(struct pcm_channel *c, int enable)
+{
+ int ret = 0;
+
+ ret = CHANNEL_PREPARE(c->methods, c->devinfo, enable);
+ return ret;
+}
+
u_int32_t
chn_start(struct pcm_channel *c, int force)
{
Index: sys/dev/sound/pcm/channel_if.m
===================================================================
--- sys/dev/sound/pcm/channel_if.m
+++ sys/dev/sound/pcm/channel_if.m
@@ -153,6 +153,12 @@
int go;
};
+METHOD int prepare {
+ kobj_t obj;
+ void *data;
+ int go;
+};
+
METHOD u_int32_t getptr {
kobj_t obj;
void *data;
Index: sys/dev/sound/pcm/dsp.c
===================================================================
--- sys/dev/sound/pcm/dsp.c
+++ sys/dev/sound/pcm/dsp.c
@@ -1085,7 +1085,6 @@
ret = 0;
xcmd = 0;
chn = NULL;
-
if (IOCGROUP(cmd) == 'M') {
if (cmd == OSS_GETVERSION) {
*arg_i = SOUND_VERSION;
@@ -1734,28 +1733,34 @@
case SNDCTL_DSP_SETTRIGGER:
if (rdch) {
- CHN_LOCK(rdch);
- rdch->flags &= ~CHN_F_NOTRIGGER;
- if (*arg_i & PCM_ENABLE_INPUT)
+ if (*arg_i & PCM_ENABLE_INPUT) {
+ chn_prepare(rdch, 1);
+ CHN_LOCK(rdch);
chn_start(rdch, 1);
- else {
+ rdch->flags &= ~CHN_F_NOTRIGGER;
+ CHN_UNLOCK(rdch);
+ } else {
+ CHN_LOCK(rdch);
chn_abort(rdch);
chn_resetbuf(rdch);
rdch->flags |= CHN_F_NOTRIGGER;
+ CHN_UNLOCK(rdch);
}
- CHN_UNLOCK(rdch);
}
if (wrch) {
- CHN_LOCK(wrch);
- wrch->flags &= ~CHN_F_NOTRIGGER;
- if (*arg_i & PCM_ENABLE_OUTPUT)
+ if (*arg_i & PCM_ENABLE_OUTPUT) {
+ chn_prepare(wrch, 1);
+ CHN_LOCK(wrch);
chn_start(wrch, 1);
- else {
+ wrch->flags &= ~CHN_F_NOTRIGGER;
+ CHN_UNLOCK(wrch);
+ } else {
+ CHN_LOCK(wrch);
chn_abort(wrch);
chn_resetbuf(wrch);
wrch->flags |= CHN_F_NOTRIGGER;
+ CHN_UNLOCK(wrch);
}
- CHN_UNLOCK(wrch);
}
break;
@@ -1789,11 +1794,17 @@
case SNDCTL_DSP_POST:
if (wrch) {
+ chn_prepare(wrch, 1);
CHN_LOCK(wrch);
wrch->flags &= ~CHN_F_NOTRIGGER;
chn_start(wrch, 1);
CHN_UNLOCK(wrch);
}
+#if 0
+ if (rdch) {
+ chn_prepare(rdch, 1);
+ }
+#endif
break;
case SNDCTL_DSP_SETDUPLEX:
Index: sys/dev/sound/pcm/vchan.c
===================================================================
--- sys/dev/sound/pcm/vchan.c
+++ sys/dev/sound/pcm/vchan.c
@@ -184,6 +184,21 @@
return (ret);
}
+static int
+vchan_prepare(kobj_t obj, void *data, int go)
+{
+ struct vchan_info *info;
+ struct pcm_channel *c, *p;
+
+ info = data;
+ c = info->channel;
+ p = c->parentchannel;
+
+ if (p)
+ chn_prepare(p, go);
+ return 1;
+}
+
static struct pcmchan_caps *
vchan_getcaps(kobj_t obj, void *data)
{
@@ -244,6 +259,7 @@
KOBJMETHOD(channel_setformat, vchan_setformat),
KOBJMETHOD(channel_setspeed, vchan_setspeed),
KOBJMETHOD(channel_trigger, vchan_trigger),
+ KOBJMETHOD(channel_prepare, vchan_prepare),
KOBJMETHOD(channel_getcaps, vchan_getcaps),
KOBJMETHOD(channel_getmatrix, vchan_getmatrix),
KOBJMETHOD_END
Index: sys/dev/sound/usb/uaudio.h
===================================================================
--- sys/dev/sound/usb/uaudio.h
+++ sys/dev/sound/usb/uaudio.h
@@ -56,6 +56,7 @@
uint32_t format);
extern int uaudio_chan_set_param_format(struct uaudio_chan *ch,
uint32_t format);
+extern void uaudio_chan_prepare(struct uaudio_chan *ch, int enable);
extern void uaudio_chan_start(struct uaudio_chan *ch);
extern void uaudio_chan_stop(struct uaudio_chan *ch);
extern int uaudio_mixer_init_sub(struct uaudio_softc *, struct snd_mixer *);
Index: sys/dev/sound/usb/uaudio.c
===================================================================
--- sys/dev/sound/usb/uaudio.c
+++ sys/dev/sound/usb/uaudio.c
@@ -267,6 +267,7 @@
#define CHAN_OP_DRAIN 3
uint8_t iface_index;
+ uint8_t cur_alt_index;
};
#define UMIDI_EMB_JACK_MAX 16 /* units */
@@ -1342,6 +1343,8 @@
goto error;
}
+ chan->cur_alt_index = (operation == CHAN_OP_START) ?
+ chan_alt->iface_alt_index : 0;
/*
* Only set the sample rate if the channel reports that it
* supports the frequency control.
@@ -2775,6 +2778,22 @@
rchan->running == 0);
}
+void
+uaudio_chan_prepare(struct uaudio_chan *ch, int enable)
+{
+ struct uaudio_softc *sc = ch->priv_sc;
+
+ if (ch->cur_alt_index == ch->usb_alt[ch->cur_alt].iface_alt_index) {
+ return;
+ }
+ usbd_req_set_alt_interface_no(sc->sc_udev,
+ NULL,
+ ch->iface_index,
+ ch->usb_alt[ch->cur_alt].iface_alt_index);
+
+ ch->cur_alt_index = ch->usb_alt[ch->cur_alt].iface_alt_index;
+}
+
void
uaudio_chan_start(struct uaudio_chan *ch)
{
@@ -2836,8 +2855,20 @@
}
}
if (do_stop) {
- usbd_transfer_stop(ch->xfer[0]);
- usbd_transfer_stop(ch->xfer[1]);
+ usb_proc_explore_unlock(sc->sc_udev);
+ CHN_UNLOCK(ch->pcm_ch);
+
+ usbd_transfer_drain(ch->xfer[0]);
+ usbd_transfer_drain(ch->xfer[1]);
+
+ usbd_req_set_alt_interface_no(sc->sc_udev,
+ NULL,
+ ch->iface_index,
+ 0);
+ ch->cur_alt_index = 0;
+ CHN_LOCK(ch->pcm_ch);
+ usb_proc_explore_lock(sc->sc_udev);
+
}
}
Index: sys/dev/sound/usb/uaudio_pcm.c
===================================================================
--- sys/dev/sound/usb/uaudio_pcm.c
+++ sys/dev/sound/usb/uaudio_pcm.c
@@ -79,6 +79,13 @@
return (uaudio_chan_set_param_fragments(data, blocksize, blockcount));
}
+static int
+ua_chan_prepare(kobj_t obj, void *data, int go)
+{
+ uaudio_chan_prepare(data, go);
+ return 0;
+}
+
static int
ua_chan_trigger(kobj_t obj, void *data, int go)
{
@@ -118,6 +125,7 @@
KOBJMETHOD(channel_setblocksize, ua_chan_setblocksize),
KOBJMETHOD(channel_setfragments, ua_chan_setfragments),
KOBJMETHOD(channel_trigger, ua_chan_trigger),
+ KOBJMETHOD(channel_prepare, ua_chan_prepare),
KOBJMETHOD(channel_getptr, ua_chan_getptr),
KOBJMETHOD(channel_getcaps, ua_chan_getcaps),
KOBJMETHOD(channel_getmatrix, ua_chan_getmatrix),

File Metadata

Mime Type
text/plain
Expires
Fri, Jun 12, 9:14 AM (13 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33903780
Default Alt Text
D28032.id81864.diff (6 KB)

Event Timeline