Lines 32-37
Link Here
|
32 |
__FBSDID("$FreeBSD$"); |
32 |
__FBSDID("$FreeBSD$"); |
33 |
|
33 |
|
34 |
#include <sys/param.h> |
34 |
#include <sys/param.h> |
|
|
35 |
#include <sys/types.h> |
36 |
#include <sys/eventhandler.h> |
35 |
#include <sys/kernel.h> |
37 |
#include <sys/kernel.h> |
36 |
#include <sys/malloc.h> |
38 |
#include <sys/malloc.h> |
37 |
#include <sys/module.h> |
39 |
#include <sys/module.h> |
Lines 52-57
struct vtrnd_softc {
Link Here
|
52 |
device_t vtrnd_dev; |
54 |
device_t vtrnd_dev; |
53 |
uint64_t vtrnd_features; |
55 |
uint64_t vtrnd_features; |
54 |
struct virtqueue *vtrnd_vq; |
56 |
struct virtqueue *vtrnd_vq; |
|
|
57 |
eventhandler_tag eh; |
58 |
bool inactive; |
55 |
}; |
59 |
}; |
56 |
|
60 |
|
57 |
static int vtrnd_modevent(module_t, int, void *); |
61 |
static int vtrnd_modevent(module_t, int, void *); |
Lines 59-64
static int vtrnd_modevent(module_t, int, void *);
Link Here
|
59 |
static int vtrnd_probe(device_t); |
63 |
static int vtrnd_probe(device_t); |
60 |
static int vtrnd_attach(device_t); |
64 |
static int vtrnd_attach(device_t); |
61 |
static int vtrnd_detach(device_t); |
65 |
static int vtrnd_detach(device_t); |
|
|
66 |
static int vtrnd_shutdown(device_t); |
62 |
|
67 |
|
63 |
static int vtrnd_negotiate_features(struct vtrnd_softc *); |
68 |
static int vtrnd_negotiate_features(struct vtrnd_softc *); |
64 |
static int vtrnd_setup_features(struct vtrnd_softc *); |
69 |
static int vtrnd_setup_features(struct vtrnd_softc *); |
Lines 86-91
static device_method_t vtrnd_methods[] = {
Link Here
|
86 |
DEVMETHOD(device_probe, vtrnd_probe), |
91 |
DEVMETHOD(device_probe, vtrnd_probe), |
87 |
DEVMETHOD(device_attach, vtrnd_attach), |
92 |
DEVMETHOD(device_attach, vtrnd_attach), |
88 |
DEVMETHOD(device_detach, vtrnd_detach), |
93 |
DEVMETHOD(device_detach, vtrnd_detach), |
|
|
94 |
DEVMETHOD(device_shutdown, vtrnd_shutdown), |
89 |
|
95 |
|
90 |
DEVMETHOD_END |
96 |
DEVMETHOD_END |
91 |
}; |
97 |
}; |
Lines 160-165
vtrnd_attach(device_t dev)
Link Here
|
160 |
error = EEXIST; |
166 |
error = EEXIST; |
161 |
goto fail; |
167 |
goto fail; |
162 |
} |
168 |
} |
|
|
169 |
|
170 |
sc->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, |
171 |
vtrnd_shutdown, dev, SHUTDOWN_PRI_LAST + 1); /* ??? */ |
172 |
if (sc->eh == NULL) { |
173 |
device_printf(dev, "Shutdown event registration failed\n"); |
174 |
error = ENXIO; |
175 |
goto fail; |
176 |
} |
177 |
|
178 |
sc->inactive = false; |
163 |
random_source_register(&random_vtrnd); |
179 |
random_source_register(&random_vtrnd); |
164 |
|
180 |
|
165 |
fail: |
181 |
fail: |
Lines 179-190
vtrnd_detach(device_t dev)
Link Here
|
179 |
atomic_load_explicit(&g_vtrnd_softc, memory_order_acquire) == sc, |
195 |
atomic_load_explicit(&g_vtrnd_softc, memory_order_acquire) == sc, |
180 |
("only one global instance at a time")); |
196 |
("only one global instance at a time")); |
181 |
|
197 |
|
|
|
198 |
sc->inactive = true; |
199 |
if (sc->eh != NULL) { |
200 |
EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->eh); |
201 |
sc->eh = NULL; |
202 |
} |
182 |
random_source_deregister(&random_vtrnd); |
203 |
random_source_deregister(&random_vtrnd); |
183 |
atomic_store_explicit(&g_vtrnd_softc, NULL, memory_order_release); |
204 |
atomic_store_explicit(&g_vtrnd_softc, NULL, memory_order_release); |
184 |
return (0); |
205 |
return (0); |
185 |
} |
206 |
} |
186 |
|
207 |
|
187 |
static int |
208 |
static int |
|
|
209 |
vtrnd_shutdown(device_t dev) |
210 |
{ |
211 |
struct vtrnd_softc *sc; |
212 |
|
213 |
sc = device_get_softc(dev); |
214 |
sc->inactive = true; |
215 |
|
216 |
return(0); |
217 |
} |
218 |
|
219 |
static int |
188 |
vtrnd_negotiate_features(struct vtrnd_softc *sc) |
220 |
vtrnd_negotiate_features(struct vtrnd_softc *sc) |
189 |
{ |
221 |
{ |
190 |
device_t dev; |
222 |
device_t dev; |
Lines 234-239
vtrnd_harvest(struct vtrnd_softc *sc, void *buf, size_
Link Here
|
234 |
int error; |
266 |
int error; |
235 |
|
267 |
|
236 |
_Static_assert(sizeof(value) < PAGE_SIZE, "sglist assumption"); |
268 |
_Static_assert(sizeof(value) < PAGE_SIZE, "sglist assumption"); |
|
|
269 |
|
270 |
if (sc->inactive) |
271 |
return (EDEADLK); |
237 |
|
272 |
|
238 |
sglist_init(&sg, 1, segs); |
273 |
sglist_init(&sg, 1, segs); |
239 |
error = sglist_append(&sg, value, *sz); |
274 |
error = sglist_append(&sg, value, *sz); |