Merge commit 'origin/master-tx'
[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     "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     pa_rtpoll_install(u->rtpoll);
609
610     for (;;) {
611         /* Render some data and write it to the dsp */
612
613         if (u->sink && PA_SINK_IS_OPENED(u->sink->thread_info.state)) {
614             pa_usec_t xtime0;
615             uint64_t buffered_bytes;
616
617             if (u->sink->thread_info.rewind_requested)
618                 process_rewind(u);
619
620             err = ioctl(u->fd, AUDIO_GETINFO, &info);
621             if (err < 0) {
622                 pa_log("AUDIO_GETINFO ioctl failed: %s", pa_cstrerror(errno));
623                 goto fail;
624             }
625
626             if (info.play.error) {
627                 pa_log_debug("buffer under-run!");
628
629                 AUDIO_INITINFO(&info);
630                 info.play.error = 0;
631                 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
632                     pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
633             }
634
635             for (;;) {
636                 void *p;
637                 ssize_t w;
638                 size_t len;
639
640                 /*
641                  * Since we cannot modify the size of the output buffer we fake it
642                  * by not filling it more than u->buffer_size.
643                  */
644                 xtime0 = pa_rtclock_usec();
645                 buffered_bytes = get_playback_buffered_bytes(u);
646                 if (buffered_bytes >= (uint64_t)u->buffer_size)
647                     break;
648
649                 len = u->buffer_size - buffered_bytes;
650                 len -= len % u->frame_size;
651
652                 if (len < (size_t) u->minimum_request)
653                     break;
654
655                 if (u->memchunk.length < len)
656                     pa_sink_render(u->sink, u->sink->thread_info.max_request, &u->memchunk);
657
658                 p = pa_memblock_acquire(u->memchunk.memblock);
659                 w = pa_write(u->fd, (uint8_t*) p + u->memchunk.index, u->memchunk.length, NULL);
660                 pa_memblock_release(u->memchunk.memblock);
661
662                 if (w <= 0) {
663                     switch (errno) {
664                         case EINTR:
665                             continue;
666                         case EAGAIN:
667                             /* If the buffer_size is too big, we get EAGAIN. Avoiding that limit by trial and error
668                              * is not ideal, but I don't know how to get the system to tell me what the limit is.
669                              */
670                             u->buffer_size = u->buffer_size * 18 / 25;
671                             u->buffer_size -= u->buffer_size % u->frame_size;
672                             u->buffer_size = PA_MAX(u->buffer_size, 2 * u->minimum_request);
673                             pa_sink_set_max_request_within_thread(u->sink, u->buffer_size);
674                             pa_sink_set_max_rewind_within_thread(u->sink, u->buffer_size);
675                             pa_log("EAGAIN. Buffer size is now %u bytes (%llu buffered)", u->buffer_size, buffered_bytes);
676                             break;
677                         default:
678                             pa_log("Failed to write data to DSP: %s", pa_cstrerror(errno));
679                             goto fail;
680                     }
681                 } else {
682                     pa_assert(w % u->frame_size == 0);
683
684                     u->written_bytes += w;
685                     u->memchunk.length -= w;
686
687                     u->memchunk.index += w;
688                     if (u->memchunk.length <= 0) {
689                         pa_memblock_unref(u->memchunk.memblock);
690                         pa_memchunk_reset(&u->memchunk);
691                     }
692                 }
693             }
694
695             pa_rtpoll_set_timer_absolute(u->rtpoll, xtime0 + pa_bytes_to_usec(buffered_bytes / 2, &u->sink->sample_spec));
696         } else
697             pa_rtpoll_set_timer_disabled(u->rtpoll);
698
699         /* Try to read some data and pass it on to the source driver */
700
701         if (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state) && (revents & POLLIN)) {
702             pa_memchunk memchunk;
703             void *p;
704             ssize_t r;
705             size_t len;
706
707             err = ioctl(u->fd, AUDIO_GETINFO, &info);
708             pa_assert(err >= 0);
709
710             if (info.record.error) {
711                 pa_log_debug("buffer overflow!");
712
713                 AUDIO_INITINFO(&info);
714                 info.record.error = 0;
715                 if (ioctl(u->fd, AUDIO_SETINFO, &info) < 0)
716                     pa_log("AUDIO_SETINFO: %s", pa_cstrerror(errno));
717             }
718
719             err = ioctl(u->fd, I_NREAD, &len);
720             pa_assert(err >= 0);
721
722             if (len > 0) {
723                 memchunk.memblock = pa_memblock_new(u->core->mempool, len);
724                 pa_assert(memchunk.memblock);
725
726                 p = pa_memblock_acquire(memchunk.memblock);
727                 r = pa_read(u->fd, p, len, NULL);
728                 pa_memblock_release(memchunk.memblock);
729
730                 if (r < 0) {
731                     pa_memblock_unref(memchunk.memblock);
732                     if (errno == EAGAIN)
733                         break;
734                     else {
735                         pa_log("Failed to read data from DSP: %s", pa_cstrerror(errno));
736                         goto fail;
737                     }
738                 } else {
739                     u->read_bytes += r;
740
741                     memchunk.index = 0;
742                     memchunk.length = r;
743
744                     pa_source_post(u->source, &memchunk);
745                     pa_memblock_unref(memchunk.memblock);
746
747                     revents &= ~POLLIN;
748                 }
749             }
750         }
751
752         if (u->rtpoll_item) {
753             struct pollfd *pollfd;
754
755             pa_assert(u->fd >= 0);
756
757             pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
758             pollfd->events = (u->source && PA_SOURCE_IS_OPENED(u->source->thread_info.state)) ? POLLIN : 0;
759         }
760
761         /* Hmm, nothing to do. Let's sleep */
762         if ((ret = pa_rtpoll_run(u->rtpoll, TRUE)) < 0)
763             goto fail;
764
765         if (ret == 0)
766             goto finish;
767
768         if (u->rtpoll_item) {
769             struct pollfd *pollfd;
770
771             pollfd = pa_rtpoll_item_get_pollfd(u->rtpoll_item, NULL);
772
773             if (pollfd->revents & ~(POLLOUT|POLLIN)) {
774                 pa_log("DSP shutdown.");
775                 goto fail;
776             }
777
778             revents = pollfd->revents;
779         } else
780             revents = 0;
781     }
782
783 fail:
784     /* We have to continue processing messages until we receive the
785      * SHUTDOWN message */
786     pa_asyncmsgq_post(u->thread_mq.outq, PA_MSGOBJECT(u->core), PA_CORE_MESSAGE_UNLOAD_MODULE, u->module, 0, NULL, NULL);
787     pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
788
789 finish:
790     pa_log_debug("Thread shutting down");
791 }
792
793 static void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) {
794     struct userdata *u = userdata;
795
796     assert(u);
797
798     pa_log_debug("caught signal");
799
800     if (u->sink) {
801         pa_sink_get_volume(u->sink, TRUE, FALSE);
802         pa_sink_get_mute(u->sink, TRUE);
803     }
804
805     if (u->source)
806         pa_source_get_volume(u->source, TRUE);
807 }
808
809 int pa__init(pa_module *m) {
810     struct userdata *u = NULL;
811     pa_bool_t record = TRUE, playback = TRUE;
812     pa_sample_spec ss;
813     pa_channel_map map;
814     pa_modargs *ma = NULL;
815     uint32_t buffer_length_msec;
816     int fd;
817     pa_sink_new_data sink_new_data;
818     pa_source_new_data source_new_data;
819     char const *name;
820     char *name_buf;
821     pa_bool_t namereg_fail;
822
823     pa_assert(m);
824
825     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
826         pa_log("failed to parse module arguments.");
827         goto fail;
828     }
829
830     if (pa_modargs_get_value_boolean(ma, "record", &record) < 0 || pa_modargs_get_value_boolean(ma, "playback", &playback) < 0) {
831         pa_log("record= and playback= expect a boolean argument.");
832         goto fail;
833     }
834
835     if (!playback && !record) {
836         pa_log("neither playback nor record enabled for device.");
837         goto fail;
838     }
839
840     u = pa_xnew0(struct userdata, 1);
841
842     /*
843      * For a process (or several processes) to use the same audio device for both
844      * record and playback at the same time, the device's mixer must be enabled.
845      * See mixerctl(1). It may be turned off for playback only or record only.
846      */
847     u->mode = (playback && record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
848
849     ss = m->core->default_sample_spec;
850     if (pa_modargs_get_sample_spec_and_channel_map(ma, &ss, &map, PA_CHANNEL_MAP_DEFAULT) < 0) {
851         pa_log("failed to parse sample specification");
852         goto fail;
853     }
854     u->frame_size = pa_frame_size(&ss);
855
856     u->minimum_request = pa_usec_to_bytes(PA_USEC_PER_SEC / MAX_RENDER_HZ, &ss);
857
858     buffer_length_msec = 100;
859     if (pa_modargs_get_value_u32(ma, "buffer_length", &buffer_length_msec) < 0) {
860         pa_log("failed to parse buffer_length argument");
861         goto fail;
862     }
863     u->buffer_size = pa_usec_to_bytes(1000 * buffer_length_msec, &ss);
864     if (u->buffer_size < 2 * u->minimum_request) {
865         pa_log("supplied buffer size argument is too small");
866         goto fail;
867     }
868
869     u->device_name = pa_xstrdup(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE));
870
871     if ((fd = open_audio_device(u, &ss)) < 0)
872         goto fail;
873
874     u->core = m->core;
875     u->module = m;
876     m->userdata = u;
877
878     pa_memchunk_reset(&u->memchunk);
879
880     u->rtpoll = pa_rtpoll_new();
881     pa_thread_mq_init(&u->thread_mq, m->core->mainloop, u->rtpoll);
882
883     u->rtpoll_item = NULL;
884     build_pollfd(u);
885
886     if (u->mode != O_WRONLY) {
887         name_buf = NULL;
888         namereg_fail = TRUE;
889
890         if (!(name = pa_modargs_get_value(ma, "source_name", NULL))) {
891             name = name_buf = pa_sprintf_malloc("solaris_input.%s", pa_path_get_filename(u->device_name));
892             namereg_fail = FALSE;
893         }
894
895         pa_source_new_data_init(&source_new_data);
896         source_new_data.driver = __FILE__;
897         source_new_data.module = m;
898         pa_source_new_data_set_name(&source_new_data, name);
899         source_new_data.namereg_fail = namereg_fail;
900         pa_source_new_data_set_sample_spec(&source_new_data, &ss);
901         pa_source_new_data_set_channel_map(&source_new_data, &map);
902         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
903         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
904         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM source");
905         pa_proplist_sets(source_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
906         pa_proplist_setf(source_new_data.proplist, PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE, "%lu", (unsigned long) u->buffer_size);
907
908         if (pa_modargs_get_proplist(ma, "source_properties", source_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
909             pa_log("Invalid properties");
910             pa_source_new_data_done(&source_new_data);
911             goto fail;
912         }
913
914         u->source = pa_source_new(m->core, &source_new_data, PA_SOURCE_HARDWARE|PA_SOURCE_LATENCY|PA_SOURCE_HW_VOLUME_CTRL);
915         pa_source_new_data_done(&source_new_data);
916         pa_xfree(name_buf);
917
918         if (!u->source) {
919             pa_log("Failed to create source object");
920             goto fail;
921         }
922
923         u->source->userdata = u;
924         u->source->parent.process_msg = source_process_msg;
925
926         pa_source_set_asyncmsgq(u->source, u->thread_mq.inq);
927         pa_source_set_rtpoll(u->source, u->rtpoll);
928
929         u->source->get_volume = source_get_volume;
930         u->source->set_volume = source_set_volume;
931         u->source->refresh_volume = TRUE;
932     } else
933         u->source = NULL;
934
935     if (u->mode != O_RDONLY) {
936         name_buf = NULL;
937         namereg_fail = TRUE;
938         if (!(name = pa_modargs_get_value(ma, "sink_name", NULL))) {
939             name = name_buf = pa_sprintf_malloc("solaris_output.%s", pa_path_get_filename(u->device_name));
940             namereg_fail = FALSE;
941         }
942
943         pa_sink_new_data_init(&sink_new_data);
944         sink_new_data.driver = __FILE__;
945         sink_new_data.module = m;
946         pa_sink_new_data_set_name(&sink_new_data, name);
947         sink_new_data.namereg_fail = namereg_fail;
948         pa_sink_new_data_set_sample_spec(&sink_new_data, &ss);
949         pa_sink_new_data_set_channel_map(&sink_new_data, &map);
950         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_STRING, u->device_name);
951         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_API, "solaris");
952         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_DESCRIPTION, "Solaris PCM sink");
953         pa_proplist_sets(sink_new_data.proplist, PA_PROP_DEVICE_ACCESS_MODE, "serial");
954
955         if (pa_modargs_get_proplist(ma, "sink_properties", sink_new_data.proplist, PA_UPDATE_REPLACE) < 0) {
956             pa_log("Invalid properties");
957             pa_sink_new_data_done(&sink_new_data);
958             goto fail;
959         }
960
961         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);
962         pa_sink_new_data_done(&sink_new_data);
963
964         pa_assert(u->sink);
965         u->sink->userdata = u;
966         u->sink->parent.process_msg = sink_process_msg;
967
968         pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
969         pa_sink_set_rtpoll(u->sink, u->rtpoll);
970
971         u->sink->get_volume = sink_get_volume;
972         u->sink->set_volume = sink_set_volume;
973         u->sink->get_mute = sink_get_mute;
974         u->sink->set_mute = sink_set_mute;
975         u->sink->refresh_volume = u->sink->refresh_muted = TRUE;
976
977         pa_sink_set_max_request(u->sink, u->buffer_size);
978         pa_sink_set_max_rewind(u->sink, u->buffer_size);
979     } else
980         u->sink = NULL;
981
982     pa_assert(u->source || u->sink);
983
984     u->sig = pa_signal_new(SIGPOLL, sig_callback, u);
985     if (u->sig)
986         ioctl(u->fd, I_SETSIG, S_MSG);
987     else
988         pa_log_warn("Could not register SIGPOLL handler");
989
990     if (!(u->thread = pa_thread_new(thread_func, u))) {
991         pa_log("Failed to create thread.");
992         goto fail;
993     }
994
995     /* Read mixer settings */
996     if (u->sink) {
997         if (sink_new_data.volume_is_set)
998             u->sink->set_volume(u->sink);
999         else
1000             u->sink->get_volume(u->sink);
1001
1002         if (sink_new_data.muted_is_set)
1003             u->sink->set_mute(u->sink);
1004         else
1005             u->sink->get_mute(u->sink);
1006
1007         pa_sink_put(u->sink);
1008     }
1009
1010     if (u->source) {
1011         if (source_new_data.volume_is_set)
1012             u->source->set_volume(u->source);
1013         else
1014             u->source->get_volume(u->source);
1015
1016         pa_source_put(u->source);
1017     }
1018
1019     pa_modargs_free(ma);
1020
1021     return 0;
1022
1023 fail:
1024     if (u)
1025         pa__done(m);
1026     else if (fd >= 0)
1027         close(fd);
1028
1029     if (ma)
1030         pa_modargs_free(ma);
1031
1032     return -1;
1033 }
1034
1035 void pa__done(pa_module *m) {
1036     struct userdata *u;
1037
1038     pa_assert(m);
1039
1040     if (!(u = m->userdata))
1041         return;
1042
1043     if (u->sig) {
1044         ioctl(u->fd, I_SETSIG, 0);
1045         pa_signal_free(u->sig);
1046     }
1047
1048     if (u->sink)
1049         pa_sink_unlink(u->sink);
1050
1051     if (u->source)
1052         pa_source_unlink(u->source);
1053
1054     if (u->thread) {
1055         pa_asyncmsgq_send(u->thread_mq.inq, NULL, PA_MESSAGE_SHUTDOWN, NULL, 0, NULL);
1056         pa_thread_free(u->thread);
1057     }
1058
1059     pa_thread_mq_done(&u->thread_mq);
1060
1061     if (u->sink)
1062         pa_sink_unref(u->sink);
1063
1064     if (u->source)
1065         pa_source_unref(u->source);
1066
1067     if (u->memchunk.memblock)
1068         pa_memblock_unref(u->memchunk.memblock);
1069
1070     if (u->rtpoll_item)
1071         pa_rtpoll_item_free(u->rtpoll_item);
1072
1073     if (u->rtpoll)
1074         pa_rtpoll_free(u->rtpoll);
1075
1076     if (u->fd >= 0)
1077         close(u->fd);
1078
1079     pa_xfree(u->device_name);
1080
1081     pa_xfree(u);
1082 }