Remove mdoc.local, we need to make this truly local.
[dragonfly.git] / sys / sys / ccbque.h
1 /*      $NetBSD$        */
2 /*
3  * [NetBSD for NEC PC98 series]
4  *  Copyright (c) 1994, 1995, 1996 NetBSD/pc98 porting staff.
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  *  3. The name of the author may not be used to endorse or promote products
16  *     derived from this software without specific prior written permission.
17  * 
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $FreeBSD: src/sys/i386/isa/ccbque.h,v 1.3.6.2 2000/10/21 07:44:24 nyan Exp $
31  * $DragonFly: src/sys/sys/ccbque.h,v 1.7 2005/06/03 17:14:51 dillon Exp $
32  */
33 /*
34  * Common command control queue funcs.
35  * Written by N. Honda.
36  */
37
38 #ifndef _CCBQUE_H_
39 #define _CCBQUE_H_
40
41 #define CCB_MWANTED 0x01
42                                                 
43 /* (I)  structure and prototype */
44 #define GENERIC_CCB_ASSERT(DEV, CCBTYPE)                                \
45 TAILQ_HEAD(CCBTYPE##tab, CCBTYPE);                                      \
46 struct CCBTYPE##que {                                                   \
47         struct CCBTYPE##tab CCBTYPE##tab;                               \
48         int count;                                                      \
49         int maxccb;                                                     \
50         u_int flags;                                                    \
51 };                                                                      \
52                                                                         \
53 void DEV##_init_ccbque (int);                                   \
54 struct CCBTYPE *DEV##_get_ccb (void);                           \
55 void DEV##_free_ccb (struct CCBTYPE *);
56
57 /* (II)  static allocated memory */
58 #define GENERIC_CCB_STATIC_ALLOC(DEV, CCBTYPE)                          \
59 static struct CCBTYPE##que CCBTYPE##que;
60
61 /* (III)  functions */
62 #define GENERIC_CCB(DEV, CCBTYPE, CHAIN)                                \
63                                                                         \
64 void                                                                    \
65 DEV##_init_ccbque(count)                                                \
66         int count;                                                      \
67 {                                                                       \
68         if (CCBTYPE##que.maxccb == 0)                                   \
69                 TAILQ_INIT(&CCBTYPE##que.CCBTYPE##tab);                 \
70         CCBTYPE##que.maxccb += count;                                   \
71 }                                                                       \
72                                                                         \
73 struct CCBTYPE *                                                        \
74 DEV##_get_ccb()                                                         \
75 {                                                                       \
76         struct CCBTYPE *cb;                                             \
77                                                                         \
78         crit_enter();                                                   \
79                                                                         \
80         if (CCBTYPE##que.count < CCBTYPE##que.maxccb)                   \
81         {                                                               \
82                 CCBTYPE##que.count ++;                                  \
83                 cb = TAILQ_FIRST(&CCBTYPE##que.CCBTYPE##tab);           \
84                 if (cb != NULL)                                         \
85                 {                                                       \
86                         TAILQ_REMOVE(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);\
87                         goto out;                                       \
88                 }                                                       \
89                 else                                                    \
90                 {                                                       \
91                         cb = malloc(sizeof(*cb), M_DEVBUF, M_INTWAIT);  \
92                         if (cb != NULL)                                 \
93                         {                                               \
94                                 bzero(cb, sizeof(*cb));                 \
95                                 goto out;                               \
96                         }                                               \
97                 }                                                       \
98                 CCBTYPE##que.count --;                                  \
99         }                                                               \
100                                                                         \
101         cb = NULL;                                                      \
102                                                                         \
103 out:                                                                    \
104         crit_exit();                                                    \
105         return cb;                                                      \
106 }                                                                       \
107                                                                         \
108 void                                                                    \
109 DEV##_free_ccb(cb)                                                      \
110         struct CCBTYPE *cb;                                     \
111 {                                                                       \
112         crit_enter();                                                   \
113                                                                         \
114         TAILQ_INSERT_TAIL(&CCBTYPE##que.CCBTYPE##tab, cb, CHAIN);       \
115         CCBTYPE##que.count --;                                          \
116                                                                         \
117         if (CCBTYPE##que.flags & CCB_MWANTED)                           \
118         {                                                               \
119                 CCBTYPE##que.flags &= ~CCB_MWANTED;                     \
120                 wakeup ((caddr_t) &CCBTYPE##que.count);                 \
121         }                                                               \
122         crit_exit();                                                    \
123 }
124 #endif  /* !_CCBQUE_H_ */