bluetooth: Support port availability flag
[profile/ivi/pulseaudio.git] / src / modules / module-solaris.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2006 Lennart Poettering
5   Copyright 2006-2007 Pierre Ossman <ossman@cendio.se> for Cendio AB
6   Copyright 2009 Finn Thain
7
8   PulseAudio is free software; you can redistribute it and/or modify
9   it under the terms of the GNU Lesser General Public License as published
10   by the Free Software Foundation; either version 2.1 of the License,
11   or (at your option) any later version.
12
13   PulseAudio is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with PulseAudio; if not, write to the Free Software
20   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21   USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <fcntl.h>
32 #include <unistd.h>
33 #include <sys/ioctl.h>
34 #include <sys/types.h>
35
36 #include <signal.h>
37 #include <stropts.h>
38 #include <sys/conf.h>
39 #include <sys/audio.h>
40
41 #include <pulse/mainloop-signal.h>
42 #include <pulse/xmalloc.h>
43 #include <pulse/timeval.h>
44 #include <pulse/util.h>
45 #include <pulse/rtclock.h>
46
47 #include <pulsecore/sink.h>
48 #include <pulsecore/source.h>
49 #include <pulsecore/module.h>
50 #include <pulsecore/sample-util.h>
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/modargs.h>
53 #include <pulsecore/log.h>
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/thread-mq.h>
56 #include <pulsecore/rtpoll.h>
57 #include <pulsecore/thread.h>
58 #include <pulsecore/time-smoother.h>
59
60 #include "module-solaris-symdef.h"
61
62 PA_MODULE_AUTHOR("Pierre Ossman");
63 PA_MODULE_DESCRIPTION("Solaris Sink/Source");
64 PA_MODULE_VERSION(PACKAGE_VERSION);
65 PA_MODULE_USAGE(
66     "sink_name=<name for the sink> "
67     "sink_properties=<properties for the sink> "
68     "source_name=<name for the source> "
69     "source_properties=<properties for the source> "
70     "device=<audio device file name> "
71     "record=<enable source?> "
72     "playback=<enable sink?> "
73     "format=<sample format> "
74     "channels=<number of channels> "
75     "rate=<sample rate> "
76     "buffer_length=<milliseconds> "
77     "channel_map=<channel map>");
78 PA_MODULE_LOAD_ONCE(FALSE);
79
80 struct userdata {
81     pa_core *core;
82     pa_sink *sink;
83     pa_source *source;
84
85     pa_thread *thread;
86     pa_thread_mq thread_mq;
87     pa_rtpoll *rtpoll;
88
89     pa_signal_event *sig;
90
91     pa_memchunk memchunk;
92
93     uint32_t frame_size;
94     int32_t buffer_size;
95     uint64_t written_bytes, read_bytes;
96
97     char *device_name;
98     int mode;
99     int fd;
100     pa_rtpoll_item *rtpoll_item;
101     pa_module *module;
102
103     pa_bool_t sink_suspended, source_suspended;
104
105     uint32_t play_samples_msw, record_samples_msw;
106     uint32_t prev_playback_samples, prev_record_samples;
107
108     int32_t minimum_request;
109
110     pa_smoother *smoother;
111 };
112
113 static const char* const valid_modargs[] = {
114     "sink_name",
115     "sink_properties",
116     "source_name",
117     "source_properties",
118     "device",
119     "record",
120     "playback",
121     "buffer_length",
122     "format",
123     "rate",
124     "channels",
125     "channel_map",
126     NULL
127 };
128
129 #define DEFAULT_DEVICE "/dev/audio"
130
131 #define MAX_RENDER_HZ   (300)
132 /* This render rate limit imposes a minimum latency, but without it we waste too much CPU time. */
133
134 #define MAX_BUFFER_SIZE (128 * 1024)
135 /* An attempt to buffer more than 128 KB causes write() to fail with errno == EAGAIN. */
136
137 static uint64_t get_playback_buffered_bytes(struct userdata *u) {
138     audio_info_t info;
139     uint64_t played_bytes;
140     int err;
141
142     pa_assert(u->sink);
143
144     err = ioctl(u->fd, AUDIO_GETINFO, &info);
145     pa_assert(err >= 0);
146
147     /* Handle wrap-around of the device's sample counter, which is a uint_32. */
148     if (u->prev_playback_samples > info.play.samples) {
149         /*
150          * Unfortunately info.play.samples can sometimes go backwards, even before it wraps!
151          * The bug seems to be absent on Solaris x86 nv117 with audio810 driver, at least on this (UP) machine.
152          * The bug is present on a different (SMP) machine running Solaris x86 nv103 with audioens driver.
153          * An earlier revision of this file mentions the same bug independently (unknown configuration).
154          */
155         if (u->prev_playback_samples + info.play.samples < 240000) {
156             ++u->play_samples_msw;
157         } else {
158             pa_log_debug("play.samples went backwards %d bytes", u->prev_playback_samples - info.play.samples);
159         }
160     }
161     u->prev_playback_samples = info.play.samples;
162     played_bytes = (((uint64_t)u->play_samples_msw << 32) + info.play.samples) * u->frame_size;
163
164     pa_smoother_put(u->smoother, pa_rtclock_now(), pa_bytes_to_usec(played_bytes, &u->sink->sample_spec));
165
166     return u->written_bytes - played_bytes;
167 }
168
169 static pa_usec_t sink_get_latency(struct userdata *u, pa_sample_spec *ss) {
170     pa_usec_t r = 0;
171
172     pa_assert(u);
173     pa_assert(ss);
174
175     if (u->fd >= 0) {
176         r = pa_bytes_to_usec(get_playback_buffered_bytes(u), ss);
177         if (u->memchunk.memblock)
178             r += pa_bytes_to_usec(u->memchunk.length, ss);
179     }
180     return r;
181 }
182
183 static uint64_t get_recorded_bytes(struct userdata *u) {
184     audio_info_t info;
185     uint64_t result;
186     int err;
187
188     pa_assert(u->source);
189
190     err = ioctl(u->fd, AUDIO_GETINFO, &info);
191     pa_assert(err >= 0);
192
193     if (u->prev_record_samples > info.record.samples)
194         ++u->record_samples_msw;
195     u->prev_record_samples = info.record.samples;
196     result = (((uint64_t)u->record_samples_msw << 32) + info.record.samples) * u->frame_size;
197
198     return result;
199 }
200
201 static pa_usec_t source_get_latency(struct userdata *u, pa_sample_spec *ss) {
202     pa_usec_t r = 0;
203     audio_info_t info;
204
205     pa_assert(u);
206     pa_assert(ss);
207
208     if (u->fd) {
209         int err = ioctl(u->fd, AUDIO_GETINFO, &info);
210         pa_assert(err >= 0);
211
212         r = pa_bytes_to_usec(get_recorded_bytes(u), ss) - pa_bytes_to_usec(u->read_bytes, ss);
213     }
214     return r;
215 }
216
217 static void build_pollfd(struct userdata *u) {
218     struct pollfd *pollfd;
219
220     pa_assert(u);
221     pa_assert(!u->rtpoll_item);
222     u->rtpoll_item = pa_rtpoll_item_new(u->rtpoll, PA_RTPOLL_NEVER, 1);
223
224     pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
225     pollfd->fd = u->fd;
226     pollfd->events = 0;
227     pollfd->revents = 0;
228 }
229
230 static int set_buffer(int fd, int buffer_size) {
231     audio_info_t info;
232
233     pa_assert(fd >= 0);
234
235     AUDIO_INITINFO(&info);
236     info.play.buffer_size = buffer_size;
237     info.record.buffer_size = buffer_size;
238
239     if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
240         if (errno == EINVAL)
241             pa_log("AUDIO_SETINFO: Unsupported buffer size.");
242         else
243             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
244         return -1;
245     }
246
247     return 0;
248 }
249
250 static int auto_format(int fd, int mode, pa_sample_spec *ss) {
251     audio_info_t info;
252
253     pa_assert(fd >= 0);
254     pa_assert(ss);
255
256     AUDIO_INITINFO(&info);
257
258     if (mode != O_RDONLY) {
259         info.play.sample_rate = ss->rate;
260         info.play.channels = ss->channels;
261         switch (ss->format) {
262         case PA_SAMPLE_U8:
263             info.play.precision = 8;
264             info.play.encoding = AUDIO_ENCODING_LINEAR;
265             break;
266         case PA_SAMPLE_ALAW:
267             info.play.precision = 8;
268             info.play.encoding = AUDIO_ENCODING_ALAW;
269             break;
270         case PA_SAMPLE_ULAW:
271             info.play.precision = 8;
272             info.play.encoding = AUDIO_ENCODING_ULAW;
273             break;
274         case PA_SAMPLE_S16NE:
275             info.play.precision = 16;
276             info.play.encoding = AUDIO_ENCODING_LINEAR;
277             break;
278         default:
279             pa_log("AUDIO_SETINFO: Unsupported sample format.");
280             return -1;
281         }
282     }
283
284     if (mode != O_WRONLY) {
285         info.record.sample_rate = ss->rate;
286         info.record.channels = ss->channels;
287         switch (ss->format) {
288         case PA_SAMPLE_U8:
289             info.record.precision = 8;
290             info.record.encoding = AUDIO_ENCODING_LINEAR;
291             break;
292         case PA_SAMPLE_ALAW:
293             info.record.precision = 8;
294             info.record.encoding = AUDIO_ENCODING_ALAW;
295             break;
296         case PA_SAMPLE_ULAW:
297             info.record.precision = 8;
298             info.record.encoding = AUDIO_ENCODING_ULAW;
299             break;
300         case PA_SAMPLE_S16NE:
301             info.record.precision = 16;
302             info.record.encoding = AUDIO_ENCODING_LINEAR;
303             break;
304         default:
305             pa_log("AUDIO_SETINFO: Unsupported sample format.");
306             return -1;
307         }
308     }
309
310     if (ioctl(fd, AUDIO_SETINFO, &info) < 0) {
311         if (errno == EINVAL)
312             pa_log("AUDIO_SETINFO: Failed to set sample format.");
313         else
314             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
315         return -1;
316     }
317
318     return 0;
319 }
320
321 static int open_audio_device(struct userdata *u, pa_sample_spec *ss) {
322     pa_assert(u);
323     pa_assert(ss);
324
325     if ((u->fd = pa_open_cloexec(u->device_name, u->mode | O_NONBLOCK, 0)) < 0) {
326         pa_log_warn("open %s failed (%s)", u->device_name, pa_cstrerror(errno));
327         return -1;
328     }
329
330     pa_log_info("device opened in %s mode.", u->mode == O_WRONLY ? "O_WRONLY" : (u->mode == O_RDONLY ? "O_RDONLY" : "O_RDWR"));
331
332     if (auto_format(u->fd, u->mode, ss) < 0)
333         return -1;
334
335     if (set_buffer(u->fd, u->buffer_size) < 0)
336         return -1;
337
338     u->written_bytes = u->read_bytes = 0;
339     u->play_samples_msw = u->record_samples_msw = 0;
340     u->prev_playback_samples = u->prev_record_samples = 0;
341
342     return u->fd;
343 }
344
345 static int suspend(struct userdata *u) {
346     pa_assert(u);
347     pa_assert(u->fd >= 0);
348
349     pa_log_info("Suspending...");
350
351     ioctl(u->fd, AUDIO_DRAIN, NULL);
352     pa_close(u->fd);
353     u->fd = -1;
354
355     if (u->rtpoll_item) {
356         pa_rtpoll_item_free(u->rtpoll_item);
357         u->rtpoll_item = NULL;
358     }
359
360     pa_log_info("Device suspended.");
361
362     return 0;
363 }
364
365 static int unsuspend(struct userdata *u) {
366     pa_assert(u);
367     pa_assert(u->fd < 0);
368
369     pa_log_info("Resuming...");
370
371     if (open_audio_device(u, u->sink ? &u->sink->sample_spec : &u->source->sample_spec) < 0)
372         return -1;
373
374     build_pollfd(u);
375
376     pa_log_info("Device resumed.");
377
378     return 0;
379 }
380
381 static int sink_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
382     struct userdata *u = PA_SINK(o)->userdata;
383
384     switch (code) {
385
386         case PA_SINK_MESSAGE_GET_LATENCY:
387             *((pa_usec_t*) data) = sink_get_latency(u, &PA_SINK(o)->sample_spec);
388             return 0;
389
390         case PA_SINK_MESSAGE_SET_STATE:
391
392             switch ((pa_sink_state_t) PA_PTR_TO_UINT(data)) {
393
394                 case PA_SINK_SUSPENDED:
395
396                     pa_assert(PA_SINK_IS_OPENED(u->sink->thread_info.state));
397
398                     pa_smoother_pause(u->smoother, pa_rtclock_now());
399
400                     if (!u->source || u->source_suspended) {
401                         if (suspend(u) < 0)
402                             return -1;
403                     }
404                     u->sink_suspended = TRUE;
405                     break;
406
407                 case PA_SINK_IDLE:
408                 case PA_SINK_RUNNING:
409
410                     if (u->sink->thread_info.state == PA_SINK_SUSPENDED) {
411                         pa_smoother_resume(u->smoother, pa_rtclock_now(), TRUE);
412
413                         if (!u->source || u->source_suspended) {
414                             if (unsuspend(u) < 0)
415                                 return -1;
416                             u->sink->get_volume(u->sink);
417                             u->sink->get_mute(u->sink);
418                         }
419                         u->sink_suspended = FALSE;
420                     }
421                     break;
422
423                 case PA_SINK_INVALID_STATE:
424                 case PA_SINK_UNLINKED:
425                 case PA_SINK_INIT:
426                     ;
427             }
428
429             break;
430     }
431
432     return pa_sink_process_msg(o, code, data, offset, chunk);
433 }
434
435 static int source_process_msg(pa_msgobject *o, int code, void *data, int64_t offset, pa_memchunk *chunk) {
436     struct userdata *u = PA_SOURCE(o)->userdata;
437
438     switch (code) {
439
440         case PA_SOURCE_MESSAGE_GET_LATENCY:
441             *((pa_usec_t*) data) = source_get_latency(u, &PA_SOURCE(o)->sample_spec);
442             return 0;
443
444         case PA_SOURCE_MESSAGE_SET_STATE:
445
446             switch ((pa_source_state_t) PA_PTR_TO_UINT(data)) {
447
448                 case PA_SOURCE_SUSPENDED:
449
450                     pa_assert(PA_SOURCE_IS_OPENED(u->source->thread_info.state));
451
452                     if (!u->sink || u->sink_suspended) {
453                         if (suspend(u) < 0)
454                             return -1;
455                     }
456                     u->source_suspended = TRUE;
457                     break;
458
459                 case PA_SOURCE_IDLE:
460                 case PA_SOURCE_RUNNING:
461
462                     if (u->source->thread_info.state == PA_SOURCE_SUSPENDED) {
463                         if (!u->sink || u->sink_suspended) {
464                             if (unsuspend(u) < 0)
465                                 return -1;
466                             u->source->get_volume(u->source);
467                         }
468                         u->source_suspended = FALSE;
469                     }
470                     break;
471
472                 case PA_SOURCE_UNLINKED:
473                 case PA_SOURCE_INIT:
474                 case PA_SOURCE_INVALID_STATE:
475                     ;
476
477             }
478             break;
479
480     }
481
482     return pa_source_process_msg(o, code, data, offset, chunk);
483 }
484
485 static void sink_set_volume(pa_sink *s) {
486     struct userdata *u;
487     audio_info_t info;
488
489     pa_assert_se(u = s->userdata);
490
491     if (u->fd >= 0) {
492         AUDIO_INITINFO(&info);
493
494         info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
495         assert(info.play.gain <= AUDIO_MAX_GAIN);
496
497         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
498             if (errno == EINVAL)
499                 pa_log("AUDIO_SETINFO: Unsupported volume.");
500             else
501                 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
502         }
503     }
504 }
505
506 static void sink_get_volume(pa_sink *s) {
507     struct userdata *u;
508     audio_info_t info;
509
510     pa_assert_se(u = s->userdata);
511
512     if (u->fd >= 0) {
513         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
514             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
515         else
516             pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
517     }
518 }
519
520 static void source_set_volume(pa_source *s) {
521     struct userdata *u;
522     audio_info_t info;
523
524     pa_assert_se(u = s->userdata);
525
526     if (u->fd >= 0) {
527         AUDIO_INITINFO(&info);
528
529         info.play.gain = pa_cvolume_max(&s->real_volume) * AUDIO_MAX_GAIN / PA_VOLUME_NORM;
530         assert(info.play.gain <= AUDIO_MAX_GAIN);
531
532         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0) {
533             if (errno == EINVAL)
534                 pa_log("AUDIO_SETINFO: Unsupported volume.");
535             else
536                 pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
537         }
538     }
539 }
540
541 static void source_get_volume(pa_source *s) {
542     struct userdata *u;
543     audio_info_t info;
544
545     pa_assert_se(u = s->userdata);
546
547     if (u->fd >= 0) {
548         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
549             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
550         else
551             pa_cvolume_set(&s->real_volume, s->sample_spec.channels, info.play.gain * PA_VOLUME_NORM / AUDIO_MAX_GAIN);
552     }
553 }
554
555 static void sink_set_mute(pa_sink *s) {
556     struct userdata *u = s->userdata;
557     audio_info_t info;
558
559     pa_assert(u);
560
561     if (u->fd >= 0) {
562         AUDIO_INITINFO(&info);
563
564         info.output_muted = !!s->muted;
565
566         if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
567             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
568     }
569 }
570
571 static void sink_get_mute(pa_sink *s) {
572     struct userdata *u = s->userdata;
573     audio_info_t info;
574
575     pa_assert(u);
576
577     if (u->fd >= 0) {
578         if (ioctl(u->fd, AUDIO_GETINFO, &info) < 0)
579             pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
580         else
581             s->muted = !!info.output_muted;
582     }
583 }
584
585 static void process_rewind(struct userdata *u) {
586     size_t rewind_nbytes;
587
588     pa_assert(u);
589
590     /* Figure out how much we shall rewind and reset the counter */
591     rewind_nbytes = u->sink->thread_info.rewind_nbytes;
592     u->sink->thread_info.rewind_nbytes = 0;
593
594     if (rewind_nbytes > 0) {
595         pa_log_debug("Requested to rewind %lu bytes.", (unsigned long) rewind_nbytes);
596         rewind_nbytes = PA_MIN(u->memchunk.length, rewind_nbytes);
597         u->memchunk.length -= rewind_nbytes;
598         if (u->memchunk.length <= 0 && u->memchunk.memblock) {
599             pa_memblock_unref(u->memchunk.memblock);
600             pa_memchunk_reset(&u->memchunk);
601         }
602         pa_log_debug("Rewound %lu bytes.", (unsigned long) rewind_nbytes);
603     }
604
605     pa_sink_process_rewind(u->sink, rewind_nbytes);
606 }
607
608 static void thread_func(void *userdata) {
609     struct userdata *u = userdata;
610     unsigned short revents = 0;
611     int ret, err;
612     audio_info_t info;
613
614     pa_assert(u);
615
616     pa_log_debug("Thread starting up");
617
618     if (u->core->realtime_scheduling)
619         pa_make_realtime(u->core->realtime_priority);
620
621     pa_thread_mq_install(&u->thread_mq);
622
623     pa_smoother_set_time_offset(u->smoother, pa_rtclock_now());
624
625     for (;;) {
626         /* Render some data and write it to the dsp */
627
628         if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
629             pa_usec_t xtime0, ysleep_interval, xsleep_interval;
630             uint64_t buffered_bytes;
631
632             if (u->sink->thread_info.rewind_requested)
633                 process_rewind(u);
634
635             err = ioctl(u->fd, AUDIO_GETINFO, &info);
636             if (err < 0) {
637                 pa_log("AUDIO_GETINFO ioctl failed: %s", pa_cstrerror(errno));
638                 goto fail;
639             }
640
641             if (info.play.error) {
642                 pa_log_debug("buffer under-run!");
643
644                 AUDIO_INITINFO(&info);
645                 info.play.error = 0;
646                 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
647                     pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
648
649                 pa_smoother_reset(u->smoother, pa_rtclock_now(), TRUE);
650             }
651
652             for (;;) {
653                 void *p;
654                 ssize_t w;
655                 size_t len;
656                 int write_type = 1;
657
658                 /*
659                  * Since we cannot modify the size of the output buffer we fake it
660                  * by not filling it more than u->buffer_size.
661                  */
662                 xtime0 = pa_rtclock_now();
663                 buffered_bytes = get_playback_buffered_bytes(u);
664                 if (buffered_bytes >= (uint64_t)u->buffer_size)
665                     break;
666
667                 len = u->buffer_size - buffered_bytes;
668                 len -= len % u->frame_size;
669
670                 if (len < (size_t) u->minimum_request)
671                     break;
672
673                 if (!u->memchunk.length)
674                     pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk);
675
676                 len = PA_MIN(u->memchunk.length, len);
677
678                 p = pa_memblock_acquire(u->memchunk.memblock);
679                 w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, len, &write_type);
680                 pa_memblock_release(u->memchunk.memblock);
681
682                 if (w <= 0) {
683                     if (errno == EINTR) {
684                         continue;
685                     } else if (errno == EAGAIN) {
686                         /* We may have realtime priority so yield the CPU to ensure that fd can become writable again. */
687                         pa_log_debug("EAGAIN with %llu bytes buffered.", buffered_bytes);
688                         break;
689                     } else {
690                         pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno));
691                         goto fail;
692                     }
693                 } else {
694                     pa_assert(w % u->frame_size == 0);
695
696                     u->written_bytes += w;
697                     u->memchunk.index += w;
698                     u->memchunk.length -= w;
699                     if (u->memchunk.length <= 0) {
700                         pa_memblock_unref(u->memchunk.memblock);
701                         pa_memchunk_reset(&u->memchunk);
702                     }
703                 }
704             }
705
706             ysleep_interval = pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec);
707             xsleep_interval = pa_smoother_translate(u->smoother, xtime0, ysleep_interval);
708             pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + PA_MIN(xsleep_interval, ysleep_interval));
709         } else
710             pa_rtpoll_set_timer_disabled(u->rtpoll);
711
712         /* Try to read some data and pass it on to the source driver */
713
714         if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state) && (revents & POLLIN)) {
715             pa_memchunk memchunk;
716             void *p;
717             ssize_t r;
718             size_t len;
719
720             err = ioctl(u->fd, AUDIO_GETINFO, &info);
721             pa_assert(err >= 0);
722
723             if (info.record.error) {
724                 pa_log_debug("buffer overflow!");
725
726                 AUDIO_INITINFO(&info);
727                 info.record.error = 0;
728                 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
729                     pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
730             }
731
732             err = ioctl(u->fd, I_NREAD, &len);
733             pa_assert(err >= 0);
734
735             if (len > 0) {
736                 memchunk.memblock = pa_memblock_new(u->core->mempool, len);
737                 pa_assert(memchunk.memblock);
738
739                 p = pa_memblock_acquire(memchunk.memblock);
740                 r = pa_read(u->fd, p, len, NULL);
741                 pa_memblock_release(memchunk.memblock);
742
743                 if (r < 0) {
744                     pa_memblock_unref(memchunk.memblock);
745                     if (errno == EAGAIN)
746                         break;
747                     else {
748                         pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno));
749                         goto fail;
750                     }
751                 } else {
752                     u->read_bytes += r;
753
754                     memchunk.index = 0;
755                     memchunk.length = r;
756
757                     pa_source_post(u->source, &memchunk);
758                     pa_memblock_unref(memchunk.memblock);
759
760                     revents &= ~POLLIN;
761                 }
762             }
763         }
764
765         if (u->rtpoll_item) {
766             struct pollfd *pollfd;
767
768             pa_assert(u->fd >= 0);
769
770             pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
771             pollfd->events = (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0;
772         }
773
774         /* Hmm, nothing to do. Let's sleep */
775         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
776             goto fail;
777
778         if (ret == 0)
779             goto finish;
780
781         if (u->rtpoll_item) {
782             struct pollfd *pollfd;
783
784             pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
785
786             if (pollfd->revents & ~(POLLOUT|POLLIN)) {
787                 pa_log("DSP shutdown.");
788                 goto fail;
789             }
790
791             revents = pollfd->revents;
792         } else
793             revents = 0;
794     }
795
796 fail:
797     /* We have to continue processing messages until we receive the
798      * SHUTDOWN message */
799     pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
800     pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
801
802 finish:
803     pa_log_debug("Thread shutting down");
804 }
805
806 static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) {
807     struct userdata *u = userdata;
808
809     assert(u);
810
811     pa_log_debug("caught signal");
812
813     if (u->sink) {
814         pa_sink_get_volume(u->sink, TRUE);
815         pa_sink_get_mute(u->sink, TRUE);
816     }
817
818     if (u->source)
819         pa_source_get_volume(u->source, TRUE);
820 }
821
822 int pa__init(pa_module *m) {
823     struct userdata *u = NULL;
824     pa_bool_t record = TRUE, playback = TRUE;
825     pa_sample_spec ss;
826     pa_channel_map map;
827     pa_modargs *ma = NULL;
828     uint32_t buffer_length_msec;
829     int fd = -1;
830     pa_sink_new_data sink_new_data;
831     pa_source_new_data source_new_data;
832     char const *name;
833     char *name_buf;
834     pa_bool_t namereg_fail;
835
836     pa_assert(m);
837
838     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
839         pa_log("failed to parse module arguments.");
840         goto fail;
841     }
842
843     if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
844         pa_log("record= and playback= expect a boolean argument.");
845         goto fail;
846     }
847
848     if (!playback && !record) {
849         pa_log("neither playback nor record enabled for device.");
850         goto fail;
851     }
852
853     u = pa_xnew0(struct userdata, 1);
854
855     if (!(u->smoother = pa_smoother_new(PA_USEC_PER_SEC, PA_USEC_PER_SEC * 2, TRUE, TRUE, 10, pa_rtclock_now(), TRUE)))
856         goto fail;
857
858     /*
859      * For a process (or several processes) to use the same audio device for both
860      * record and playback at the same time, the device's mixer must be enabled.
861      * See mixerctl(1). It may be turned off for playback only or record only.
862      */
863     u->mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
864
865     ss = m->core->default_sample_spec;
866     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
867         pa_log("failed to parse sample specification");
868         goto fail;
869     }
870     u->frame_size = pa_frame_size(&ss);
871
872     u->minimum_request = pa_usec_to_bytes(PA_USEC_PER_SEC / MAX_RENDER_HZ, &ss);
873
874     buffer_length_msec = 100;
875     if (pa_modargs_get_value_u32(ma, "buffer_length", &buffer_length_msec) < 0) {
876         pa_log("failed to parse buffer_length argument");
877         goto fail;
878     }
879     u->buffer_size = pa_usec_to_bytes(1000 * buffer_length_msec, &ss);
880     if (u->buffer_size < 2 * u->minimum_request) {
881         pa_log("buffer_length argument cannot be smaller than %u",
882                (unsigned)(pa_bytes_to_usec(2 * u->minimum_request, &ss) / 1000));
883         goto fail;
884     }
885     if (u->buffer_size > MAX_BUFFER_SIZE) {
886         pa_log("buffer_length argument cannot be greater than %u",
887                (unsigned)(pa_bytes_to_usec(MAX_BUFFER_SIZE, &ss) / 1000));
888         goto fail;
889     }
890
891     u->device_name = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
892
893     if ((fd = open_audio_device(u, &ss)) < 0)
894         goto fail;
895
896     u->core = m->core;
897     u->module = m;
898     m->userdata = u;
899
900     pa_memchunk_reset(&u->memchunk);
901
902     u->rtpoll = pa_rtpoll_new();
903     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
904
905     u->rtpoll_item = NULL;
906     build_pollfd(u);
907
908     if (u->mode != O_WRONLY) {
909         name_buf = NULL;
910         namereg_fail = TRUE;
911
912         if (!(name = pa_modargs_get_value(ma, "source_name", NULL))) {
913             name = name_buf = pa_sprintf_malloc("solaris_input.%s", pa_path_get_filename(u->device_name));
914             namereg_fail = FALSE;
915         }
916
917         pa_source_new_data_init(&source_new_data);
918         source_new_data.driver = __FILE__;
919         source_new_data.module = m;
920         pa_source_new_data_set_name(&source_new_data, name);
921         source_new_data.namereg_fail = namereg_fail;
922         pa_source_new_data_set_sample_spec(&source_new_data, &ss);
923         pa_source_new_data_set_channel_map(&source_new_data, &map);
924         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
925         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
926         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM source");
927         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
928         pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) u->buffer_size);
929
930         if (pa_modargs_get_proplist(ma, "source_properties", source_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
931             pa_log("Invalid properties");
932             pa_source_new_data_done(&source_new_data);
933             goto fail;
934         }
935
936         u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY);
937         pa_source_new_data_done(&source_new_data);
938         pa_xfree(name_buf);
939
940         if (!u->source) {
941             pa_log("Failed to create source object");
942             goto fail;
943         }
944
945         u->source->userdata = u;
946         u->source->parent.process_msg = source_process_msg;
947
948         pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
949         pa_source_set_rtpoll(u->source, u->rtpoll);
950         pa_source_set_fixed_latency(u->source, pa_bytes_to_usec(u->buffer_size, &u->source->sample_spec));
951
952         pa_source_set_get_volume_callback(u->source, source_get_volume);
953         pa_source_set_set_volume_callback(u->source, source_set_volume);
954         u->source->refresh_volume = TRUE;
955     } else
956         u->source = NULL;
957
958     if (u->mode != O_RDONLY) {
959         name_buf = NULL;
960         namereg_fail = TRUE;
961         if (!(name = pa_modargs_get_value(ma, "sink_name", NULL))) {
962             name = name_buf = pa_sprintf_malloc("solaris_output.%s", pa_path_get_filename(u->device_name));
963             namereg_fail = FALSE;
964         }
965
966         pa_sink_new_data_init(&sink_new_data);
967         sink_new_data.driver = __FILE__;
968         sink_new_data.module = m;
969         pa_sink_new_data_set_name(&sink_new_data, name);
970         sink_new_data.namereg_fail = namereg_fail;
971         pa_sink_new_data_set_sample_spec(&sink_new_data, &ss);
972         pa_sink_new_data_set_channel_map(&sink_new_data, &map);
973         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
974         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
975         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM sink");
976         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
977
978         if (pa_modargs_get_proplist(ma, "sink_properties", sink_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
979             pa_log("Invalid properties");
980             pa_sink_new_data_done(&sink_new_data);
981             goto fail;
982         }
983
984         u->sink = pa_sink_new(m->core, &sink_new_data, PA_SINK_HARDWARE|PA_SINK_LATENCY);
985         pa_sink_new_data_done(&sink_new_data);
986
987         pa_assert(u->sink);
988         u->sink->userdata = u;
989         u->sink->parent.process_msg = sink_process_msg;
990
991         pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
992         pa_sink_set_rtpoll(u->sink, u->rtpoll);
993         pa_sink_set_fixed_latency(u->sink, pa_bytes_to_usec(u->buffer_size, &u->sink->sample_spec));
994         pa_sink_set_max_request(u->sink, u->buffer_size);
995         pa_sink_set_max_rewind(u->sink, u->buffer_size);
996
997         pa_sink_set_get_volume_callback(u->sink, sink_get_volume);
998         pa_sink_set_set_volume_callback(u->sink, sink_set_volume);
999         pa_sink_set_get_mute_callback(u->sink, sink_get_mute);
1000         pa_sink_set_set_mute_callback(u->sink, sink_set_mute);
1001         u->sink->refresh_volume = u->sink->refresh_muted = TRUE;
1002     } else
1003         u->sink = NULL;
1004
1005     pa_assert(u->source || u->sink);
1006
1007     u->sig = pa_signal_new(SIGPOLL, sig_callback, u);
1008     if (u->sig)
1009         ioctl(u->fd, I_SETSIG, S_MSG);
1010     else
1011         pa_log_warn("Could not register SIGPOLL handler");
1012
1013     if (!(u->thread = pa_thread_new("solaris", thread_func, u))) {
1014         pa_log("Failed to create thread.");
1015         goto fail;
1016     }
1017
1018     /* Read mixer settings */
1019     if (u->sink) {
1020         if (sink_new_data.volume_is_set)
1021             u->sink->set_volume(u->sink);
1022         else
1023             u->sink->get_volume(u->sink);
1024
1025         if (sink_new_data.muted_is_set)
1026             u->sink->set_mute(u->sink);
1027         else
1028             u->sink->get_mute(u->sink);
1029
1030         pa_sink_put(u->sink);
1031     }
1032
1033     if (u->source) {
1034         if (source_new_data.volume_is_set)
1035             u->source->set_volume(u->source);
1036         else
1037             u->source->get_volume(u->source);
1038
1039         pa_source_put(u->source);
1040     }
1041
1042     pa_modargs_free(ma);
1043
1044     return 0;
1045
1046 fail:
1047     if (u)
1048         pa__done(m);
1049     else if (fd >= 0)
1050         close(fd);
1051
1052     if (ma)
1053         pa_modargs_free(ma);
1054
1055     return -1;
1056 }
1057
1058 void pa__done(pa_module *m) {
1059     struct userdata *u;
1060
1061     pa_assert(m);
1062
1063     if (!(u = m->userdata))
1064         return;
1065
1066     if (u->sig) {
1067         ioctl(u->fd, I_SETSIG, 0);
1068         pa_signal_free(u->sig);
1069     }
1070
1071     if (u->sink)
1072         pa_sink_unlink(u->sink);
1073
1074     if (u->source)
1075         pa_source_unlink(u->source);
1076
1077     if (u->thread) {
1078         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1079         pa_thread_free(u->thread);
1080     }
1081
1082     pa_thread_mq_done(&u->thread_mq);
1083
1084     if (u->sink)
1085         pa_sink_unref(u->sink);
1086
1087     if (u->source)
1088         pa_source_unref(u->source);
1089
1090     if (u->memchunk.memblock)
1091         pa_memblock_unref(u->memchunk.memblock);
1092
1093     if (u->rtpoll_item)
1094         pa_rtpoll_item_free(u->rtpoll_item);
1095
1096     if (u->rtpoll)
1097         pa_rtpoll_free(u->rtpoll);
1098
1099     if (u->fd >= 0)
1100         close(u->fd);
1101
1102     if (u->smoother)
1103         pa_smoother_free(u->smoother);
1104
1105     pa_xfree(u->device_name);
1106
1107     pa_xfree(u);
1108 }