Diff markup
1 /* 1 /*
2 * ALSA sequencer Priority Queue 2 * ALSA sequencer Priority Queue
3 * Copyright (c) 1998-1999 by Frank van de P 3 * Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
4 * 4 *
5 * 5 *
6 * This program is free software; you can re 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Pub 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either vers 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope t 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even th 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICUL 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more detai 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GN 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 19 *
20 */ 20 */
21 21
22 #include <linux/time.h> 22 #include <linux/time.h>
23 #include <linux/slab.h> 23 #include <linux/slab.h>
24 #include <sound/core.h> 24 #include <sound/core.h>
25 #include "seq_timer.h" 25 #include "seq_timer.h"
26 #include "seq_prioq.h" 26 #include "seq_prioq.h"
27 27
28 28
29 /* Implementation is a simple linked list for 29 /* Implementation is a simple linked list for now...
30 30
31 This priority queue orders the events on ti 31 This priority queue orders the events on timestamp. For events with an
32 equeal timestamp the queue behaves as a FIF 32 equeal timestamp the queue behaves as a FIFO.
33 33
34 * 34 *
35 * +-------+ 35 * +-------+
36 * Head --> | first | 36 * Head --> | first |
37 * +-------+ 37 * +-------+
38 * |next 38 * |next
39 * +-----v-+ 39 * +-----v-+
40 * | | 40 * | |
41 * +-------+ 41 * +-------+
42 * | 42 * |
43 * +-----v-+ 43 * +-----v-+
44 * | | 44 * | |
45 * +-------+ 45 * +-------+
46 * | 46 * |
47 * +-----v-+ 47 * +-----v-+
48 * Tail --> | last | 48 * Tail --> | last |
49 * +-------+ 49 * +-------+
50 * 50 *
51 51
52 */ 52 */
53 53
54 54
55 55
56 /* create new prioq (constructor) */ 56 /* create new prioq (constructor) */
57 struct snd_seq_prioq *snd_seq_prioq_new(void) 57 struct snd_seq_prioq *snd_seq_prioq_new(void)
58 { 58 {
59 struct snd_seq_prioq *f; 59 struct snd_seq_prioq *f;
60 60
61 f = kzalloc(sizeof(*f), GFP_KERNEL); 61 f = kzalloc(sizeof(*f), GFP_KERNEL);
62 if (f == NULL) { 62 if (f == NULL) {
63 snd_printd("oops: malloc faile 63 snd_printd("oops: malloc failed for snd_seq_prioq_new()\n");
64 return NULL; 64 return NULL;
65 } 65 }
66 66
67 spin_lock_init(&f->lock); 67 spin_lock_init(&f->lock);
68 f->head = NULL; 68 f->head = NULL;
69 f->tail = NULL; 69 f->tail = NULL;
70 f->cells = 0; 70 f->cells = 0;
71 71
72 return f; 72 return f;
73 } 73 }
74 74
75 /* delete prioq (destructor) */ 75 /* delete prioq (destructor) */
76 void snd_seq_prioq_delete(struct snd_seq_prioq 76 void snd_seq_prioq_delete(struct snd_seq_prioq **fifo)
77 { 77 {
78 struct snd_seq_prioq *f = *fifo; 78 struct snd_seq_prioq *f = *fifo;
79 *fifo = NULL; 79 *fifo = NULL;
80 80
81 if (f == NULL) { 81 if (f == NULL) {
82 snd_printd("oops: snd_seq_prio 82 snd_printd("oops: snd_seq_prioq_delete() called with NULL prioq\n");
83 return; 83 return;
84 } 84 }
85 85
86 /* release resources...*/ 86 /* release resources...*/
87 /*....................*/ 87 /*....................*/
88 88
89 if (f->cells > 0) { 89 if (f->cells > 0) {
90 /* drain prioQ */ 90 /* drain prioQ */
91 while (f->cells > 0) 91 while (f->cells > 0)
92 snd_seq_cell_free(snd_ 92 snd_seq_cell_free(snd_seq_prioq_cell_out(f));
93 } 93 }
94 94
95 kfree(f); 95 kfree(f);
96 } 96 }
97 97
98 98
99 99
100 100
101 /* compare timestamp between events */ 101 /* compare timestamp between events */
102 /* return 1 if a >= b; 0 */ 102 /* return 1 if a >= b; 0 */
103 static inline int compare_timestamp(struct snd 103 static inline int compare_timestamp(struct snd_seq_event *a,
104 struct snd 104 struct snd_seq_event *b)
105 { 105 {
106 if ((a->flags & SNDRV_SEQ_TIME_STAMP_M 106 if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
107 /* compare ticks */ 107 /* compare ticks */
108 return (snd_seq_compare_tick_t 108 return (snd_seq_compare_tick_time(&a->time.tick, &b->time.tick));
109 } else { 109 } else {
110 /* compare real time */ 110 /* compare real time */
111 return (snd_seq_compare_real_t 111 return (snd_seq_compare_real_time(&a->time.time, &b->time.time));
112 } 112 }
113 } 113 }
114 114
115 /* compare timestamp between events */ 115 /* compare timestamp between events */
116 /* return negative if a < b; 116 /* return negative if a < b;
117 * zero if a = b; 117 * zero if a = b;
118 * positive if a > b; 118 * positive if a > b;
119 */ 119 */
120 static inline int compare_timestamp_rel(struct 120 static inline int compare_timestamp_rel(struct snd_seq_event *a,
121 struct 121 struct snd_seq_event *b)
122 { 122 {
123 if ((a->flags & SNDRV_SEQ_TIME_STAMP_M 123 if ((a->flags & SNDRV_SEQ_TIME_STAMP_MASK) == SNDRV_SEQ_TIME_STAMP_TICK) {
124 /* compare ticks */ 124 /* compare ticks */
125 if (a->time.tick > b->time.tic 125 if (a->time.tick > b->time.tick)
126 return 1; 126 return 1;
127 else if (a->time.tick == b->ti 127 else if (a->time.tick == b->time.tick)
128 return 0; 128 return 0;
129 else 129 else
130 return -1; 130 return -1;
131 } else { 131 } else {
132 /* compare real time */ 132 /* compare real time */
133 if (a->time.time.tv_sec > b->t 133 if (a->time.time.tv_sec > b->time.time.tv_sec)
134 return 1; 134 return 1;
135 else if (a->time.time.tv_sec = 135 else if (a->time.time.tv_sec == b->time.time.tv_sec) {
136 if (a->time.time.tv_ns 136 if (a->time.time.tv_nsec > b->time.time.tv_nsec)
137 return 1; 137 return 1;
138 else if (a->time.time. 138 else if (a->time.time.tv_nsec == b->time.time.tv_nsec)
139 return 0; 139 return 0;
140 else 140 else
141 return -1; 141 return -1;
142 } else 142 } else
143 return -1; 143 return -1;
144 } 144 }
145 } 145 }
146 146
147 /* enqueue cell to prioq */ 147 /* enqueue cell to prioq */
148 int snd_seq_prioq_cell_in(struct snd_seq_prioq 148 int snd_seq_prioq_cell_in(struct snd_seq_prioq * f,
149 struct snd_seq_event 149 struct snd_seq_event_cell * cell)
150 { 150 {
151 struct snd_seq_event_cell *cur, *prev; 151 struct snd_seq_event_cell *cur, *prev;
152 unsigned long flags; 152 unsigned long flags;
153 int count; 153 int count;
154 int prior; 154 int prior;
155 155
156 snd_assert(f, return -EINVAL); 156 snd_assert(f, return -EINVAL);
157 snd_assert(cell, return -EINVAL); 157 snd_assert(cell, return -EINVAL);
158 158
159 /* check flags */ 159 /* check flags */
160 prior = (cell->event.flags & SNDRV_SEQ 160 prior = (cell->event.flags & SNDRV_SEQ_PRIORITY_MASK);
161 161
162 spin_lock_irqsave(&f->lock, flags); 162 spin_lock_irqsave(&f->lock, flags);
163 163
164 /* check if this element needs to inse 164 /* check if this element needs to inserted at the end (ie. ordered
165 data is inserted) This will be very 165 data is inserted) This will be very likeley if a sequencer
166 application or midi file player is 166 application or midi file player is feeding us (sequential) data */
167 if (f->tail && !prior) { 167 if (f->tail && !prior) {
168 if (compare_timestamp(&cell->e 168 if (compare_timestamp(&cell->event, &f->tail->event)) {
169 /* add new cell to tai 169 /* add new cell to tail of the fifo */
170 f->tail->next = cell; 170 f->tail->next = cell;
171 f->tail = cell; 171 f->tail = cell;
172 cell->next = NULL; 172 cell->next = NULL;
173 f->cells++; 173 f->cells++;
174 spin_unlock_irqrestore 174 spin_unlock_irqrestore(&f->lock, flags);
175 return 0; 175 return 0;
176 } 176 }
177 } 177 }
178 /* traverse list of elements to find t 178 /* traverse list of elements to find the place where the new cell is
179 to be inserted... Note that this is 179 to be inserted... Note that this is a order n process ! */
180 180
181 prev = NULL; /* previous ce 181 prev = NULL; /* previous cell */
182 cur = f->head; /* cursor */ 182 cur = f->head; /* cursor */
183 183
184 count = 10000; /* FIXME: enough big, i 184 count = 10000; /* FIXME: enough big, isn't it? */
185 while (cur != NULL) { 185 while (cur != NULL) {
186 /* compare timestamps */ 186 /* compare timestamps */
187 int rel = compare_timestamp_re 187 int rel = compare_timestamp_rel(&cell->event, &cur->event);
188 if (rel < 0) 188 if (rel < 0)
189 /* new cell has earlie 189 /* new cell has earlier schedule time, */
190 break; 190 break;
191 else if (rel == 0 && prior) 191 else if (rel == 0 && prior)
192 /* equal schedule time 192 /* equal schedule time and prior to others */
193 break; 193 break;
194 /* new cell has equal or large 194 /* new cell has equal or larger schedule time, */
195 /* move cursor to next cell */ 195 /* move cursor to next cell */
196 prev = cur; 196 prev = cur;
197 cur = cur->next; 197 cur = cur->next;
198 if (! --count) { 198 if (! --count) {
199 spin_unlock_irqrestore 199 spin_unlock_irqrestore(&f->lock, flags);
200 snd_printk(KERN_ERR "c 200 snd_printk(KERN_ERR "cannot find a pointer.. infinite loop?\n");
201 return -EINVAL; 201 return -EINVAL;
202 } 202 }
203 } 203 }
204 204
205 /* insert it before cursor */ 205 /* insert it before cursor */
206 if (prev != NULL) 206 if (prev != NULL)
207 prev->next = cell; 207 prev->next = cell;
208 cell->next = cur; 208 cell->next = cur;
209 209
210 if (f->head == cur) /* this is the fir 210 if (f->head == cur) /* this is the first cell, set head to it */
211 f->head = cell; 211 f->head = cell;
212 if (cur == NULL) /* reached end of the 212 if (cur == NULL) /* reached end of the list */
213 f->tail = cell; 213 f->tail = cell;
214 f->cells++; 214 f->cells++;
215 spin_unlock_irqrestore(&f->lock, flags 215 spin_unlock_irqrestore(&f->lock, flags);
216 return 0; 216 return 0;
217 } 217 }
218 218
219 /* dequeue cell from prioq */ 219 /* dequeue cell from prioq */
220 struct snd_seq_event_cell *snd_seq_prioq_cell_ 220 struct snd_seq_event_cell *snd_seq_prioq_cell_out(struct snd_seq_prioq *f)
221 { 221 {
222 struct snd_seq_event_cell *cell; 222 struct snd_seq_event_cell *cell;
223 unsigned long flags; 223 unsigned long flags;
224 224
225 if (f == NULL) { 225 if (f == NULL) {
226 snd_printd("oops: snd_seq_prio 226 snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
227 return NULL; 227 return NULL;
228 } 228 }
229 spin_lock_irqsave(&f->lock, flags); 229 spin_lock_irqsave(&f->lock, flags);
230 230
231 cell = f->head; 231 cell = f->head;
232 if (cell) { 232 if (cell) {
233 f->head = cell->next; 233 f->head = cell->next;
234 234
235 /* reset tail if this was the 235 /* reset tail if this was the last element */
236 if (f->tail == cell) 236 if (f->tail == cell)
237 f->tail = NULL; 237 f->tail = NULL;
238 238
239 cell->next = NULL; 239 cell->next = NULL;
240 f->cells--; 240 f->cells--;
241 } 241 }
242 242
243 spin_unlock_irqrestore(&f->lock, flags 243 spin_unlock_irqrestore(&f->lock, flags);
244 return cell; 244 return cell;
245 } 245 }
246 246
247 /* return number of events available in prioq 247 /* return number of events available in prioq */
248 int snd_seq_prioq_avail(struct snd_seq_prioq * 248 int snd_seq_prioq_avail(struct snd_seq_prioq * f)
249 { 249 {
250 if (f == NULL) { 250 if (f == NULL) {
251 snd_printd("oops: snd_seq_prio 251 snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
252 return 0; 252 return 0;
253 } 253 }
254 return f->cells; 254 return f->cells;
255 } 255 }
256 256
257 257
258 /* peek at cell at the head of the prioq */ 258 /* peek at cell at the head of the prioq */
259 struct snd_seq_event_cell *snd_seq_prioq_cell_ 259 struct snd_seq_event_cell *snd_seq_prioq_cell_peek(struct snd_seq_prioq * f)
260 { 260 {
261 if (f == NULL) { 261 if (f == NULL) {
262 snd_printd("oops: snd_seq_prio 262 snd_printd("oops: snd_seq_prioq_cell_in() called with NULL prioq\n");
263 return NULL; 263 return NULL;
264 } 264 }
265 return f->head; 265 return f->head;
266 } 266 }
267 267
268 268
269 static inline int prioq_match(struct snd_seq_e 269 static inline int prioq_match(struct snd_seq_event_cell *cell,
270 int client, int 270 int client, int timestamp)
271 { 271 {
272 if (cell->event.source.client == clien 272 if (cell->event.source.client == client ||
273 cell->event.dest.client == client) 273 cell->event.dest.client == client)
274 return 1; 274 return 1;
275 if (!timestamp) 275 if (!timestamp)
276 return 0; 276 return 0;
277 switch (cell->event.flags & SNDRV_SEQ_ 277 switch (cell->event.flags & SNDRV_SEQ_TIME_STAMP_MASK) {
278 case SNDRV_SEQ_TIME_STAMP_TICK: 278 case SNDRV_SEQ_TIME_STAMP_TICK:
279 if (cell->event.time.tick) 279 if (cell->event.time.tick)
280 return 1; 280 return 1;
281 break; 281 break;
282 case SNDRV_SEQ_TIME_STAMP_REAL: 282 case SNDRV_SEQ_TIME_STAMP_REAL:
283 if (cell->event.time.time.tv_s 283 if (cell->event.time.time.tv_sec ||
284 cell->event.time.time.tv_n 284 cell->event.time.time.tv_nsec)
285 return 1; 285 return 1;
286 break; 286 break;
287 } 287 }
288 return 0; 288 return 0;
289 } 289 }
290 290
291 /* remove cells for left client */ 291 /* remove cells for left client */
292 void snd_seq_prioq_leave(struct snd_seq_prioq 292 void snd_seq_prioq_leave(struct snd_seq_prioq * f, int client, int timestamp)
293 { 293 {
294 register struct snd_seq_event_cell *ce 294 register struct snd_seq_event_cell *cell, *next;
295 unsigned long flags; 295 unsigned long flags;
296 struct snd_seq_event_cell *prev = NULL 296 struct snd_seq_event_cell *prev = NULL;
297 struct snd_seq_event_cell *freefirst = 297 struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
298 298
299 /* collect all removed cells */ 299 /* collect all removed cells */
300 spin_lock_irqsave(&f->lock, flags); 300 spin_lock_irqsave(&f->lock, flags);
301 cell = f->head; 301 cell = f->head;
302 while (cell) { 302 while (cell) {
303 next = cell->next; 303 next = cell->next;
304 if (prioq_match(cell, client, 304 if (prioq_match(cell, client, timestamp)) {
305 /* remove cell from pr 305 /* remove cell from prioq */
306 if (cell == f->head) { 306 if (cell == f->head) {
307 f->head = cell 307 f->head = cell->next;
308 } else { 308 } else {
309 prev->next = c 309 prev->next = cell->next;
310 } 310 }
311 if (cell == f->tail) 311 if (cell == f->tail)
312 f->tail = cell 312 f->tail = cell->next;
313 f->cells--; 313 f->cells--;
314 /* add cell to free li 314 /* add cell to free list */
315 cell->next = NULL; 315 cell->next = NULL;
316 if (freefirst == NULL) 316 if (freefirst == NULL) {
317 freefirst = ce 317 freefirst = cell;
318 } else { 318 } else {
319 freeprev->next 319 freeprev->next = cell;
320 } 320 }
321 freeprev = cell; 321 freeprev = cell;
322 } else { 322 } else {
323 #if 0 323 #if 0
324 printk("type = %i, sou 324 printk("type = %i, source = %i, dest = %i, client = %i\n",
325 cell->event.ty 325 cell->event.type,
326 cell->event.so 326 cell->event.source.client,
327 cell->event.de 327 cell->event.dest.client,
328 client); 328 client);
329 #endif 329 #endif
330 prev = cell; 330 prev = cell;
331 } 331 }
332 cell = next; 332 cell = next;
333 } 333 }
334 spin_unlock_irqrestore(&f->lock, flags 334 spin_unlock_irqrestore(&f->lock, flags);
335 335
336 /* remove selected cells */ 336 /* remove selected cells */
337 while (freefirst) { 337 while (freefirst) {
338 freenext = freefirst->next; 338 freenext = freefirst->next;
339 snd_seq_cell_free(freefirst); 339 snd_seq_cell_free(freefirst);
340 freefirst = freenext; 340 freefirst = freenext;
341 } 341 }
342 } 342 }
343 343
344 static int prioq_remove_match(struct snd_seq_r 344 static int prioq_remove_match(struct snd_seq_remove_events *info,
345 struct snd_seq_e 345 struct snd_seq_event *ev)
346 { 346 {
347 int res; 347 int res;
348 348
349 if (info->remove_mode & SNDRV_SEQ_REMO 349 if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
350 if (ev->dest.client != info->d 350 if (ev->dest.client != info->dest.client ||
351 ev->dest.port 351 ev->dest.port != info->dest.port)
352 return 0; 352 return 0;
353 } 353 }
354 if (info->remove_mode & SNDRV_SEQ_REMO 354 if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
355 if (! snd_seq_ev_is_channel_ty 355 if (! snd_seq_ev_is_channel_type(ev))
356 return 0; 356 return 0;
357 /* data.note.channel and data. 357 /* data.note.channel and data.control.channel are identical */
358 if (ev->data.note.channel != i 358 if (ev->data.note.channel != info->channel)
359 return 0; 359 return 0;
360 } 360 }
361 if (info->remove_mode & SNDRV_SEQ_REMO 361 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
362 if (info->remove_mode & SNDRV_ 362 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
363 res = snd_seq_compare_ 363 res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
364 else 364 else
365 res = snd_seq_compare_ 365 res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
366 if (!res) 366 if (!res)
367 return 0; 367 return 0;
368 } 368 }
369 if (info->remove_mode & SNDRV_SEQ_REMO 369 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
370 if (info->remove_mode & SNDRV_ 370 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
371 res = snd_seq_compare_ 371 res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
372 else 372 else
373 res = snd_seq_compare_ 373 res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
374 if (res) 374 if (res)
375 return 0; 375 return 0;
376 } 376 }
377 if (info->remove_mode & SNDRV_SEQ_REMO 377 if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
378 if (ev->type != info->type) 378 if (ev->type != info->type)
379 return 0; 379 return 0;
380 } 380 }
381 if (info->remove_mode & SNDRV_SEQ_REMO 381 if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
382 /* Do not remove off events */ 382 /* Do not remove off events */
383 switch (ev->type) { 383 switch (ev->type) {
384 case SNDRV_SEQ_EVENT_NOTEOFF: 384 case SNDRV_SEQ_EVENT_NOTEOFF:
385 /* case SNDRV_SEQ_EVENT_SAMPLE 385 /* case SNDRV_SEQ_EVENT_SAMPLE_STOP: */
386 return 0; 386 return 0;
387 default: 387 default:
388 break; 388 break;
389 } 389 }
390 } 390 }
391 if (info->remove_mode & SNDRV_SEQ_REMO 391 if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
392 if (info->tag != ev->tag) 392 if (info->tag != ev->tag)
393 return 0; 393 return 0;
394 } 394 }
395 395
396 return 1; 396 return 1;
397 } 397 }
398 398
399 /* remove cells matching remove criteria */ 399 /* remove cells matching remove criteria */
400 void snd_seq_prioq_remove_events(struct snd_se 400 void snd_seq_prioq_remove_events(struct snd_seq_prioq * f, int client,
401 struct snd_se 401 struct snd_seq_remove_events *info)
402 { 402 {
403 struct snd_seq_event_cell *cell, *next 403 struct snd_seq_event_cell *cell, *next;
404 unsigned long flags; 404 unsigned long flags;
405 struct snd_seq_event_cell *prev = NULL 405 struct snd_seq_event_cell *prev = NULL;
406 struct snd_seq_event_cell *freefirst = 406 struct snd_seq_event_cell *freefirst = NULL, *freeprev = NULL, *freenext;
407 407
408 /* collect all removed cells */ 408 /* collect all removed cells */
409 spin_lock_irqsave(&f->lock, flags); 409 spin_lock_irqsave(&f->lock, flags);
410 cell = f->head; 410 cell = f->head;
411 411
412 while (cell) { 412 while (cell) {
413 next = cell->next; 413 next = cell->next;
414 if (cell->event.source.client 414 if (cell->event.source.client == client &&
415 prioq_remove_match(inf 415 prioq_remove_match(info, &cell->event)) {
416 416
417 /* remove cell from pr 417 /* remove cell from prioq */
418 if (cell == f->head) { 418 if (cell == f->head) {
419 f->head = cell 419 f->head = cell->next;
420 } else { 420 } else {
421 prev->next = c 421 prev->next = cell->next;
422 } 422 }
423 423
424 if (cell == f->tail) 424 if (cell == f->tail)
425 f->tail = cell 425 f->tail = cell->next;
426 f->cells--; 426 f->cells--;
427 427
428 /* add cell to free li 428 /* add cell to free list */
429 cell->next = NULL; 429 cell->next = NULL;
430 if (freefirst == NULL) 430 if (freefirst == NULL) {
431 freefirst = ce 431 freefirst = cell;
432 } else { 432 } else {
433 freeprev->next 433 freeprev->next = cell;
434 } 434 }
435 435
436 freeprev = cell; 436 freeprev = cell;
437 } else { 437 } else {
438 prev = cell; 438 prev = cell;
439 } 439 }
440 cell = next; 440 cell = next;
441 } 441 }
442 spin_unlock_irqrestore(&f->lock, flags 442 spin_unlock_irqrestore(&f->lock, flags);
443 443
444 /* remove selected cells */ 444 /* remove selected cells */
445 while (freefirst) { 445 while (freefirst) {
446 freenext = freefirst->next; 446 freenext = freefirst->next;
447 snd_seq_cell_free(freefirst); 447 snd_seq_cell_free(freefirst);
448 freefirst = freenext; 448 freefirst = freenext;
449 } 449 }
450 } 450 }
451 451
452 452
453 453
|
This page was automatically generated by the
LXR engine.
|