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