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