~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/core/seq/oss/seq_oss_writeq.c

Version: ~ [ linux-5.9.1 ] ~ [ linux-5.8.16 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.72 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.152 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.202 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.240 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.240 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * OSS compatible sequencer driver
  3  *
  4  * seq_oss_writeq.c - write queue and sync
  5  *
  6  * Copyright (C) 1998,99 Takashi Iwai <tiwai@suse.de>
  7  *
  8  * This program is free software; you can redistribute it and/or modify
  9  * it under the terms of the GNU General Public License as published by
 10  * the Free Software Foundation; either version 2 of the License, or
 11  * (at your option) any later version.
 12  *
 13  * This program is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16  * GNU General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU General Public License
 19  * along with this program; if not, write to the Free Software
 20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 21  */
 22 
 23 #include "seq_oss_writeq.h"
 24 #include "seq_oss_event.h"
 25 #include "seq_oss_timer.h"
 26 #include <sound/seq_oss_legacy.h>
 27 #include "../seq_lock.h"
 28 #include "../seq_clientmgr.h"
 29 #include <linux/wait.h>
 30 #include <linux/slab.h>
 31 
 32 
 33 /*
 34  * create a write queue record
 35  */
 36 struct seq_oss_writeq *
 37 snd_seq_oss_writeq_new(struct seq_oss_devinfo *dp, int maxlen)
 38 {
 39         struct seq_oss_writeq *q;
 40         struct snd_seq_client_pool pool;
 41 
 42         if ((q = kzalloc(sizeof(*q), GFP_KERNEL)) == NULL)
 43                 return NULL;
 44         q->dp = dp;
 45         q->maxlen = maxlen;
 46         spin_lock_init(&q->sync_lock);
 47         q->sync_event_put = 0;
 48         q->sync_time = 0;
 49         init_waitqueue_head(&q->sync_sleep);
 50 
 51         memset(&pool, 0, sizeof(pool));
 52         pool.client = dp->cseq;
 53         pool.output_pool = maxlen;
 54         pool.output_room = maxlen / 2;
 55 
 56         snd_seq_oss_control(dp, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pool);
 57 
 58         return q;
 59 }
 60 
 61 /*
 62  * delete the write queue
 63  */
 64 void
 65 snd_seq_oss_writeq_delete(struct seq_oss_writeq *q)
 66 {
 67         if (q) {
 68                 snd_seq_oss_writeq_clear(q);    /* to be sure */
 69                 kfree(q);
 70         }
 71 }
 72 
 73 
 74 /*
 75  * reset the write queue
 76  */
 77 void
 78 snd_seq_oss_writeq_clear(struct seq_oss_writeq *q)
 79 {
 80         struct snd_seq_remove_events reset;
 81 
 82         memset(&reset, 0, sizeof(reset));
 83         reset.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT; /* remove all */
 84         snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, &reset);
 85 
 86         /* wake up sleepers if any */
 87         snd_seq_oss_writeq_wakeup(q, 0);
 88 }
 89 
 90 /*
 91  * wait until the write buffer has enough room
 92  */
 93 int
 94 snd_seq_oss_writeq_sync(struct seq_oss_writeq *q)
 95 {
 96         struct seq_oss_devinfo *dp = q->dp;
 97         abstime_t time;
 98 
 99         time = snd_seq_oss_timer_cur_tick(dp->timer);
100         if (q->sync_time >= time)
101                 return 0; /* already finished */
102 
103         if (! q->sync_event_put) {
104                 struct snd_seq_event ev;
105                 union evrec *rec;
106 
107                 /* put echoback event */
108                 memset(&ev, 0, sizeof(ev));
109                 ev.flags = 0;
110                 ev.type = SNDRV_SEQ_EVENT_ECHO;
111                 ev.time.tick = time;
112                 /* echo back to itself */
113                 snd_seq_oss_fill_addr(dp, &ev, dp->addr.client, dp->addr.port);
114                 rec = (union evrec *)&ev.data;
115                 rec->t.code = SEQ_SYNCTIMER;
116                 rec->t.time = time;
117                 q->sync_event_put = 1;
118                 snd_seq_kernel_client_enqueue_blocking(dp->cseq, &ev, NULL, 0, 0);
119         }
120 
121         wait_event_interruptible_timeout(q->sync_sleep, ! q->sync_event_put, HZ);
122         if (signal_pending(current))
123                 /* interrupted - return 0 to finish sync */
124                 q->sync_event_put = 0;
125         if (! q->sync_event_put || q->sync_time >= time)
126                 return 0;
127         return 1;
128 }
129 
130 /*
131  * wake up sync - echo event was catched
132  */
133 void
134 snd_seq_oss_writeq_wakeup(struct seq_oss_writeq *q, abstime_t time)
135 {
136         unsigned long flags;
137 
138         spin_lock_irqsave(&q->sync_lock, flags);
139         q->sync_time = time;
140         q->sync_event_put = 0;
141         if (waitqueue_active(&q->sync_sleep)) {
142                 wake_up(&q->sync_sleep);
143         }
144         spin_unlock_irqrestore(&q->sync_lock, flags);
145 }
146 
147 
148 /*
149  * return the unused pool size
150  */
151 int
152 snd_seq_oss_writeq_get_free_size(struct seq_oss_writeq *q)
153 {
154         struct snd_seq_client_pool pool;
155         pool.client = q->dp->cseq;
156         snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
157         return pool.output_free;
158 }
159 
160 
161 /*
162  * set output threshold size from ioctl
163  */
164 void
165 snd_seq_oss_writeq_set_output(struct seq_oss_writeq *q, int val)
166 {
167         struct snd_seq_client_pool pool;
168         pool.client = q->dp->cseq;
169         snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_GET_CLIENT_POOL, &pool);
170         pool.output_room = val;
171         snd_seq_oss_control(q->dp, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pool);
172 }
173 
174 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp