This source file includes following definitions.
- uiomove
- ureadc
- hashinit
- hook_establish
- hook_disestablish
- dohooks
- powerhook_establish
- powerhook_disestablish
- dopowerhooks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/proc.h>
43 #include <sys/sched.h>
44 #include <sys/malloc.h>
45 #include <sys/queue.h>
46 #include <sys/kernel.h>
47 #include <sys/resourcevar.h>
48
49 int
50 uiomove(void *cp, int n, struct uio *uio)
51 {
52 struct iovec *iov;
53 u_int cnt;
54 int error = 0;
55 struct proc *p;
56
57 p = uio->uio_procp;
58
59 #ifdef DIAGNOSTIC
60 if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
61 panic("uiomove: mode");
62 if (uio->uio_segflg == UIO_USERSPACE && p != curproc)
63 panic("uiomove: proc");
64 #endif
65 while (n > 0 && uio->uio_resid) {
66 iov = uio->uio_iov;
67 cnt = iov->iov_len;
68 if (cnt == 0) {
69 uio->uio_iov++;
70 uio->uio_iovcnt--;
71 continue;
72 }
73 if (cnt > n)
74 cnt = n;
75 switch (uio->uio_segflg) {
76
77 case UIO_USERSPACE:
78 if (curcpu()->ci_schedstate.spc_schedflags &
79 SPCF_SHOULDYIELD)
80 preempt(NULL);
81 if (uio->uio_rw == UIO_READ)
82 error = copyout(cp, iov->iov_base, cnt);
83 else
84 error = copyin(iov->iov_base, cp, cnt);
85 if (error)
86 return (error);
87 break;
88
89 case UIO_SYSSPACE:
90 if (uio->uio_rw == UIO_READ)
91 error = kcopy(cp, iov->iov_base, cnt);
92 else
93 error = kcopy(iov->iov_base, cp, cnt);
94 if (error)
95 return(error);
96 }
97 iov->iov_base = (caddr_t)iov->iov_base + cnt;
98 iov->iov_len -= cnt;
99 uio->uio_resid -= cnt;
100 uio->uio_offset += cnt;
101 cp = (caddr_t)cp + cnt;
102 n -= cnt;
103 }
104 return (error);
105 }
106
107
108
109
110 int
111 ureadc(int c, struct uio *uio)
112 {
113 struct iovec *iov;
114
115 if (uio->uio_resid == 0)
116 #ifdef DIAGNOSTIC
117 panic("ureadc: zero resid");
118 #else
119 return (EINVAL);
120 #endif
121 again:
122 if (uio->uio_iovcnt <= 0)
123 #ifdef DIAGNOSTIC
124 panic("ureadc: non-positive iovcnt");
125 #else
126 return (EINVAL);
127 #endif
128 iov = uio->uio_iov;
129 if (iov->iov_len <= 0) {
130 uio->uio_iovcnt--;
131 uio->uio_iov++;
132 goto again;
133 }
134 switch (uio->uio_segflg) {
135
136 case UIO_USERSPACE:
137 {
138 char tmp = c;
139
140 if (copyout(&tmp, iov->iov_base, sizeof(char)) != 0)
141 return (EFAULT);
142 }
143 break;
144
145 case UIO_SYSSPACE:
146 *(char *)iov->iov_base = c;
147 break;
148 }
149 iov->iov_base = (caddr_t)iov->iov_base + 1;
150 iov->iov_len--;
151 uio->uio_resid--;
152 uio->uio_offset++;
153 return (0);
154 }
155
156
157
158
159 void *
160 hashinit(int elements, int type, int flags, u_long *hashmask)
161 {
162 u_long hashsize, i;
163 LIST_HEAD(generic, generic) *hashtbl;
164
165 if (elements <= 0)
166 panic("hashinit: bad cnt");
167 for (hashsize = 1; hashsize < elements; hashsize <<= 1)
168 continue;
169 hashtbl = malloc(hashsize * sizeof(*hashtbl), type, flags);
170 if (hashtbl == NULL)
171 return NULL;
172 for (i = 0; i < hashsize; i++)
173 LIST_INIT(&hashtbl[i]);
174 *hashmask = hashsize - 1;
175 return (hashtbl);
176 }
177
178
179
180
181
182 struct hook_desc_head startuphook_list =
183 TAILQ_HEAD_INITIALIZER(startuphook_list);
184 struct hook_desc_head shutdownhook_list =
185 TAILQ_HEAD_INITIALIZER(shutdownhook_list);
186 struct hook_desc_head mountroothook_list =
187 TAILQ_HEAD_INITIALIZER(mountroothook_list);
188
189 void *
190 hook_establish(struct hook_desc_head *head, int tail, void (*fn)(void *),
191 void *arg)
192 {
193 struct hook_desc *hdp;
194
195 hdp = (struct hook_desc *)malloc(sizeof (*hdp), M_DEVBUF, M_NOWAIT);
196 if (hdp == NULL)
197 return (NULL);
198
199 hdp->hd_fn = fn;
200 hdp->hd_arg = arg;
201 if (tail)
202 TAILQ_INSERT_TAIL(head, hdp, hd_list);
203 else
204 TAILQ_INSERT_HEAD(head, hdp, hd_list);
205
206 return (hdp);
207 }
208
209 void
210 hook_disestablish(struct hook_desc_head *head, void *vhook)
211 {
212 struct hook_desc *hdp;
213
214 #ifdef DIAGNOSTIC
215 for (hdp = TAILQ_FIRST(head); hdp != NULL;
216 hdp = TAILQ_NEXT(hdp, hd_list))
217 if (hdp == vhook)
218 break;
219 if (hdp == NULL)
220 panic("hook_disestablish: hook not established");
221 #endif
222 hdp = vhook;
223 TAILQ_REMOVE(head, hdp, hd_list);
224 free(hdp, M_DEVBUF);
225 }
226
227
228
229
230
231
232
233 void
234 dohooks(struct hook_desc_head *head, int flags)
235 {
236 struct hook_desc *hdp;
237
238 if ((flags & HOOK_REMOVE) == 0) {
239 TAILQ_FOREACH(hdp, head, hd_list) {
240 (*hdp->hd_fn)(hdp->hd_arg);
241 }
242 } else {
243 while ((hdp = TAILQ_FIRST(head)) != NULL) {
244 TAILQ_REMOVE(head, hdp, hd_list);
245 (*hdp->hd_fn)(hdp->hd_arg);
246 if ((flags & HOOK_FREE) != 0)
247 free(hdp, M_DEVBUF);
248 }
249 }
250 }
251
252
253
254
255
256 struct powerhook_desc {
257 CIRCLEQ_ENTRY(powerhook_desc) sfd_list;
258 void (*sfd_fn)(int, void *);
259 void *sfd_arg;
260 };
261
262 CIRCLEQ_HEAD(, powerhook_desc) powerhook_list =
263 CIRCLEQ_HEAD_INITIALIZER(powerhook_list);
264
265 void *
266 powerhook_establish(void (*fn)(int, void *), void *arg)
267 {
268 struct powerhook_desc *ndp;
269
270 ndp = (struct powerhook_desc *)
271 malloc(sizeof(*ndp), M_DEVBUF, M_NOWAIT);
272 if (ndp == NULL)
273 return NULL;
274
275 ndp->sfd_fn = fn;
276 ndp->sfd_arg = arg;
277 CIRCLEQ_INSERT_HEAD(&powerhook_list, ndp, sfd_list);
278
279 return (ndp);
280 }
281
282 void
283 powerhook_disestablish(void *vhook)
284 {
285 #ifdef DIAGNOSTIC
286 struct powerhook_desc *dp;
287
288 CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list)
289 if (dp == vhook)
290 break;
291 if (dp == NULL)
292 panic("powerhook_disestablish: hook not established");
293 #endif
294
295 CIRCLEQ_REMOVE(&powerhook_list, (struct powerhook_desc *)vhook,
296 sfd_list);
297 free(vhook, M_DEVBUF);
298 }
299
300
301
302
303 void
304 dopowerhooks(int why)
305 {
306 struct powerhook_desc *dp;
307 int s;
308
309 s = splhigh();
310 if (why == PWR_RESUME) {
311 CIRCLEQ_FOREACH_REVERSE(dp, &powerhook_list, sfd_list) {
312 (*dp->sfd_fn)(why, dp->sfd_arg);
313 }
314 } else {
315 CIRCLEQ_FOREACH(dp, &powerhook_list, sfd_list) {
316 (*dp->sfd_fn)(why, dp->sfd_arg);
317 }
318 }
319 splx(s);
320 }