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