]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/sound/clone.c
sqlite3: Vendor import of sqlite3 3.37.2
[FreeBSD/FreeBSD.git] / sys / dev / sound / clone.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2007 Ariff Abdullah <ariff@FreeBSD.org>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/conf.h>
34 #include <sys/kernel.h>
35 #include <sys/malloc.h>
36 #include <sys/proc.h>
37
38 #ifdef HAVE_KERNEL_OPTION_HEADERS
39 #include "opt_snd.h"
40 #endif
41
42 #if defined(SND_DIAGNOSTIC) || defined(SND_DEBUG)
43 #include <dev/sound/pcm/sound.h>
44 #endif
45
46 #include <dev/sound/clone.h>
47
48 /*
49  * So here we go again, another clonedevs manager. Unlike default clonedevs,
50  * this clone manager is designed to withstand various abusive behavior
51  * (such as 'while : ; do ls /dev/whatever ; done', etc.), reusable object
52  * after reaching certain expiration threshold, aggressive garbage collector,
53  * transparent device allocator and concurrency handling across multiple
54  * thread/proc. Due to limited information given by dev_clone EVENTHANDLER,
55  * we don't have much clues whether the caller wants a real open() or simply
56  * making fun of us with things like stat(), mtime() etc. Assuming that:
57  * 1) Time window between dev_clone EH <-> real open() should be small
58  * enough and 2) mtime()/stat() etc. always looks like a half way / stalled
59  * operation, we can decide whether a new cdev must be created, old
60  * (expired) cdev can be reused or an existing cdev can be shared.
61  *
62  * Most of the operations and logics are generic enough and can be applied
63  * on other places (such as if_tap, snp, etc).  Perhaps this can be
64  * rearranged to complement clone_*(). However, due to this still being
65  * specific to the sound driver (and as a proof of concept on how it can be
66  * done), si_drv2 is used to keep the pointer of the clone list entry to
67  * avoid expensive lookup.
68  */
69
70 /* clone entry */
71 struct snd_clone_entry {
72         TAILQ_ENTRY(snd_clone_entry) link;
73         struct snd_clone *parent;
74         struct cdev *devt;
75         struct timespec tsp;
76         uint32_t flags;
77         pid_t pid;
78         int unit;
79 };
80
81 /* clone manager */
82 struct snd_clone {
83         TAILQ_HEAD(link_head, snd_clone_entry) head;
84         struct timespec tsp;
85         int refcount;
86         int size;
87         int typemask;
88         int maxunit;
89         int deadline;
90         uint32_t flags;
91 };
92
93 #ifdef SND_DIAGNOSTIC
94 #define SND_CLONE_ASSERT(x, y)          do {                    \
95         if (!(x))                                               \
96                 panic y;                                        \
97 } while (0)
98 #else
99 #define SND_CLONE_ASSERT(...)           KASSERT(__VA_ARGS__)
100 #endif
101
102 /*
103  * snd_clone_create() : Return opaque allocated clone manager.
104  */
105 struct snd_clone *
106 snd_clone_create(int typemask, int maxunit, int deadline, uint32_t flags)
107 {
108         struct snd_clone *c;
109
110         SND_CLONE_ASSERT(!(typemask & ~SND_CLONE_MAXUNIT),
111             ("invalid typemask: 0x%08x", typemask));
112         SND_CLONE_ASSERT(maxunit == -1 ||
113             !(maxunit & ~(~typemask & SND_CLONE_MAXUNIT)),
114             ("maxunit overflow: typemask=0x%08x maxunit=%d",
115             typemask, maxunit));
116         SND_CLONE_ASSERT(!(flags & ~SND_CLONE_MASK),
117             ("invalid clone flags=0x%08x", flags));
118
119         c = malloc(sizeof(*c), M_DEVBUF, M_WAITOK | M_ZERO);
120         c->refcount = 0;
121         c->size = 0;
122         c->typemask = typemask;
123         c->maxunit = (maxunit == -1) ? (~typemask & SND_CLONE_MAXUNIT) :
124             maxunit;
125         c->deadline = deadline;
126         c->flags = flags;
127         getnanouptime(&c->tsp);
128         TAILQ_INIT(&c->head);
129
130         return (c);
131 }
132
133 int
134 snd_clone_busy(struct snd_clone *c)
135 {
136         struct snd_clone_entry *ce;
137
138         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
139
140         if (c->size == 0)
141                 return (0);
142
143         TAILQ_FOREACH(ce, &c->head, link) {
144                 if ((ce->flags & SND_CLONE_BUSY) ||
145                     (ce->devt != NULL && ce->devt->si_threadcount != 0))
146                         return (EBUSY);
147         }
148
149         return (0);
150 }
151
152 /*
153  * snd_clone_enable()/disable() : Suspend/resume clone allocation through
154  * snd_clone_alloc(). Everything else will not be affected by this.
155  */
156 int
157 snd_clone_enable(struct snd_clone *c)
158 {
159         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
160
161         if (c->flags & SND_CLONE_ENABLE)
162                 return (EINVAL);
163
164         c->flags |= SND_CLONE_ENABLE;
165
166         return (0);
167 }
168
169 int
170 snd_clone_disable(struct snd_clone *c)
171 {
172         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
173
174         if (!(c->flags & SND_CLONE_ENABLE))
175                 return (EINVAL);
176
177         c->flags &= ~SND_CLONE_ENABLE;
178
179         return (0);
180 }
181
182 /*
183  * Getters / Setters. Not worth explaining :)
184  */
185 int
186 snd_clone_getsize(struct snd_clone *c)
187 {
188         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
189
190         return (c->size);
191 }
192
193 int
194 snd_clone_getmaxunit(struct snd_clone *c)
195 {
196         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
197
198         return (c->maxunit);
199 }
200
201 int
202 snd_clone_setmaxunit(struct snd_clone *c, int maxunit)
203 {
204         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
205         SND_CLONE_ASSERT(maxunit == -1 ||
206             !(maxunit & ~(~c->typemask & SND_CLONE_MAXUNIT)),
207             ("maxunit overflow: typemask=0x%08x maxunit=%d",
208             c->typemask, maxunit));
209
210         c->maxunit = (maxunit == -1) ? (~c->typemask & SND_CLONE_MAXUNIT) :
211             maxunit;
212
213         return (c->maxunit);
214 }
215
216 int
217 snd_clone_getdeadline(struct snd_clone *c)
218 {
219         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
220
221         return (c->deadline);
222 }
223
224 int
225 snd_clone_setdeadline(struct snd_clone *c, int deadline)
226 {
227         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
228
229         c->deadline = deadline;
230
231         return (c->deadline);
232 }
233
234 uint32_t
235 snd_clone_getflags(struct snd_clone *c)
236 {
237         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
238
239         return (c->flags);
240 }
241
242 uint32_t
243 snd_clone_setflags(struct snd_clone *c, uint32_t flags)
244 {
245         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
246         SND_CLONE_ASSERT(!(flags & ~SND_CLONE_MASK),
247             ("invalid clone flags=0x%08x", flags));
248
249         c->flags = flags;
250
251         return (c->flags);
252 }
253
254 uint32_t
255 snd_clone_getdevflags(struct cdev *dev)
256 {
257         struct snd_clone_entry *ce;
258
259         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
260
261         ce = dev->si_drv2;
262         if (ce == NULL)
263                 return (0xffffffff);
264
265         SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
266
267         return (ce->flags);
268 }
269
270 uint32_t
271 snd_clone_setdevflags(struct cdev *dev, uint32_t flags)
272 {
273         struct snd_clone_entry *ce;
274
275         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
276         SND_CLONE_ASSERT(!(flags & ~SND_CLONE_DEVMASK),
277             ("invalid clone dev flags=0x%08x", flags));
278
279         ce = dev->si_drv2;
280         if (ce == NULL)
281                 return (0xffffffff);
282
283         SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
284
285         ce->flags = flags;
286
287         return (ce->flags);
288 }
289
290 /* Elapsed time conversion to ms */
291 #define SND_CLONE_ELAPSED(x, y)                                         \
292         ((((x)->tv_sec - (y)->tv_sec) * 1000) +                         \
293         (((y)->tv_nsec > (x)->tv_nsec) ?                                \
294         (((1000000000L + (x)->tv_nsec -                                 \
295         (y)->tv_nsec) / 1000000) - 1000) :                              \
296         (((x)->tv_nsec - (y)->tv_nsec) / 1000000)))
297
298 #define SND_CLONE_EXPIRED(x, y, z)                                      \
299         ((x)->deadline < 1 ||                                           \
300         ((y)->tv_sec - (z)->tv_sec) > ((x)->deadline / 1000) ||         \
301         SND_CLONE_ELAPSED(y, z) > (x)->deadline)
302
303 /*
304  * snd_clone_gc() : Garbage collector for stalled, expired objects. Refer to
305  * clone.h for explanations on GC settings.
306  */
307 int
308 snd_clone_gc(struct snd_clone *c)
309 {
310         struct snd_clone_entry *ce, *tce;
311         struct timespec now;
312         int pruned;
313
314         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
315
316         if (!(c->flags & SND_CLONE_GC_ENABLE) || c->size == 0)
317                 return (0);
318
319         getnanouptime(&now);
320
321         /*
322          * Bail out if the last clone handler was invoked below the deadline
323          * threshold.
324          */
325         if ((c->flags & SND_CLONE_GC_EXPIRED) &&
326             !SND_CLONE_EXPIRED(c, &now, &c->tsp))
327                 return (0);
328
329         pruned = 0;
330
331         /*
332          * Visit each object in reverse order. If the object is still being
333          * referenced by a valid open(), skip it. Look for expired objects
334          * and either revoke its clone invocation status or mercilessly
335          * throw it away.
336          */
337         TAILQ_FOREACH_REVERSE_SAFE(ce, &c->head, link_head, link, tce) {
338                 if (!(ce->flags & SND_CLONE_BUSY) &&
339                     (!(ce->flags & SND_CLONE_INVOKE) ||
340                     SND_CLONE_EXPIRED(c, &now, &ce->tsp))) {
341                         if ((c->flags & SND_CLONE_GC_REVOKE) ||
342                             ce->devt->si_threadcount != 0) {
343                                 ce->flags &= ~SND_CLONE_INVOKE;
344                                 ce->pid = -1;
345                         } else {
346                                 TAILQ_REMOVE(&c->head, ce, link);
347                                 destroy_dev(ce->devt);
348                                 free(ce, M_DEVBUF);
349                                 c->size--;
350                         }
351                         pruned++;
352                 }
353         }
354
355         /* return total pruned objects */
356         return (pruned);
357 }
358
359 void
360 snd_clone_destroy(struct snd_clone *c)
361 {
362         struct snd_clone_entry *ce, *tmp;
363
364         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
365
366         ce = TAILQ_FIRST(&c->head);
367         while (ce != NULL) {
368                 tmp = TAILQ_NEXT(ce, link);
369                 if (ce->devt != NULL)
370                         destroy_dev(ce->devt);
371                 free(ce, M_DEVBUF);
372                 ce = tmp;
373         }
374
375         free(c, M_DEVBUF);
376 }
377
378 /*
379  * snd_clone_acquire() : The vital part of concurrency management. Must be
380  * called somewhere at the beginning of open() handler. ENODEV is not really
381  * fatal since it just tell the caller that this is not cloned stuff.
382  * EBUSY is *real*, don't forget that!
383  */
384 int
385 snd_clone_acquire(struct cdev *dev)
386 {
387         struct snd_clone_entry *ce;
388
389         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
390
391         ce = dev->si_drv2;
392         if (ce == NULL)
393                 return (ENODEV);
394
395         SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
396
397         ce->flags &= ~SND_CLONE_INVOKE;
398
399         if (ce->flags & SND_CLONE_BUSY)
400                 return (EBUSY);
401
402         ce->flags |= SND_CLONE_BUSY;
403
404         return (0);
405 }
406
407 /*
408  * snd_clone_release() : Release busy status. Must be called somewhere at
409  * the end of close() handler, or somewhere after fail open().
410  */
411 int
412 snd_clone_release(struct cdev *dev)
413 {
414         struct snd_clone_entry *ce;
415
416         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
417
418         ce = dev->si_drv2;
419         if (ce == NULL)
420                 return (ENODEV);
421
422         SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
423
424         ce->flags &= ~SND_CLONE_INVOKE;
425
426         if (!(ce->flags & SND_CLONE_BUSY))
427                 return (EBADF);
428
429         ce->flags &= ~SND_CLONE_BUSY;
430         ce->pid = -1;
431
432         return (0);
433 }
434
435 /*
436  * snd_clone_ref/unref() : Garbage collector reference counter. To make
437  * garbage collector run automatically, the sequence must be something like
438  * this (both in open() and close() handlers):
439  *
440  *  open() - 1) snd_clone_acquire()
441  *           2) .... check check ... if failed, snd_clone_release()
442  *           3) Success. Call snd_clone_ref()
443  *
444  * close() - 1) .... check check check ....
445  *           2) Success. snd_clone_release()
446  *           3) snd_clone_unref() . Garbage collector will run at this point
447  *              if this is the last referenced object.
448  */
449 int
450 snd_clone_ref(struct cdev *dev)
451 {
452         struct snd_clone_entry *ce;
453         struct snd_clone *c;
454
455         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
456
457         ce = dev->si_drv2;
458         if (ce == NULL)
459                 return (0);
460
461         c = ce->parent;
462         SND_CLONE_ASSERT(c != NULL, ("NULL parent"));
463         SND_CLONE_ASSERT(c->refcount >= 0, ("refcount < 0"));
464
465         return (++c->refcount);
466 }
467
468 int
469 snd_clone_unref(struct cdev *dev)
470 {
471         struct snd_clone_entry *ce;
472         struct snd_clone *c;
473
474         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
475
476         ce = dev->si_drv2;
477         if (ce == NULL)
478                 return (0);
479
480         c = ce->parent;
481         SND_CLONE_ASSERT(c != NULL, ("NULL parent"));
482         SND_CLONE_ASSERT(c->refcount > 0, ("refcount <= 0"));
483
484         c->refcount--;
485
486         /* 
487          * Run automatic garbage collector, if needed.
488          */
489         if ((c->flags & SND_CLONE_GC_UNREF) &&
490             (!(c->flags & SND_CLONE_GC_LASTREF) ||
491             (c->refcount == 0 && (c->flags & SND_CLONE_GC_LASTREF))))
492                 (void)snd_clone_gc(c);
493
494         return (c->refcount);
495 }
496
497 void
498 snd_clone_register(struct snd_clone_entry *ce, struct cdev *dev)
499 {
500         SND_CLONE_ASSERT(ce != NULL, ("NULL snd_clone_entry"));
501         SND_CLONE_ASSERT(dev != NULL, ("NULL dev"));
502         SND_CLONE_ASSERT(dev->si_drv2 == NULL, ("dev->si_drv2 not NULL"));
503         SND_CLONE_ASSERT((ce->flags & SND_CLONE_ALLOC) == SND_CLONE_ALLOC,
504             ("invalid clone alloc flags=0x%08x", ce->flags));
505         SND_CLONE_ASSERT(ce->devt == NULL, ("ce->devt not NULL"));
506         SND_CLONE_ASSERT(ce->unit == dev2unit(dev),
507             ("invalid unit ce->unit=0x%08x dev2unit=0x%08x",
508             ce->unit, dev2unit(dev)));
509
510         SND_CLONE_ASSERT(ce->parent != NULL, ("NULL parent"));
511
512         dev->si_drv2 = ce;
513         ce->devt = dev;
514         ce->flags &= ~SND_CLONE_ALLOC;
515         ce->flags |= SND_CLONE_INVOKE;
516 }
517
518 struct snd_clone_entry *
519 snd_clone_alloc(struct snd_clone *c, struct cdev **dev, int *unit, int tmask)
520 {
521         struct snd_clone_entry *ce, *after, *bce, *cce, *nce, *tce;
522         struct timespec now;
523         int cunit, allocunit;
524         pid_t curpid;
525
526         SND_CLONE_ASSERT(c != NULL, ("NULL snd_clone"));
527         SND_CLONE_ASSERT(dev != NULL, ("NULL dev pointer"));
528         SND_CLONE_ASSERT((c->typemask & tmask) == tmask,
529             ("invalid tmask: typemask=0x%08x tmask=0x%08x",
530             c->typemask, tmask));
531         SND_CLONE_ASSERT(unit != NULL, ("NULL unit pointer"));
532         SND_CLONE_ASSERT(*unit == -1 || !(*unit & (c->typemask | tmask)),
533             ("typemask collision: typemask=0x%08x tmask=0x%08x *unit=%d",
534             c->typemask, tmask, *unit));
535
536         if (!(c->flags & SND_CLONE_ENABLE) ||
537             (*unit != -1 && *unit > c->maxunit))
538                 return (NULL);
539
540         ce = NULL;
541         after = NULL;
542         bce = NULL;     /* "b"usy candidate */
543         cce = NULL;     /* "c"urthread/proc candidate */
544         nce = NULL;     /* "n"ull, totally unbusy candidate */
545         tce = NULL;     /* Last "t"ry candidate */
546         cunit = 0;
547         allocunit = (*unit == -1) ? 0 : *unit;
548         curpid = curthread->td_proc->p_pid;
549
550         getnanouptime(&now);
551
552         TAILQ_FOREACH(ce, &c->head, link) {
553                 /*
554                  * Sort incrementally according to device type.
555                  */
556                 if (tmask > (ce->unit & c->typemask)) {
557                         if (cunit == 0)
558                                 after = ce;
559                         continue;
560                 } else if (tmask < (ce->unit & c->typemask))
561                         break;
562
563                 /*
564                  * Shoot.. this is where the grumpiness begin. Just
565                  * return immediately.
566                  */
567                 if (*unit != -1 && *unit == (ce->unit & ~tmask))
568                         goto snd_clone_alloc_out;
569
570                 cunit++;
571                 /*
572                  * Simmilar device type. Sort incrementally according
573                  * to allocation unit. While here, look for free slot
574                  * and possible collision for new / future allocation.
575                  */
576                 if (*unit == -1 && (ce->unit & ~tmask) == allocunit)
577                         allocunit++;
578                 if ((ce->unit & ~tmask) < allocunit)
579                         after = ce;
580                 /*
581                  * Clone logic:
582                  *   1. Look for non busy, but keep track of the best
583                  *      possible busy cdev.
584                  *   2. Look for the best (oldest referenced) entry that is
585                  *      in a same process / thread.
586                  *   3. Look for the best (oldest referenced), absolute free
587                  *      entry.
588                  *   4. Lastly, look for the best (oldest referenced)
589                  *      any entries that doesn't fit with anything above.
590                  */
591                 if (ce->flags & SND_CLONE_BUSY) {
592                         if (ce->devt != NULL && (bce == NULL ||
593                             timespeccmp(&ce->tsp, &bce->tsp, <)))
594                                 bce = ce;
595                         continue;
596                 }
597                 if (ce->pid == curpid &&
598                     (cce == NULL || timespeccmp(&ce->tsp, &cce->tsp, <)))
599                         cce = ce;
600                 else if (!(ce->flags & SND_CLONE_INVOKE) &&
601                     (nce == NULL || timespeccmp(&ce->tsp, &nce->tsp, <)))
602                         nce = ce;
603                 else if (tce == NULL || timespeccmp(&ce->tsp, &tce->tsp, <))
604                         tce = ce;
605         }
606         if (*unit != -1)
607                 goto snd_clone_alloc_new;
608         else if (cce != NULL) {
609                 /* Same proc entry found, go for it */
610                 ce = cce;
611                 goto snd_clone_alloc_out;
612         } else if (nce != NULL) {
613                 /*
614                  * Next, try absolute free entry. If the calculated
615                  * allocunit is smaller, create new entry instead.
616                  */
617                 if (allocunit < (nce->unit & ~tmask))
618                         goto snd_clone_alloc_new;
619                 ce = nce;
620                 goto snd_clone_alloc_out;
621         } else if (allocunit > c->maxunit) {
622                 /*
623                  * Maximum allowable unit reached. Try returning any
624                  * available cdev and hope for the best. If the lookup is
625                  * done for things like stat(), mtime() etc. , things should
626                  * be ok. Otherwise, open() handler should do further checks
627                  * and decide whether to return correct error code or not.
628                  */
629                 if (tce != NULL) {
630                         ce = tce;
631                         goto snd_clone_alloc_out;
632                 } else if (bce != NULL) {
633                         ce = bce;
634                         goto snd_clone_alloc_out;
635                 }
636                 return (NULL);
637         }
638
639 snd_clone_alloc_new:
640         /*
641          * No free entries found, and we still haven't reached maximum
642          * allowable units. Allocate, setup a minimal unique entry with busy
643          * status so nobody will monkey on this new entry. Unit magic is set
644          * right here to avoid collision with other contesting handler.
645          * The caller must be carefull here to maintain its own
646          * synchronization, as long as it will not conflict with malloc(9)
647          * operations.
648          *
649          * That said, go figure.
650          */
651         ce = malloc(sizeof(*ce), M_DEVBUF,
652             ((c->flags & SND_CLONE_WAITOK) ? M_WAITOK : M_NOWAIT) | M_ZERO);
653         if (ce == NULL) {
654                 if (*unit != -1)
655                         return (NULL);
656                 /*
657                  * We're being dense, ignorance is bliss,
658                  * Super Regulatory Measure (TM).. TRY AGAIN!
659                  */
660                 if (nce != NULL) {
661                         ce = nce;
662                         goto snd_clone_alloc_out;
663                 } else if (tce != NULL) {
664                         ce = tce;
665                         goto snd_clone_alloc_out;
666                 } else if (bce != NULL) {
667                         ce = bce;
668                         goto snd_clone_alloc_out;
669                 }
670                 return (NULL);
671         }
672         /* Setup new entry */
673         ce->parent = c;
674         ce->unit = tmask | allocunit;
675         ce->pid = curpid;
676         ce->tsp = now;
677         ce->flags |= SND_CLONE_ALLOC;
678         if (after != NULL) {
679                 TAILQ_INSERT_AFTER(&c->head, after, ce, link);
680         } else {
681                 TAILQ_INSERT_HEAD(&c->head, ce, link);
682         }
683         c->size++;
684         c->tsp = now;
685         /*
686          * Save new allocation unit for caller which will be used
687          * by make_dev().
688          */
689         *unit = allocunit;
690
691         return (ce);
692
693 snd_clone_alloc_out:
694         /*
695          * Set, mark, timestamp the entry if this is a truly free entry.
696          * Leave busy entry alone.
697          */
698         if (!(ce->flags & SND_CLONE_BUSY)) {
699                 ce->pid = curpid;
700                 ce->tsp = now;
701                 ce->flags |= SND_CLONE_INVOKE;
702         }
703         c->tsp = now;
704         *dev = ce->devt;
705
706         return (NULL);
707 }