Index: files/patch-src_modules_oss_module-oss.c =================================================================== --- files/patch-src_modules_oss_module-oss.c (revision 530222) +++ files/patch-src_modules_oss_module-oss.c (working copy) @@ -1,6 +1,129 @@ ---- src/modules/oss/module-oss.c.orig 2018-05-07 14:30:52 UTC +--- src/modules/oss/module-oss.c.orig 2019-09-13 13:10:23 UTC +++ src/modules/oss/module-oss.c -@@ -1235,10 +1235,14 @@ int pa__init(pa_module*m) { +@@ -126,6 +126,8 @@ struct userdata { + + int nfrags, frag_size, orig_frag_size; + ++ bool shutdown; ++ + bool use_mmap; + unsigned out_mmap_current, in_mmap_current; + void *in_mmap, *out_mmap; +@@ -843,14 +845,10 @@ static void sink_set_volume(pa_sink *s) { + pa_assert(u->mixer_devmask & (SOUND_MASK_VOLUME|SOUND_MASK_PCM)); + + if (u->mixer_devmask & SOUND_MASK_VOLUME) +- if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->real_volume) >= 0) +- return; ++ (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_VOLUME, &s->sample_spec, &s->real_volume); + + if (u->mixer_devmask & SOUND_MASK_PCM) +- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->real_volume) >= 0) +- return; +- +- pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); ++ (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_PCM, &s->sample_spec, &s->real_volume); + } + + static void source_get_volume(pa_source *s) { +@@ -858,7 +856,7 @@ static void source_get_volume(pa_source *s) { + + pa_assert_se(u = s->userdata); + +- pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); ++ pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); + + if (u->mixer_devmask & SOUND_MASK_IGAIN) + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_IGAIN, &s->sample_spec, &s->real_volume) >= 0) +@@ -868,6 +866,10 @@ static void source_get_volume(pa_source *s) { + if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_RECLEV, &s->sample_spec, &s->real_volume) >= 0) + return; + ++ if (u->mixer_devmask & SOUND_MASK_MIC) ++ if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_READ_MIC, &s->sample_spec, &s->real_volume) >= 0) ++ return; ++ + pa_log_info("Device doesn't support reading mixer settings: %s", pa_cstrerror(errno)); + } + +@@ -876,17 +878,16 @@ static void source_set_volume(pa_source *s) { + + pa_assert_se(u = s->userdata); + +- pa_assert(u->mixer_devmask & (SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); ++ pa_assert(u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_IGAIN|SOUND_MASK_RECLEV)); + + if (u->mixer_devmask & SOUND_MASK_IGAIN) +- if (pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->real_volume) >= 0) +- return; ++ (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_IGAIN, &s->sample_spec, &s->real_volume); + + if (u->mixer_devmask & SOUND_MASK_RECLEV) +- if (pa_oss_get_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->real_volume) >= 0) +- return; ++ (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_RECLEV, &s->sample_spec, &s->real_volume); + +- pa_log_info("Device doesn't support writing mixer settings: %s", pa_cstrerror(errno)); ++ if (u->mixer_devmask & SOUND_MASK_MIC) ++ (void) pa_oss_set_volume(u->mixer_fd, SOUND_MIXER_WRITE_MIC, &s->sample_spec, &s->real_volume); + } + + static void thread_func(void *userdata) { +@@ -1133,15 +1134,22 @@ static void thread_func(void *userdata) { + pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL); + pollfd->events = (short) + (((u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0) | +- ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0)); ++ ((u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) ? POLLOUT : 0) | ++ POLLHUP); + } + ++ /* set a watchdog timeout of one second */ ++ pa_rtpoll_set_timer_relative(u->rtpoll, 1000000); ++ + /* Hmm, nothing to do. Let's sleep */ +- if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) ++ if ((ret = pa_rtpoll_run(u->rtpoll)) < 0) { + goto fail; ++ } + +- if (ret == 0) +- goto finish; ++ /* check for shutdown */ ++ if (u->shutdown) { ++ goto fail; ++ } + + if (u->rtpoll_item) { + struct pollfd *pollfd; +@@ -1156,6 +1164,16 @@ static void thread_func(void *userdata) { + revents = pollfd->revents; + } else + revents = 0; ++ ++ /* check for mixer shutdown, if any */ ++ if ((revents & (POLLOUT | POLLIN)) == 0) { ++ int mixer_fd = u->mixer_fd; ++ int devmask; ++ if (mixer_fd > -1 && ioctl(mixer_fd, SOUND_MIXER_READ_DEVMASK, &devmask) < 0) { ++ pa_log("Mixer shutdown."); ++ goto fail; ++ } ++ } + } + + fail: +@@ -1163,9 +1181,6 @@ fail: + * processing messages until we received PA_MESSAGE_SHUTDOWN */ + pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL); + pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN); +- +-finish: +- pa_log_debug("Thread shutting down"); + } + + int pa__init(pa_module*m) { +@@ -1235,10 +1250,14 @@ int pa__init(pa_module*m) { use_mmap = false; } @@ -15,3 +138,20 @@ if (pa_oss_get_hw_description(dev, hwdesc, sizeof(hwdesc)) >= 0) pa_log_info("Hardware name is '%s'.", hwdesc); +@@ -1452,7 +1471,7 @@ int pa__init(pa_module*m) { + do_close = false; + } + +- if (u->source && (u->mixer_devmask & (SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) { ++ if (u->source && (u->mixer_devmask & (SOUND_MASK_MIC|SOUND_MASK_RECLEV|SOUND_MASK_IGAIN))) { + pa_log_debug("Found hardware mixer track for recording."); + pa_source_set_get_volume_callback(u->source, source_get_volume); + pa_source_set_set_volume_callback(u->source, source_set_volume); +@@ -1537,6 +1556,7 @@ void pa__done(pa_module*m) { + pa_source_unlink(u->source); + + if (u->thread) { ++ u->shutdown = true; + pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL); + pa_thread_free(u->thread); + } Index: files/patch-src_modules_oss_oss-util.c =================================================================== --- files/patch-src_modules_oss_oss-util.c (revision 530222) +++ files/patch-src_modules_oss_oss-util.c (working copy) @@ -1,9 +1,9 @@ Support 24bit audio see Comment 6 of https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=198567 ---- src/modules/oss/oss-util.c.orig 2015-09-10 04:51:41 UTC +--- src/modules/oss/oss-util.c.orig 2018-07-13 19:06:14 UTC +++ src/modules/oss/oss-util.c -@@ -39,6 +39,22 @@ +@@ -39,7 +39,27 @@ #include "oss-util.h" @@ -22,11 +22,27 @@ +#ifndef DSP_CAP_BIND +#define DSP_CAP_BIND 0x00008000 +#endif ++#ifndef ENOLINK ++#define ENOLINK EINVAL ++#endif + int pa_oss_open(const char *device, int *mode, int* pcaps) { ++ static const int nonblock_io = 1; int fd = -1; int caps; -@@ -164,8 +180,8 @@ int pa_oss_auto_format(int fd, pa_sample + char *t; +@@ -89,6 +109,10 @@ int pa_oss_open(const char *device, int *mode, int* pc + } + + success: ++ if (ioctl(fd, FIONBIO, &nonblock_io) < 0) { ++ pa_log("FIONBIO: %s", pa_cstrerror(errno)); ++ goto fail; ++ } + + t = pa_sprintf_malloc( + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s", +@@ -164,8 +188,8 @@ int pa_oss_auto_format(int fd, pa_sample_spec *ss) { [PA_SAMPLE_FLOAT32BE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S32LE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S32BE] = AFMT_QUERY, /* not supported */ @@ -37,3 +53,87 @@ [PA_SAMPLE_S24_32LE] = AFMT_QUERY, /* not supported */ [PA_SAMPLE_S24_32BE] = AFMT_QUERY, /* not supported */ }; +@@ -290,41 +314,35 @@ int pa_oss_set_volume(int fd, unsigned long mixer, con + } + + static int get_device_number(const char *dev) { +- const char *p, *e; ++ const char *p; ++ const char *e; + char *rp = NULL; +- int r; ++ int r = -1; + + if (!(p = rp = pa_readlink(dev))) { +-#ifdef ENOLINK +- if (errno != EINVAL && errno != ENOLINK) { +-#else +- if (errno != EINVAL) { +-#endif +- r = -1; +- goto finish; +- } +- ++ if (errno != EINVAL && errno != ENOLINK) ++ return -2; + p = dev; + } + +- if ((e = strrchr(p, '/'))) +- p = e+1; ++ /* find the last forward slash */ ++ while ((e = strrchr(p, '/'))) ++ p = e + 1; + +- if (p == 0) { +- r = 0; +- goto finish; ++ /* collect unit number at end, if any */ ++ while (*p) { ++ if (*p >= '0' && *p <= '9') { ++ if (r < 0) ++ r = 0; ++ else ++ r *= 10; ++ r += *p - '0'; ++ } else { ++ r = -1; ++ } ++ p++; + } + +- p = strchr(p, 0) -1; +- +- if (*p >= '0' && *p <= '9') { +- r = *p - '0'; +- goto finish; +- } +- +- r = -1; +- +-finish: + pa_xfree(rp); + return r; + } +@@ -334,7 +352,7 @@ int pa_oss_get_hw_description(const char *dev, char *n + int n, r = -1; + int b = 0; + +- if ((n = get_device_number(dev)) < 0) ++ if ((n = get_device_number(dev)) == -2) + return -1; + + if (!(f = pa_fopen_cloexec("/dev/sndstat", "r")) && +@@ -400,10 +418,10 @@ int pa_oss_open_mixer_for_device(const char *device) { + char *fn; + int fd; + +- if ((n = get_device_number(device)) < 0) ++ if ((n = get_device_number(device)) == -2) + return -1; + +- if (n == 0) ++ if (n == -1) + if ((fd = open_mixer("/dev/mixer")) >= 0) + return fd; +