Thu Jun 13 00:55:01 2013 UTC ()
Convert the entropy pool framework from pseudo-callout-driven to
soft interrupt driven operation.

Add a polling mode of operation -- now we can ask hardware random number
generators to top us up just when we need it (bcm2835_rng and amdpm
converted as examples).

Fix a stall noticed with repeated reads from /dev/random while testing.


(tls)
diff -r1.3 -r1.4 src/sys/arch/arm/broadcom/bcm2835_rng.c
diff -r1.11 -r1.12 src/sys/dev/rndpseudo.c
diff -r1.36 -r1.37 src/sys/dev/pci/amdpm.c
diff -r1.19 -r1.20 src/sys/dev/pci/amdpm_smbus.c
diff -r1.9 -r1.10 src/sys/dev/pci/amdpmvar.h
diff -r1.9 -r1.10 src/sys/dev/pci/hifn7751var.h
diff -r1.51 -r1.52 src/sys/dev/pci/hifn7751.c
diff -r1.28 -r1.29 src/sys/dev/pci/ubsec.c
diff -r1.4 -r1.5 src/sys/dev/pci/ubsecvar.h
diff -r1.300 -r1.301 src/sys/dev/scsipi/sd.c
diff -r1.2 -r1.3 src/sys/kern/kern_rndpool.c
diff -r1.10 -r1.11 src/sys/kern/kern_rndq.c
diff -r1.16 -r1.17 src/sys/kern/subr_cprng.c
diff -r1.35 -r1.36 src/sys/sys/rnd.h

cvs diff -r1.3 -r1.4 src/sys/arch/arm/broadcom/bcm2835_rng.c (expand / switch to unified diff)

--- src/sys/arch/arm/broadcom/bcm2835_rng.c 2013/02/01 16:10:16 1.3
+++ src/sys/arch/arm/broadcom/bcm2835_rng.c 2013/06/13 00:55:01 1.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: bcm2835_rng.c,v 1.3 2013/02/01 16:10:16 skrll Exp $ */ 1/* $NetBSD: bcm2835_rng.c,v 1.4 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jared D. McNeill 8 * by Jared D. McNeill
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,65 +20,66 @@ @@ -20,65 +20,66 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: bcm2835_rng.c,v 1.3 2013/02/01 16:10:16 skrll Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: bcm2835_rng.c,v 1.4 2013/06/13 00:55:01 tls Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/device.h> 37#include <sys/device.h>
38#include <sys/kernel.h> 38#include <sys/kernel.h>
39#include <sys/bus.h> 39#include <sys/bus.h>
40#include <sys/rnd.h> 40#include <sys/rnd.h>
 41#include <sys/atomic.h>
41 42
42#include <arm/broadcom/bcm_amba.h> 43#include <arm/broadcom/bcm_amba.h>
43#include <arm/broadcom/bcm2835reg.h> 44#include <arm/broadcom/bcm2835reg.h>
44#include <arm/broadcom/bcm2835_intr.h> 45#include <arm/broadcom/bcm2835_intr.h>
45 46
46#define RNG_CTRL 0x00 47#define RNG_CTRL 0x00
47#define RNG_CTRL_EN __BIT(0) 48#define RNG_CTRL_EN __BIT(0)
48#define RNG_STATUS 0x04 49#define RNG_STATUS 0x04
49#define RNG_STATUS_CNT_MASK __BITS(31,24) 50#define RNG_STATUS_CNT_MASK __BITS(31,24)
50#define RNG_STATUS_CNT_SHIFT 24 51#define RNG_STATUS_CNT_SHIFT 24
51#define RNG_DATA 0x08 52#define RNG_DATA 0x08
52 53
53#define RNG_DATA_MAX 256 54#define RNG_DATA_MAX 256
54 55
55struct bcm2835rng_softc { 56struct bcm2835rng_softc {
56 device_t sc_dev; 57 device_t sc_dev;
57 58
58 bus_space_tag_t sc_iot; 59 bus_space_tag_t sc_iot;
59 bus_space_handle_t sc_ioh; 60 bus_space_handle_t sc_ioh;
60 61
61 krndsource_t sc_rnd; 62 krndsource_t sc_rnd;
62 callout_t sc_tick; 63
 64 kmutex_t sc_mutex;
63 65
64 uint32_t sc_data[RNG_DATA_MAX]; 66 uint32_t sc_data[RNG_DATA_MAX];
65}; 67};
66 68
 69static void bcmrng_get(size_t, void *);
67static int bcmrng_match(device_t, cfdata_t, void *); 70static int bcmrng_match(device_t, cfdata_t, void *);
68static void bcmrng_attach(device_t, device_t, void *); 71static void bcmrng_attach(device_t, device_t, void *);
69 72
70static void bcmrng_tick(void *); 
71 
72CFATTACH_DECL_NEW(bcmrng_amba, sizeof(struct bcm2835rng_softc), 73CFATTACH_DECL_NEW(bcmrng_amba, sizeof(struct bcm2835rng_softc),
73 bcmrng_match, bcmrng_attach, NULL, NULL); 74 bcmrng_match, bcmrng_attach, NULL, NULL);
74 75
75/* ARGSUSED */ 76/* ARGSUSED */
76static int 77static int
77bcmrng_match(device_t parent, cfdata_t match, void *aux) 78bcmrng_match(device_t parent, cfdata_t match, void *aux)
78{ 79{
79 struct amba_attach_args *aaa = aux; 80 struct amba_attach_args *aaa = aux;
80 81
81 if (strcmp(aaa->aaa_name, "bcmrng") != 0) 82 if (strcmp(aaa->aaa_name, "bcmrng") != 0)
82 return 0; 83 return 0;
83 84
84 return 1; 85 return 1;
@@ -93,49 +94,57 @@ bcmrng_attach(device_t parent, device_t  @@ -93,49 +94,57 @@ bcmrng_attach(device_t parent, device_t
93 94
94 aprint_naive("\n"); 95 aprint_naive("\n");
95 aprint_normal(": RNG\n"); 96 aprint_normal(": RNG\n");
96 97
97 sc->sc_dev = self; 98 sc->sc_dev = self;
98 sc->sc_iot = aaa->aaa_iot; 99 sc->sc_iot = aaa->aaa_iot;
99 100
100 if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0, 101 if (bus_space_map(aaa->aaa_iot, aaa->aaa_addr, BCM2835_RNG_SIZE, 0,
101 &sc->sc_ioh)) { 102 &sc->sc_ioh)) {
102 aprint_error_dev(sc->sc_dev, "unable to map device\n"); 103 aprint_error_dev(sc->sc_dev, "unable to map device\n");
103 return; 104 return;
104 } 105 }
105 106
106 rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG, 107 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
107 RND_FLAG_NO_ESTIMATE); 
108 108
109 callout_init(&sc->sc_tick, CALLOUT_MPSAFE); 109 rndsource_setcb(&sc->sc_rnd, bcmrng_get, sc);
110 callout_setfunc(&sc->sc_tick, bcmrng_tick, sc); 110 rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG,
 111 RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
111 112
112 /* discard initial numbers, broadcom says they are "less random" */ 113 /* discard initial numbers, broadcom says they are "less random" */
113 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000); 114 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS, 0x40000);
114 115
115 /* enable rng */ 116 /* enable rng */
116 ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL); 117 ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL);
117 ctrl |= RNG_CTRL_EN; 118 ctrl |= RNG_CTRL_EN;
118 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl); 119 bus_space_write_4(sc->sc_iot, sc->sc_ioh, RNG_CTRL, ctrl);
119 
120 /* start timer */ 
121 bcmrng_tick(sc); 
122} 120}
123 121
124static void 122static void
125bcmrng_tick(void *priv) 123bcmrng_get(size_t bytes, void *priv)
126{ 124{
127 struct bcm2835rng_softc *sc = priv; 125 struct bcm2835rng_softc *sc = priv;
128 uint32_t status; 126 uint32_t status;
129 int cnt; 127 int need = bytes, cnt;
130 128
131 status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS); 129 mutex_spin_enter(&sc->sc_mutex);
132 cnt = (status & RNG_STATUS_CNT_MASK) >> RNG_STATUS_CNT_SHIFT; 130
133 if (cnt > 0) { 131 printf("bcmrng: asked for %d bytes", (int)bytes);
134 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, RNG_DATA, 132
135 sc->sc_data, cnt); 133 if (__predict_false(need < 1)) {
136 rnd_add_data(&sc->sc_rnd, sc->sc_data, 134 return;
137 cnt * 4, cnt * 4 * NBBY); 
138 } 135 }
139 136
140 callout_schedule(&sc->sc_tick, 1); 137 while (need > 0) {
 138 status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, RNG_STATUS);
 139 cnt = (status & RNG_STATUS_CNT_MASK) >> RNG_STATUS_CNT_SHIFT;
 140 if (cnt > 0) {
 141 bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh,
 142 RNG_DATA, sc->sc_data, cnt);
 143 rnd_add_data(&sc->sc_rnd, sc->sc_data,
 144 cnt * 4, cnt * 4 * NBBY);
 145 }
 146
 147 need -= cnt * 4;
 148 }
 149 mutex_spin_exit(&sc->sc_mutex);
141} 150}

cvs diff -r1.11 -r1.12 src/sys/dev/Attic/rndpseudo.c (expand / switch to unified diff)

--- src/sys/dev/Attic/rndpseudo.c 2012/11/25 15:29:24 1.11
+++ src/sys/dev/Attic/rndpseudo.c 2013/06/13 00:55:01 1.12
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rndpseudo.c,v 1.11 2012/11/25 15:29:24 christos Exp $ */ 1/* $NetBSD: rndpseudo.c,v 1.12 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon. 8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.11 2012/11/25 15:29:24 christos Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.12 2013/06/13 00:55:01 tls Exp $");
34 34
35#if defined(_KERNEL_OPT) 35#if defined(_KERNEL_OPT)
36#include "opt_compat_netbsd.h" 36#include "opt_compat_netbsd.h"
37#endif 37#endif
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/ioctl.h> 40#include <sys/ioctl.h>
41#include <sys/fcntl.h> 41#include <sys/fcntl.h>
42#include <sys/file.h> 42#include <sys/file.h>
43#include <sys/filedesc.h> 43#include <sys/filedesc.h>
44#include <sys/select.h> 44#include <sys/select.h>
45#include <sys/poll.h> 45#include <sys/poll.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
@@ -209,26 +209,27 @@ rndopen(dev_t dev, int flag, int ifmt, @@ -209,26 +209,27 @@ rndopen(dev_t dev, int flag, int ifmt,
209 case RND_DEV_RANDOM: 209 case RND_DEV_RANDOM:
210 hard = 1; 210 hard = 1;
211 break; 211 break;
212 default: 212 default:
213 return ENXIO; 213 return ENXIO;
214 } 214 }
215 ctx = pool_cache_get(rp_cpc, PR_WAITOK);  215 ctx = pool_cache_get(rp_cpc, PR_WAITOK);
216 if ((error = fd_allocfile(&fp, &fd)) != 0) { 216 if ((error = fd_allocfile(&fp, &fd)) != 0) {
217 pool_cache_put(rp_cpc, ctx); 217 pool_cache_put(rp_cpc, ctx);
218 return error; 218 return error;
219 } 219 }
220 ctx->cprng = NULL; 220 ctx->cprng = NULL;
221 ctx->hard = hard; 221 ctx->hard = hard;
 222 ctx->bytesonkey = 0;
222 mutex_init(&ctx->interlock, MUTEX_DEFAULT, IPL_NONE); 223 mutex_init(&ctx->interlock, MUTEX_DEFAULT, IPL_NONE);
223 224
224 return fd_clone(fp, fd, flag, &rnd_fileops, ctx); 225 return fd_clone(fp, fd, flag, &rnd_fileops, ctx);
225} 226}
226 227
227static void 228static void
228rnd_alloc_cprng(rp_ctx_t *ctx) 229rnd_alloc_cprng(rp_ctx_t *ctx)
229{ 230{
230 char personalization_buf[64]; 231 char personalization_buf[64];
231 struct lwp *l = curlwp; 232 struct lwp *l = curlwp;
232 int cflags = ctx->hard ? CPRNG_USE_CV : 233 int cflags = ctx->hard ? CPRNG_USE_CV :
233 CPRNG_INIT_ANY|CPRNG_REKEY_ANY; 234 CPRNG_INIT_ANY|CPRNG_REKEY_ANY;
234 235
@@ -288,42 +289,57 @@ rnd_read(struct file * fp, off_t *offp,  @@ -288,42 +289,57 @@ rnd_read(struct file * fp, off_t *offp,
288 return EIO; 289 return EIO;
289 } 290 }
290 291
291 strength = cprng_strong_strength(cprng); 292 strength = cprng_strong_strength(cprng);
292 ret = 0; 293 ret = 0;
293 bf = pool_cache_get(rp_pc, PR_WAITOK); 294 bf = pool_cache_get(rp_pc, PR_WAITOK);
294 while (uio->uio_resid > 0) { 295 while (uio->uio_resid > 0) {
295 int n, nread, want; 296 int n, nread, want;
296 297
297 want = MIN(RND_TEMP_BUFFER_SIZE, uio->uio_resid); 298 want = MIN(RND_TEMP_BUFFER_SIZE, uio->uio_resid);
298 299
299 /* XXX is this _really_ what's wanted? */ 300 /* XXX is this _really_ what's wanted? */
300 if (ctx->hard) { 301 if (ctx->hard) {
 302#ifdef RND_VERBOSE
 303 printf("rnd: hard, want = %d, strength = %d, "
 304 "bytesonkey = %d\n", (int)want, (int)strength,
 305 (int)ctx->bytesonkey);
 306#endif
301 n = MIN(want, strength - ctx->bytesonkey); 307 n = MIN(want, strength - ctx->bytesonkey);
302 if (n < 1) { 308 if (n < 1) {
303 cprng_strong_deplete(cprng); 309#ifdef RND_VERBOSE
304 n = MIN(want, strength); 310 printf("rnd: BAD BAD BAD: n = %d, want = %d, "
305 ctx->bytesonkey = 0; 311 "strength = %d, bytesonkey = %d\n", n,
306 membar_producer(); 312 (int)want, (int)strength,
 313 (int)ctx->bytesonkey);
 314#endif
307 } 315 }
308 } else { 316 } else {
309 n = want; 317 n = want;
310 } 318 }
311 319
312 nread = cprng_strong(cprng, bf, n, 320 nread = cprng_strong(cprng, bf, n,
313 (fp->f_flag & FNONBLOCK) ? FNONBLOCK : 0); 321 (fp->f_flag & FNONBLOCK) ? FNONBLOCK : 0);
314 322
315 if (ctx->hard && nread > 0) { 323 if (ctx->hard && nread > 0) {
316 atomic_add_int(&ctx->bytesonkey, nread); 324 if (atomic_add_int_nv(&ctx->bytesonkey, nread) >=
 325 strength) {
 326 cprng_strong_deplete(cprng);
 327 ctx->bytesonkey = 0;
 328 membar_producer();
 329 }
 330#ifdef RND_VERBOSE
 331 printf("rnd: new bytesonkey %d\n", ctx->bytesonkey);
 332#endif
317 } 333 }
318 if (nread < 1) { 334 if (nread < 1) {
319 if (fp->f_flag & FNONBLOCK) { 335 if (fp->f_flag & FNONBLOCK) {
320 ret = EWOULDBLOCK; 336 ret = EWOULDBLOCK;
321 } else { 337 } else {
322 ret = EINTR; 338 ret = EINTR;
323 } 339 }
324 goto out; 340 goto out;
325 } 341 }
326 342
327 ret = uiomove((void *)bf, nread, uio); 343 ret = uiomove((void *)bf, nread, uio);
328 if (ret != 0 || n < want) { 344 if (ret != 0 || n < want) {
329 goto out; 345 goto out;

cvs diff -r1.36 -r1.37 src/sys/dev/pci/amdpm.c (expand / switch to unified diff)

--- src/sys/dev/pci/amdpm.c 2012/10/27 17:18:28 1.36
+++ src/sys/dev/pci/amdpm.c 2013/06/13 00:55:01 1.37
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: amdpm.c,v 1.36 2012/10/27 17:18:28 chs Exp $ */ 1/* $NetBSD: amdpm.c,v 1.37 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Enami Tsugutomo. 8 * by Enami Tsugutomo.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,51 +20,53 @@ @@ -20,51 +20,53 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.36 2012/10/27 17:18:28 chs Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: amdpm.c,v 1.37 2013/06/13 00:55:01 tls Exp $");
34 34
35#include "opt_amdpm.h" 35#include "opt_amdpm.h"
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/callout.h> 41#include <sys/callout.h>
42#include <sys/rnd.h> 42#include <sys/rnd.h>
 43#include <sys/mutex.h>
43 44
44#include <sys/bus.h> 45#include <sys/bus.h>
45#include <dev/ic/acpipmtimer.h> 46#include <dev/ic/acpipmtimer.h>
46 47
47#include <dev/i2c/i2cvar.h> 48#include <dev/i2c/i2cvar.h>
48 49
49#include <dev/pci/pcivar.h> 50#include <dev/pci/pcivar.h>
50#include <dev/pci/pcireg.h> 51#include <dev/pci/pcireg.h>
51#include <dev/pci/pcidevs.h> 52#include <dev/pci/pcidevs.h>
52 53
53#include <dev/pci/amdpmreg.h> 54#include <dev/pci/amdpmreg.h>
54#include <dev/pci/amdpmvar.h> 55#include <dev/pci/amdpmvar.h>
55#include <dev/pci/amdpm_smbusreg.h> 56#include <dev/pci/amdpm_smbusreg.h>
56 57
57static void amdpm_rnd_callout(void *); 58static void amdpm_rnd_callout(void *);
 59static void amdpm_rnd_callout_locked(void *);
58 60
59#ifdef AMDPM_RND_COUNTERS 61#ifdef AMDPM_RND_COUNTERS
60#define AMDPM_RNDCNT_INCR(ev) (ev)->ev_count++ 62#define AMDPM_RNDCNT_INCR(ev) (ev)->ev_count++
61#endif 63#endif
62 64
63static int 65static int
64amdpm_match(device_t parent, cfdata_t match, void *aux) 66amdpm_match(device_t parent, cfdata_t match, void *aux)
65{ 67{
66 struct pci_attach_args *pa = aux; 68 struct pci_attach_args *pa = aux;
67 69
68 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD) { 70 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD) {
69 switch (PCI_PRODUCT(pa->pa_id)) { 71 switch (PCI_PRODUCT(pa->pa_id)) {
70 case PCI_PRODUCT_AMD_PBC768_PMC: 72 case PCI_PRODUCT_AMD_PBC768_PMC:
@@ -73,26 +75,37 @@ amdpm_match(device_t parent, cfdata_t ma @@ -73,26 +75,37 @@ amdpm_match(device_t parent, cfdata_t ma
73 } 75 }
74 } 76 }
75 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) { 77 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NVIDIA) {
76 switch (PCI_PRODUCT(pa->pa_id)) { 78 switch (PCI_PRODUCT(pa->pa_id)) {
77 case PCI_PRODUCT_NVIDIA_XBOX_SMBUS: 79 case PCI_PRODUCT_NVIDIA_XBOX_SMBUS:
78 return (1); 80 return (1);
79 } 81 }
80 } 82 }
81 83
82 return (0); 84 return (0);
83} 85}
84 86
85static void 87static void
 88amdpm_rnd_get(size_t bytes, void *priv)
 89{
 90 struct amdpm_softc *sc = priv;
 91
 92 mutex_enter(&sc->sc_mutex);
 93 sc->sc_rnd_need = bytes;
 94 amdpm_rnd_callout_locked(sc);
 95 mutex_exit(&sc->sc_mutex);
 96}
 97
 98static void
86amdpm_attach(device_t parent, device_t self, void *aux) 99amdpm_attach(device_t parent, device_t self, void *aux)
87{ 100{
88 struct amdpm_softc *sc = device_private(self); 101 struct amdpm_softc *sc = device_private(self);
89 struct pci_attach_args *pa = aux; 102 struct pci_attach_args *pa = aux;
90 pcireg_t confreg, pmptrreg; 103 pcireg_t confreg, pmptrreg;
91 u_int32_t pmreg; 104 u_int32_t pmreg;
92 int i; 105 int i;
93 106
94 pci_aprint_devinfo(pa, NULL); 107 pci_aprint_devinfo(pa, NULL);
95 108
96 sc->sc_dev = self; 109 sc->sc_dev = self;
97 110
98 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_XBOX_SMBUS) 111 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NVIDIA_XBOX_SMBUS)
@@ -141,96 +154,120 @@ amdpm_attach(device_t parent, device_t s @@ -141,96 +154,120 @@ amdpm_attach(device_t parent, device_t s
141 AMDPM_PMSIZE, 0, &sc->sc_ioh)) { 154 AMDPM_PMSIZE, 0, &sc->sc_ioh)) {
142 aprint_error_dev(self, "failed to map PMxx space\n"); 155 aprint_error_dev(self, "failed to map PMxx space\n");
143 return; 156 return;
144 } 157 }
145 } 158 }
146 159
147 /* don't attach a timecounter on nforce boards */ 160 /* don't attach a timecounter on nforce boards */
148 if ((confreg & AMDPM_TMRRST) == 0 && (confreg & AMDPM_STOPTMR) == 0 && 161 if ((confreg & AMDPM_TMRRST) == 0 && (confreg & AMDPM_STOPTMR) == 0 &&
149 !sc->sc_nforce) { 162 !sc->sc_nforce) {
150 acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh, 163 acpipmtimer_attach(self, sc->sc_iot, sc->sc_ioh,
151 AMDPM_TMR, ((confreg & AMDPM_TMR32) ? ACPIPMT_32BIT : 0)); 164 AMDPM_TMR, ((confreg & AMDPM_TMR32) ? ACPIPMT_32BIT : 0));
152 } 165 }
153 166
 167 /* XXX this mutex is IPL_VM because it can be taken by rnd_getmore() */
 168 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_VM);
 169
154 /* try to attach devices on the smbus */ 170 /* try to attach devices on the smbus */
155 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC8111_ACPI || 171 if (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC8111_ACPI ||
156 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC || 172 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PBC768_PMC ||
157 sc->sc_nforce) { 173 sc->sc_nforce) {
158 amdpm_smbus_attach(sc); 174 amdpm_smbus_attach(sc);
159 } 175 }
160 176
161 if (confreg & AMDPM_RNGEN) { 177 if (confreg & AMDPM_RNGEN) {
162 /* Check to see if we can read data from the RNG. */ 178 /* Check to see if we can read data from the RNG. */
163 (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh, 179 (void) bus_space_read_4(sc->sc_iot, sc->sc_ioh,
164 AMDPM_RNGDATA); 180 AMDPM_RNGDATA);
165 for (i = 0; i < 1000; i++) { 181 for (i = 0; i < 1000; i++) {
166 pmreg = bus_space_read_4(sc->sc_iot, 182 pmreg = bus_space_read_4(sc->sc_iot,
167 sc->sc_ioh, AMDPM_RNGSTAT); 183 sc->sc_ioh, AMDPM_RNGSTAT);
168 if (pmreg & AMDPM_RNGDONE) 184 if (pmreg & AMDPM_RNGDONE)
169 break; 185 break;
170 delay(1); 186 delay(1);
171 } 187 }
172 if ((pmreg & AMDPM_RNGDONE) != 0) { 188 if ((pmreg & AMDPM_RNGDONE) != 0) {
173 aprint_normal_dev(self, "" 189 aprint_normal_dev(self, ""
174 "random number generator enabled (apprx. %dms)\n", 190 "random number generator enabled (apprx. %dms)\n",
175 i); 191 i);
176 callout_init(&sc->sc_rnd_ch, 0); 192 callout_init(&sc->sc_rnd_ch, CALLOUT_MPSAFE);
 193 rndsource_setcb(&sc->sc_rnd_source,
 194 amdpm_rnd_get, sc);
177 rnd_attach_source(&sc->sc_rnd_source, 195 rnd_attach_source(&sc->sc_rnd_source,
178 device_xname(self), RND_TYPE_RNG, 196 device_xname(self), RND_TYPE_RNG,
179 /* 197 /*
180 * XXX Careful! The use of RND_FLAG_NO_ESTIMATE 198 * XXX Careful! The use of RND_FLAG_NO_ESTIMATE
181 * XXX here is unobvious: we later feed raw bits 199 * XXX here is unobvious: we later feed raw bits
182 * XXX into the "entropy pool" with rnd_add_data, 200 * XXX into the "entropy pool" with rnd_add_data,
183 * XXX explicitly supplying an entropy estimate. 201 * XXX explicitly supplying an entropy estimate.
184 * XXX In this context, NO_ESTIMATE serves only 202 * XXX In this context, NO_ESTIMATE serves only
185 * XXX to prevent rnd_add_data from trying to 203 * XXX to prevent rnd_add_data from trying to
186 * XXX use the *time at which we added the data* 204 * XXX use the *time at which we added the data*
187 * XXX as entropy, which is not a good idea since 205 * XXX as entropy, which is not a good idea since
188 * XXX we add data periodically from a callout. 206 * XXX we add data periodically from a callout.
189 */ 207 */
190 RND_FLAG_NO_ESTIMATE); 208 RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
191#ifdef AMDPM_RND_COUNTERS 209#ifdef AMDPM_RND_COUNTERS
192 evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC, 210 evcnt_attach_dynamic(&sc->sc_rnd_hits, EVCNT_TYPE_MISC,
193 NULL, device_xname(self), "rnd hits"); 211 NULL, device_xname(self), "rnd hits");
194 evcnt_attach_dynamic(&sc->sc_rnd_miss, EVCNT_TYPE_MISC, 212 evcnt_attach_dynamic(&sc->sc_rnd_miss, EVCNT_TYPE_MISC,
195 NULL, device_xname(self), "rnd miss"); 213 NULL, device_xname(self), "rnd miss");
196 for (i = 0; i < 256; i++) { 214 for (i = 0; i < 256; i++) {
197 evcnt_attach_dynamic(&sc->sc_rnd_data[i], 215 evcnt_attach_dynamic(&sc->sc_rnd_data[i],
198 EVCNT_TYPE_MISC, NULL, device_xname(self), 216 EVCNT_TYPE_MISC, NULL, device_xname(self),
199 "rnd data"); 217 "rnd data");
200 } 218 }
201#endif 219#endif
 220 sc->sc_rnd_need = RND_POOLBITS / NBBY;
202 amdpm_rnd_callout(sc); 221 amdpm_rnd_callout(sc);
203 } 222 }
204 } 223 }
205} 224}
206 225
207CFATTACH_DECL_NEW(amdpm, sizeof(struct amdpm_softc), 226CFATTACH_DECL_NEW(amdpm, sizeof(struct amdpm_softc),
208 amdpm_match, amdpm_attach, NULL, NULL); 227 amdpm_match, amdpm_attach, NULL, NULL);
209 228
210static void 229static void
211amdpm_rnd_callout(void *v) 230amdpm_rnd_callout_locked(void *v)
212{ 231{
213 struct amdpm_softc *sc = v; 232 struct amdpm_softc *sc = v;
214 u_int32_t rngreg; 233 u_int32_t rngreg;
215#ifdef AMDPM_RND_COUNTERS 234#ifdef AMDPM_RND_COUNTERS
216 int i; 235 int i;
217#endif 236#endif
218 237
 238 if (sc->sc_rnd_need < 1) {
 239 callout_stop(&sc->sc_rnd_ch);
 240 return;
 241 }
 242
219 if ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_RNGSTAT) & 243 if ((bus_space_read_4(sc->sc_iot, sc->sc_ioh, AMDPM_RNGSTAT) &
220 AMDPM_RNGDONE) != 0) { 244 AMDPM_RNGDONE) != 0) {
221 rngreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 245 rngreg = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
222 AMDPM_RNGDATA); 246 AMDPM_RNGDATA);
223 rnd_add_data(&sc->sc_rnd_source, &rngreg, 247 rnd_add_data(&sc->sc_rnd_source, &rngreg,
224 sizeof(rngreg), sizeof(rngreg) * NBBY); 248 sizeof(rngreg), sizeof(rngreg) * NBBY);
 249 sc->sc_rnd_need -= sizeof(rngreg);
225#ifdef AMDPM_RND_COUNTERS 250#ifdef AMDPM_RND_COUNTERS
226 AMDPM_RNDCNT_INCR(&sc->sc_rnd_hits); 251 AMDPM_RNDCNT_INCR(&sc->sc_rnd_hits);
227 for (i = 0; i < sizeof(rngreg); i++, rngreg >>= NBBY) 252 for (i = 0; i < sizeof(rngreg); i++, rngreg >>= NBBY)
228 AMDPM_RNDCNT_INCR(&sc->sc_rnd_data[rngreg & 0xff]); 253 AMDPM_RNDCNT_INCR(&sc->sc_rnd_data[rngreg & 0xff]);
229#endif 254#endif
230 } 255 }
231#ifdef AMDPM_RND_COUNTERS 256#ifdef AMDPM_RND_COUNTERS
232 else 257 else
233 AMDPM_RNDCNT_INCR(&sc->sc_rnd_miss); 258 AMDPM_RNDCNT_INCR(&sc->sc_rnd_miss);
234#endif 259#endif
235 callout_reset(&sc->sc_rnd_ch, 1, amdpm_rnd_callout, sc); 260 if (sc->sc_rnd_need > 0) {
 261 callout_reset(&sc->sc_rnd_ch, 1, amdpm_rnd_callout, sc);
 262 }
 263}
 264
 265static void
 266amdpm_rnd_callout(void *v)
 267{
 268 struct amdpm_softc *sc = v;
 269
 270 mutex_enter(&sc->sc_mutex);
 271 amdpm_rnd_callout_locked(v);
 272 mutex_exit(&sc->sc_mutex);
236} 273}

cvs diff -r1.19 -r1.20 src/sys/dev/pci/amdpm_smbus.c (expand / switch to unified diff)

--- src/sys/dev/pci/amdpm_smbus.c 2012/10/27 17:18:28 1.19
+++ src/sys/dev/pci/amdpm_smbus.c 2013/06/13 00:55:01 1.20
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: amdpm_smbus.c,v 1.19 2012/10/27 17:18:28 chs Exp $ */ 1/* $NetBSD: amdpm_smbus.c,v 1.20 2013/06/13 00:55:01 tls Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 Anil Gopinath (anil_public@yahoo.com) 4 * Copyright (c) 2005 Anil Gopinath (anil_public@yahoo.com)
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -22,27 +22,27 @@ @@ -22,27 +22,27 @@
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31/* driver for SMBUS 1.0 host controller found in the 31/* driver for SMBUS 1.0 host controller found in the
32 * AMD-8111 HyperTransport I/O Hub 32 * AMD-8111 HyperTransport I/O Hub
33 */ 33 */
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: amdpm_smbus.c,v 1.19 2012/10/27 17:18:28 chs Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: amdpm_smbus.c,v 1.20 2013/06/13 00:55:01 tls Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/systm.h> 38#include <sys/systm.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/rnd.h> 41#include <sys/rnd.h>
42#include <sys/mutex.h> 42#include <sys/mutex.h>
43 43
44#include <dev/pci/pcireg.h> 44#include <dev/pci/pcireg.h>
45#include <dev/pci/pcivar.h> 45#include <dev/pci/pcivar.h>
46#include <dev/pci/pcidevs.h> 46#include <dev/pci/pcidevs.h>
47 47
48#include <dev/i2c/i2cvar.h> 48#include <dev/i2c/i2cvar.h>
@@ -73,28 +73,26 @@ amdpm_smbus_attach(struct amdpm_softc *s @@ -73,28 +73,26 @@ amdpm_smbus_attach(struct amdpm_softc *s
73 struct i2cbus_attach_args iba; 73 struct i2cbus_attach_args iba;
74  74
75 /* register with iic */ 75 /* register with iic */
76 sc->sc_i2c.ic_cookie = sc;  76 sc->sc_i2c.ic_cookie = sc;
77 sc->sc_i2c.ic_acquire_bus = amdpm_smbus_acquire_bus;  77 sc->sc_i2c.ic_acquire_bus = amdpm_smbus_acquire_bus;
78 sc->sc_i2c.ic_release_bus = amdpm_smbus_release_bus; 78 sc->sc_i2c.ic_release_bus = amdpm_smbus_release_bus;
79 sc->sc_i2c.ic_send_start = NULL; 79 sc->sc_i2c.ic_send_start = NULL;
80 sc->sc_i2c.ic_send_stop = NULL; 80 sc->sc_i2c.ic_send_stop = NULL;
81 sc->sc_i2c.ic_initiate_xfer = NULL; 81 sc->sc_i2c.ic_initiate_xfer = NULL;
82 sc->sc_i2c.ic_read_byte = NULL; 82 sc->sc_i2c.ic_read_byte = NULL;
83 sc->sc_i2c.ic_write_byte = NULL; 83 sc->sc_i2c.ic_write_byte = NULL;
84 sc->sc_i2c.ic_exec = amdpm_smbus_exec; 84 sc->sc_i2c.ic_exec = amdpm_smbus_exec;
85 85
86 mutex_init(&sc->sc_mutex, MUTEX_DEFAULT, IPL_NONE); 
87 
88 iba.iba_tag = &sc->sc_i2c; 86 iba.iba_tag = &sc->sc_i2c;
89 (void)config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print); 87 (void)config_found_ia(sc->sc_dev, "i2cbus", &iba, iicbus_print);
90} 88}
91 89
92static int 90static int
93amdpm_smbus_acquire_bus(void *cookie, int flags) 91amdpm_smbus_acquire_bus(void *cookie, int flags)
94{ 92{
95 struct amdpm_softc *sc = cookie; 93 struct amdpm_softc *sc = cookie;
96 94
97 mutex_enter(&sc->sc_mutex); 95 mutex_enter(&sc->sc_mutex);
98 return 0; 96 return 0;
99} 97}
100 98

cvs diff -r1.9 -r1.10 src/sys/dev/pci/amdpmvar.h (expand / switch to unified diff)

--- src/sys/dev/pci/amdpmvar.h 2012/10/27 17:18:28 1.9
+++ src/sys/dev/pci/amdpmvar.h 2013/06/13 00:55:01 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: amdpmvar.h,v 1.9 2012/10/27 17:18:28 chs Exp $ */ 1/* $NetBSD: amdpmvar.h,v 1.10 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Enami Tsugutomo. 8 * by Enami Tsugutomo.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -43,23 +43,24 @@ struct amdpm_softc { @@ -43,23 +43,24 @@ struct amdpm_softc {
43 43
44 bus_space_tag_t sc_iot; 44 bus_space_tag_t sc_iot;
45 bus_space_handle_t sc_ioh; /* PMxx space */ 45 bus_space_handle_t sc_ioh; /* PMxx space */
46 bus_space_handle_t sc_sm_ioh; /* SM space */ 46 bus_space_handle_t sc_sm_ioh; /* SM space */
47 47
48 i2c_addr_t sc_smbus_slaveaddr; /* address of smbus slave */ 48 i2c_addr_t sc_smbus_slaveaddr; /* address of smbus slave */
49 struct i2c_controller sc_i2c; /* i2c controller info */ 49 struct i2c_controller sc_i2c; /* i2c controller info */
50 kmutex_t sc_mutex; 50 kmutex_t sc_mutex;
51 51
52 void *sc_ih; 52 void *sc_ih;
53 53
54 struct callout sc_rnd_ch; 54 struct callout sc_rnd_ch;
55 krndsource_t sc_rnd_source; 55 krndsource_t sc_rnd_source;
 56 int sc_rnd_need;
56#ifdef AMDPM_RND_COUNTERS 57#ifdef AMDPM_RND_COUNTERS
57 struct evcnt sc_rnd_hits; 58 struct evcnt sc_rnd_hits;
58 struct evcnt sc_rnd_miss; 59 struct evcnt sc_rnd_miss;
59 struct evcnt sc_rnd_data[256]; 60 struct evcnt sc_rnd_data[256];
60#endif 61#endif
61 62
62 char sc_nforce; 63 char sc_nforce;
63}; 64};
64 65
65#endif /* _DEV_PCI_AMDPMVAR_H_ */ 66#endif /* _DEV_PCI_AMDPMVAR_H_ */

cvs diff -r1.9 -r1.10 src/sys/dev/pci/hifn7751var.h (expand / switch to unified diff)

--- src/sys/dev/pci/hifn7751var.h 2012/10/27 17:18:32 1.9
+++ src/sys/dev/pci/hifn7751var.h 2013/06/13 00:55:01 1.10
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hifn7751var.h,v 1.9 2012/10/27 17:18:32 chs Exp $ */ 1/* $NetBSD: hifn7751var.h,v 1.10 2013/06/13 00:55:01 tls Exp $ */
2/* $OpenBSD: hifn7751var.h,v 1.18 2000/06/02 22:36:45 deraadt Exp $ */ 2/* $OpenBSD: hifn7751var.h,v 1.18 2000/06/02 22:36:45 deraadt Exp $ */
3 3
4/* 4/*
5 * Invertex AEON / Hifn 7751 driver 5 * Invertex AEON / Hifn 7751 driver
6 * Copyright (c) 1999 Invertex Inc. All rights reserved. 6 * Copyright (c) 1999 Invertex Inc. All rights reserved.
7 * Copyright (c) 1999 Theo de Raadt 7 * Copyright (c) 1999 Theo de Raadt
8 * Copyright (c) 2000-2001 Network Security Technologies, Inc. 8 * Copyright (c) 2000-2001 Network Security Technologies, Inc.
9 * http://www.netsec.net 9 * http://www.netsec.net
10 * 10 *
11 * Please send any comments, feedback, bug-fixes, or feature requests to 11 * Please send any comments, feedback, bug-fixes, or feature requests to
12 * software@invertex.com. 12 * software@invertex.com.
13 * 13 *
14 * Redistribution and use in source and binary forms, with or without 14 * Redistribution and use in source and binary forms, with or without
@@ -159,41 +159,42 @@ struct hifn_softc { @@ -159,41 +159,42 @@ struct hifn_softc {
159#define HIFN_HAS_AES 0x04 /* includes AES support */ 159#define HIFN_HAS_AES 0x04 /* includes AES support */
160#define HIFN_IS_7811 0x08 /* Hifn 7811 part */ 160#define HIFN_IS_7811 0x08 /* Hifn 7811 part */
161#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */ 161#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
162#define HIFN_NO_BURSTWRITE 0x20 162#define HIFN_NO_BURSTWRITE 0x20
163#define HIFN_HAS_LEDS 0x40 163#define HIFN_HAS_LEDS 0x40
164 164
165#define HIFN_RNG_BITSPER 17 /* From Hifn 6500 paper: 0.06 bits 165#define HIFN_RNG_BITSPER 17 /* From Hifn 6500 paper: 0.06 bits
166 of entropy per RNG register bit 166 of entropy per RNG register bit
167 worst-case */ 167 worst-case */
168 168
169 struct callout sc_rngto; /* rng timeout */ 169 struct callout sc_rngto; /* rng timeout */
170 struct callout sc_tickto; /* led-clear timeout */ 170 struct callout sc_tickto; /* led-clear timeout */
171 krndsource_t sc_rnd_source; 171 krndsource_t sc_rnd_source;
172 int sc_rngfirst; 
173 int sc_rnghz; 172 int sc_rnghz;
 173 int sc_rng_need; /* how many bytes wanted */
174 int sc_c_busy; /* command ring busy */ 174 int sc_c_busy; /* command ring busy */
175 int sc_s_busy; /* source data ring busy */ 175 int sc_s_busy; /* source data ring busy */
176 int sc_d_busy; /* destination data ring busy */ 176 int sc_d_busy; /* destination data ring busy */
177 int sc_r_busy; /* result ring busy */ 177 int sc_r_busy; /* result ring busy */
178 int sc_active; /* for initial countdown */ 178 int sc_active; /* for initial countdown */
179 int sc_needwakeup; /* ops q'd wating on resources */ 179 int sc_needwakeup; /* ops q'd wating on resources */
180 int sc_curbatch; /* # ops submitted w/o int */ 180 int sc_curbatch; /* # ops submitted w/o int */
181 int sc_suspended; 181 int sc_suspended;
182 struct hifn_session sc_sessions[2048]; 182 struct hifn_session sc_sessions[2048];
183 pci_chipset_tag_t sc_pci_pc; 183 pci_chipset_tag_t sc_pci_pc;
184 pcitag_t sc_pci_tag; 184 pcitag_t sc_pci_tag;
185 bus_size_t sc_waw_lastreg; 185 bus_size_t sc_waw_lastreg;
186 int sc_waw_lastgroup; 186 int sc_waw_lastgroup;
 187 kmutex_t sc_mtx;
187}; 188};
188 189
189#define WRITE_REG_0(sc,reg,val) hifn_write_4((sc), 0, (reg), (val)) 190#define WRITE_REG_0(sc,reg,val) hifn_write_4((sc), 0, (reg), (val))
190#define WRITE_REG_1(sc,reg,val) hifn_write_4((sc), 1, (reg), (val)) 191#define WRITE_REG_1(sc,reg,val) hifn_write_4((sc), 1, (reg), (val))
191#define READ_REG_0(sc,reg) hifn_read_4((sc), 0, (reg)) 192#define READ_REG_0(sc,reg) hifn_read_4((sc), 0, (reg))
192#define READ_REG_1(sc,reg) hifn_read_4((sc), 1, (reg)) 193#define READ_REG_1(sc,reg) hifn_read_4((sc), 1, (reg))
193 194
194#define SET_LED(sc,v) \ 195#define SET_LED(sc,v) \
195 if (sc->sc_flags & HIFN_HAS_LEDS) \ 196 if (sc->sc_flags & HIFN_HAS_LEDS) \
196 WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \ 197 WRITE_REG_1(sc, HIFN_1_7811_MIPSRST, \
197 READ_REG_1(sc, HIFN_1_7811_MIPSRST) | (v)) 198 READ_REG_1(sc, HIFN_1_7811_MIPSRST) | (v))
198#define CLR_LED(sc,v) \ 199#define CLR_LED(sc,v) \
199 if (sc->sc_flags & HIFN_HAS_LEDS) \ 200 if (sc->sc_flags & HIFN_HAS_LEDS) \

cvs diff -r1.51 -r1.52 src/sys/dev/pci/hifn7751.c (expand / switch to unified diff)

--- src/sys/dev/pci/hifn7751.c 2012/10/27 17:18:32 1.51
+++ src/sys/dev/pci/hifn7751.c 2013/06/13 00:55:01 1.52
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: hifn7751.c,v 1.51 2012/10/27 17:18:32 chs Exp $ */ 1/* $NetBSD: hifn7751.c,v 1.52 2013/06/13 00:55:01 tls Exp $ */
2/* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */ 2/* $FreeBSD: hifn7751.c,v 1.5.2.7 2003/10/08 23:52:00 sam Exp $ */
3/* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */ 3/* $OpenBSD: hifn7751.c,v 1.140 2003/08/01 17:55:54 deraadt Exp $ */
4 4
5/* 5/*
6 * Invertex AEON / Hifn 7751 driver 6 * Invertex AEON / Hifn 7751 driver
7 * Copyright (c) 1999 Invertex Inc. All rights reserved. 7 * Copyright (c) 1999 Invertex Inc. All rights reserved.
8 * Copyright (c) 1999 Theo de Raadt 8 * Copyright (c) 1999 Theo de Raadt
9 * Copyright (c) 2000-2001 Network Security Technologies, Inc. 9 * Copyright (c) 2000-2001 Network Security Technologies, Inc.
10 * http://www.netsec.net 10 * http://www.netsec.net
11 * Copyright (c) 2003 Hifn Inc. 11 * Copyright (c) 2003 Hifn Inc.
12 * 12 *
13 * This driver is based on a previous driver by Invertex, for which they 13 * This driver is based on a previous driver by Invertex, for which they
14 * requested: Please send any comments, feedback, bug-fixes, or feature 14 * requested: Please send any comments, feedback, bug-fixes, or feature
@@ -38,30 +38,31 @@ @@ -38,30 +38,31 @@
38 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * 39 *
40 * Effort sponsored in part by the Defense Advanced Research Projects 40 * Effort sponsored in part by the Defense Advanced Research Projects
41 * Agency (DARPA) and Air Force Research Laboratory, Air Force 41 * Agency (DARPA) and Air Force Research Laboratory, Air Force
42 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 42 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
43 * 43 *
44 */ 44 */
45 45
46/* 46/*
47 * Driver for various Hifn pre-HIPP encryption processors. 47 * Driver for various Hifn pre-HIPP encryption processors.
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.51 2012/10/27 17:18:32 chs Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: hifn7751.c,v 1.52 2013/06/13 00:55:01 tls Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
 55#include <sys/mutex.h>
55#include <sys/proc.h> 56#include <sys/proc.h>
56#include <sys/errno.h> 57#include <sys/errno.h>
57#include <sys/malloc.h> 58#include <sys/malloc.h>
58#include <sys/kernel.h> 59#include <sys/kernel.h>
59#include <sys/mbuf.h> 60#include <sys/mbuf.h>
60#include <sys/device.h> 61#include <sys/device.h>
61 62
62#ifdef __OpenBSD__ 63#ifdef __OpenBSD__
63#include <crypto/crypto.h> 64#include <crypto/crypto.h>
64#include <dev/rndvar.h> 65#include <dev/rndvar.h>
65#else 66#else
66#include <opencrypto/cryptodev.h> 67#include <opencrypto/cryptodev.h>
67#include <sys/cprng.h> 68#include <sys/cprng.h>
@@ -130,42 +131,42 @@ static int hifn_process(void*, struct cr @@ -130,42 +131,42 @@ static int hifn_process(void*, struct cr
130static void hifn_callback(struct hifn_softc *, struct hifn_command *, 131static void hifn_callback(struct hifn_softc *, struct hifn_command *,
131 u_int8_t *); 132 u_int8_t *);
132static int hifn_crypto(struct hifn_softc *, struct hifn_command *, 133static int hifn_crypto(struct hifn_softc *, struct hifn_command *,
133 struct cryptop*, int); 134 struct cryptop*, int);
134static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *); 135static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
135static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *); 136static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
136static int hifn_dmamap_aligned(bus_dmamap_t); 137static int hifn_dmamap_aligned(bus_dmamap_t);
137static int hifn_dmamap_load_src(struct hifn_softc *, 138static int hifn_dmamap_load_src(struct hifn_softc *,
138 struct hifn_command *); 139 struct hifn_command *);
139static int hifn_dmamap_load_dst(struct hifn_softc *, 140static int hifn_dmamap_load_dst(struct hifn_softc *,
140 struct hifn_command *); 141 struct hifn_command *);
141static int hifn_init_pubrng(struct hifn_softc *); 142static int hifn_init_pubrng(struct hifn_softc *);
142static void hifn_rng(void *); 143static void hifn_rng(void *);
 144static void hifn_rng_locked(void *);
143static void hifn_tick(void *); 145static void hifn_tick(void *);
144static void hifn_abort(struct hifn_softc *); 146static void hifn_abort(struct hifn_softc *);
145static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, 147static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *,
146 int *); 148 int *);
147static void hifn_write_4(struct hifn_softc *, int, bus_size_t, u_int32_t); 149static void hifn_write_4(struct hifn_softc *, int, bus_size_t, u_int32_t);
148static u_int32_t hifn_read_4(struct hifn_softc *, int, bus_size_t); 150static u_int32_t hifn_read_4(struct hifn_softc *, int, bus_size_t);
149#ifdef HAVE_CRYPTO_LZS 151#ifdef HAVE_CRYPTO_LZS
150static int hifn_compression(struct hifn_softc *, struct cryptop *, 152static int hifn_compression(struct hifn_softc *, struct cryptop *,
151 struct hifn_command *); 153 struct hifn_command *);
152static struct mbuf *hifn_mkmbuf_chain(int, struct mbuf *); 154static struct mbuf *hifn_mkmbuf_chain(int, struct mbuf *);
153static int hifn_compress_enter(struct hifn_softc *, struct hifn_command *); 155static int hifn_compress_enter(struct hifn_softc *, struct hifn_command *);
154static void hifn_callback_comp(struct hifn_softc *, struct hifn_command *, 156static void hifn_callback_comp(struct hifn_softc *, struct hifn_command *,
155 u_int8_t *); 157 u_int8_t *);
156#endif /* HAVE_CRYPTO_LZS */ 158#endif /* HAVE_CRYPTO_LZS */
157 159
158 
159struct hifn_stats hifnstats; 160struct hifn_stats hifnstats;
160 161
161static const struct hifn_product { 162static const struct hifn_product {
162 pci_vendor_id_t hifn_vendor; 163 pci_vendor_id_t hifn_vendor;
163 pci_product_id_t hifn_product; 164 pci_product_id_t hifn_product;
164 int hifn_flags; 165 int hifn_flags;
165 const char *hifn_name; 166 const char *hifn_name;
166} hifn_products[] = { 167} hifn_products[] = {
167 { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON, 168 { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
168 0, 169 0,
169 "Invertex AEON", 170 "Invertex AEON",
170 }, 171 },
171 172
@@ -408,56 +409,72 @@ hifn_attach(device_t parent, device_t se @@ -408,56 +409,72 @@ hifn_attach(device_t parent, device_t se
408 crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC_96, 0, 0, 409 crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC_96, 0, 0,
409 hifn_newsession, hifn_freesession, hifn_process, sc); 410 hifn_newsession, hifn_freesession, hifn_process, sc);
410 crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC_96, 0, 0, 411 crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC_96, 0, 0,
411 hifn_newsession, hifn_freesession, hifn_process, sc); 412 hifn_newsession, hifn_freesession, hifn_process, sc);
412 crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0, 413 crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0,
413 hifn_newsession, hifn_freesession, hifn_process, sc); 414 hifn_newsession, hifn_freesession, hifn_process, sc);
414 break; 415 break;
415 } 416 }
416 417
417 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0, 418 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap, 0,
418 sc->sc_dmamap->dm_mapsize, 419 sc->sc_dmamap->dm_mapsize,
419 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 420 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
420 421
421 if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG)) 422 if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG)) {
422 hifn_init_pubrng(sc); 423 hifn_init_pubrng(sc);
 424 sc->sc_rng_need = RND_POOLBITS / NBBY;
 425 }
 426
 427 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM);
423 428
424#ifdef __OpenBSD__ 429#ifdef __OpenBSD__
425 timeout_set(&sc->sc_tickto, hifn_tick, sc); 430 timeout_set(&sc->sc_tickto, hifn_tick, sc);
426 timeout_add(&sc->sc_tickto, hz); 431 timeout_add(&sc->sc_tickto, hz);
427#else 432#else
428 callout_init(&sc->sc_tickto, 0); 433 callout_init(&sc->sc_tickto, CALLOUT_MPSAFE);
429 callout_reset(&sc->sc_tickto, hz, hifn_tick, sc); 434 callout_reset(&sc->sc_tickto, hz, hifn_tick, sc);
430#endif 435#endif
431 return; 436 return;
432 437
433fail_intr: 438fail_intr:
434 pci_intr_disestablish(pc, sc->sc_ih); 439 pci_intr_disestablish(pc, sc->sc_ih);
435fail_mem: 440fail_mem:
436 bus_dmamap_unload(sc->sc_dmat, dmamap); 441 bus_dmamap_unload(sc->sc_dmat, dmamap);
437 bus_dmamap_destroy(sc->sc_dmat, dmamap); 442 bus_dmamap_destroy(sc->sc_dmat, dmamap);
438 bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma)); 443 bus_dmamem_unmap(sc->sc_dmat, kva, sizeof(*sc->sc_dma));
439 bus_dmamem_free(sc->sc_dmat, &seg, rseg); 444 bus_dmamem_free(sc->sc_dmat, &seg, rseg);
440 445
441 /* Turn off DMA polling */ 446 /* Turn off DMA polling */
442 WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET | 447 WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
443 HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE); 448 HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
444 449
445fail_io1: 450fail_io1:
446 bus_space_unmap(sc->sc_st1, sc->sc_sh1, iosize1); 451 bus_space_unmap(sc->sc_st1, sc->sc_sh1, iosize1);
447fail_io0: 452fail_io0:
448 bus_space_unmap(sc->sc_st0, sc->sc_sh0, iosize0); 453 bus_space_unmap(sc->sc_st0, sc->sc_sh0, iosize0);
449} 454}
450 455
 456static void
 457hifn_rng_get(size_t bytes, void *priv)
 458{
 459 struct hifn_softc *sc = priv;
 460
 461 mutex_enter(&sc->sc_mtx);
 462 sc->sc_rng_need = bytes;
 463
 464 hifn_rng_locked(sc);
 465 mutex_exit(&sc->sc_mtx);
 466}
 467
451static int 468static int
452hifn_init_pubrng(struct hifn_softc *sc) 469hifn_init_pubrng(struct hifn_softc *sc)
453{ 470{
454 u_int32_t r; 471 u_int32_t r;
455 int i; 472 int i;
456 473
457 if ((sc->sc_flags & HIFN_IS_7811) == 0) { 474 if ((sc->sc_flags & HIFN_IS_7811) == 0) {
458 /* Reset 7951 public key/rng engine */ 475 /* Reset 7951 public key/rng engine */
459 WRITE_REG_1(sc, HIFN_1_PUB_RESET, 476 WRITE_REG_1(sc, HIFN_1_PUB_RESET,
460 READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET); 477 READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
461 478
462 for (i = 0; i < 100; i++) { 479 for (i = 0; i < 100; i++) {
463 DELAY(1000); 480 DELAY(1000);
@@ -490,182 +507,196 @@ hifn_init_pubrng(struct hifn_softc *sc) @@ -490,182 +507,196 @@ hifn_init_pubrng(struct hifn_softc *sc)
490 READ_REG_1(sc, HIFN_1_RNG_CONFIG) | 507 READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
491 HIFN_RNGCFG_ENA); 508 HIFN_RNGCFG_ENA);
492 509
493 /* 510 /*
494 * The Hifn RNG documentation states that at their 511 * The Hifn RNG documentation states that at their
495 * recommended "conservative" RNG config values, 512 * recommended "conservative" RNG config values,
496 * the RNG must warm up for 0.4s before providing 513 * the RNG must warm up for 0.4s before providing
497 * data that meet their worst-case estimate of 0.06 514 * data that meet their worst-case estimate of 0.06
498 * bits of random data per output register bit. 515 * bits of random data per output register bit.
499 */ 516 */
500 DELAY(4000); 517 DELAY(4000);
501 518
502#ifdef __NetBSD__ 519#ifdef __NetBSD__
 520 rndsource_setcb(&sc->sc_rnd_source, hifn_rng_get, sc);
503 /* 521 /*
504 * XXX Careful! The use of RND_FLAG_NO_ESTIMATE 522 * XXX Careful! The use of RND_FLAG_NO_ESTIMATE
505 * XXX here is unobvious: we later feed raw bits 523 * XXX here is unobvious: we later feed raw bits
506 * XXX into the "entropy pool" with rnd_add_data, 524 * XXX into the "entropy pool" with rnd_add_data,
507 * XXX explicitly supplying an entropy estimate. 525 * XXX explicitly supplying an entropy estimate.
508 * XXX In this context, NO_ESTIMATE serves only 526 * XXX In this context, NO_ESTIMATE serves only
509 * XXX to prevent rnd_add_data from trying to 527 * XXX to prevent rnd_add_data from trying to
510 * XXX use the *time at which we added the data* 528 * XXX use the *time at which we added the data*
511 * XXX as entropy, which is not a good idea since 529 * XXX as entropy, which is not a good idea since
512 * XXX we add data periodically from a callout. 530 * XXX we add data periodically from a callout.
513 */ 531 */
514 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dv), 532 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dv),
515 RND_TYPE_RNG, RND_FLAG_NO_ESTIMATE); 533 RND_TYPE_RNG,
 534 RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
516#endif 535#endif
517 536
518 sc->sc_rngfirst = 1; 
519 if (hz >= 100) 537 if (hz >= 100)
520 sc->sc_rnghz = hz / 100; 538 sc->sc_rnghz = hz / 100;
521 else 539 else
522 sc->sc_rnghz = 1; 540 sc->sc_rnghz = 1;
523#ifdef __OpenBSD__ 541#ifdef __OpenBSD__
524 timeout_set(&sc->sc_rngto, hifn_rng, sc); 542 timeout_set(&sc->sc_rngto, hifn_rng, sc);
525#else /* !__OpenBSD__ */ 543#else /* !__OpenBSD__ */
526 callout_init(&sc->sc_rngto, 0); 544 callout_init(&sc->sc_rngto, CALLOUT_MPSAFE);
527#endif /* !__OpenBSD__ */ 545#endif /* !__OpenBSD__ */
528 } 546 }
529 547
530 /* Enable public key engine, if available */ 548 /* Enable public key engine, if available */
531 if (sc->sc_flags & HIFN_HAS_PUBLIC) { 549 if (sc->sc_flags & HIFN_HAS_PUBLIC) {
532 WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE); 550 WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
533 sc->sc_dmaier |= HIFN_DMAIER_PUBDONE; 551 sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
534 WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); 552 WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
535 } 553 }
536 554
537 /* Call directly into the RNG once to prime the pool. */ 555 /* Call directly into the RNG once to prime the pool. */
538 hifn_rng(sc); /* Sets callout/timeout at end */ 556 hifn_rng(sc); /* Sets callout/timeout at end */
539 557
540 return (0); 558 return (0);
541} 559}
542 560
543static void 561static void
544hifn_rng(void *vsc) 562hifn_rng_locked(void *vsc)
545{ 563{
546 struct hifn_softc *sc = vsc; 564 struct hifn_softc *sc = vsc;
547#ifdef __NetBSD__ 565#ifdef __NetBSD__
548 uint32_t num[64]; 566 uint32_t num[64];
549#else 567#else
550 uint32_t num[2]; 568 uint32_t num[2];
551#endif 569#endif
552 uint32_t sts; 570 uint32_t sts;
553 int i; 571 int i;
 572 size_t got, gotent;
 573
 574 if (sc->sc_rng_need < 1) {
 575 callout_stop(&sc->sc_rngto);
 576 return;
 577 }
554 578
555 if (sc->sc_flags & HIFN_IS_7811) { 579 if (sc->sc_flags & HIFN_IS_7811) {
556 for (i = 0; i < 5; i++) { /* XXX why 5? */ 580 for (i = 0; i < 5; i++) { /* XXX why 5? */
557 sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS); 581 sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
558 if (sts & HIFN_7811_RNGSTS_UFL) { 582 if (sts & HIFN_7811_RNGSTS_UFL) {
559 printf("%s: RNG underflow: disabling\n", 583 printf("%s: RNG underflow: disabling\n",
560 device_xname(sc->sc_dv)); 584 device_xname(sc->sc_dv));
561 return; 585 return;
562 } 586 }
563 if ((sts & HIFN_7811_RNGSTS_RDY) == 0) 587 if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
564 break; 588 break;
565 589
566 /* 590 /*
567 * There are at least two words in the RNG FIFO 591 * There are at least two words in the RNG FIFO
568 * at this point. 592 * at this point.
569 */ 593 */
570 num[0] = READ_REG_1(sc, HIFN_1_7811_RNGDAT); 594 num[0] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
571 num[1] = READ_REG_1(sc, HIFN_1_7811_RNGDAT); 595 num[1] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
 596 got = 2 * sizeof(num[0]);
 597 gotent = (got * NBBY) / HIFN_RNG_BITSPER;
572 598
573 if (sc->sc_rngfirst) 
574 sc->sc_rngfirst = 0; 
575#ifdef __NetBSD__ 599#ifdef __NetBSD__
576 rnd_add_data(&sc->sc_rnd_source, num, 600 rnd_add_data(&sc->sc_rnd_source, num, got, gotent);
577 2 * sizeof(num[0]), 601 sc->sc_rng_need -= gotent;
578 (2 * sizeof(num[0]) * NBBY) / 
579 HIFN_RNG_BITSPER); 
580#else 602#else
581 /* 603 /*
582 * XXX This is a really bad idea. 604 * XXX This is a really bad idea.
583 * XXX Hifn estimate as little as 0.06 605 * XXX Hifn estimate as little as 0.06
584 * XXX actual bits of entropy per output 606 * XXX actual bits of entropy per output
585 * XXX register bit. How can we tell the 607 * XXX register bit. How can we tell the
586 * XXX kernel RNG subsystem we're handing 608 * XXX kernel RNG subsystem we're handing
587 * XXX it 64 "true" random bits, for any 609 * XXX it 64 "true" random bits, for any
588 * XXX sane value of "true"? 610 * XXX sane value of "true"?
589 * XXX 611 * XXX
590 * XXX The right thing to do here, if we 612 * XXX The right thing to do here, if we
591 * XXX cannot supply an estimate ourselves, 613 * XXX cannot supply an estimate ourselves,
592 * XXX would be to hash the bits locally. 614 * XXX would be to hash the bits locally.
593 */ 615 */
594 add_true_randomness(num[0]); 616 add_true_randomness(num[0]);
595 add_true_randomness(num[1]); 617 add_true_randomness(num[1]);
596#endif 618#endif
597  619
598 } 620 }
599 } else { 621 } else {
600#ifdef __NetBSD__ 622 int nwords = 0;
601 /* First time through, try to help fill the pool. */ 623
602 int nwords = sc->sc_rngfirst ? 624 if (sc->sc_rng_need) {
603 sizeof(num) / sizeof(num[0]) : 4; 625 nwords = (sc->sc_rng_need * NBBY) / HIFN_RNG_BITSPER;
604#else 626 }
605 int nwords = 2; 627
606#endif 628 if (nwords < 2) {
 629 nwords = 2;
 630 }
 631
607 /* 632 /*
608 * We must be *extremely* careful here. The Hifn 633 * We must be *extremely* careful here. The Hifn
609 * 795x differ from the published 6500 RNG design 634 * 795x differ from the published 6500 RNG design
610 * in more ways than the obvious lack of the output 635 * in more ways than the obvious lack of the output
611 * FIFO and LFSR control registers. In fact, there 636 * FIFO and LFSR control registers. In fact, there
612 * is only one LFSR, instead of the 6500's two, and 637 * is only one LFSR, instead of the 6500's two, and
613 * it's 32 bits, not 31. 638 * it's 32 bits, not 31.
614 * 639 *
615 * Further, a block diagram obtained from Hifn shows 640 * Further, a block diagram obtained from Hifn shows
616 * a very curious latching of this register: the LFSR 641 * a very curious latching of this register: the LFSR
617 * rotates at a frequency of RNG_Clk / 8, but the 642 * rotates at a frequency of RNG_Clk / 8, but the
618 * RNG_Data register is latched at a frequency of 643 * RNG_Data register is latched at a frequency of
619 * RNG_Clk, which means that it is possible for 644 * RNG_Clk, which means that it is possible for
620 * consecutive reads of the RNG_Data register to read 645 * consecutive reads of the RNG_Data register to read
621 * identical state from the LFSR. The simplest 646 * identical state from the LFSR. The simplest
622 * workaround seems to be to read eight samples from 647 * workaround seems to be to read eight samples from
623 * the register for each one that we use. Since each 648 * the register for each one that we use. Since each
624 * read must require at least one PCI cycle, and 649 * read must require at least one PCI cycle, and
625 * RNG_Clk is at least PCI_Clk, this is safe. 650 * RNG_Clk is at least PCI_Clk, this is safe.
626 */ 651 */
627 
628 
629 if (sc->sc_rngfirst) { 
630 sc->sc_rngfirst = 0; 
631 } 
632  
633 
634 for(i = 0 ; i < nwords * 8; i++) 652 for(i = 0 ; i < nwords * 8; i++)
635 { 653 {
636 volatile u_int32_t regtmp; 654 volatile u_int32_t regtmp;
637 regtmp = READ_REG_1(sc, HIFN_1_RNG_DATA); 655 regtmp = READ_REG_1(sc, HIFN_1_RNG_DATA);
638 num[i / 8] = regtmp; 656 num[i / 8] = regtmp;
639 } 657 }
 658
 659 got = nwords * sizeof(num[0]);
 660 gotent = (got * NBBY) / HIFN_RNG_BITSPER;
640#ifdef __NetBSD__ 661#ifdef __NetBSD__
641 rnd_add_data(&sc->sc_rnd_source, num, 662 rnd_add_data(&sc->sc_rnd_source, num, got, gotent);
642 nwords * sizeof(num[0]), 663 sc->sc_rng_need -= gotent;
643 (nwords * sizeof(num[0]) * NBBY) / 
644 HIFN_RNG_BITSPER); 
645#else 664#else
646 /* XXX a bad idea; see 7811 block above */ 665 /* XXX a bad idea; see 7811 block above */
647 add_true_randomness(num[0]); 666 add_true_randomness(num[0]);
648#endif 667#endif
649 } 668 }
650 669
651#ifdef __OpenBSD__ 670#ifdef __OpenBSD__
652 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 671 timeout_add(&sc->sc_rngto, sc->sc_rnghz);
653#else 672#else
654 callout_reset(&sc->sc_rngto, sc->sc_rnghz, hifn_rng, sc); 673 if (sc->sc_rng_need > 0) {
 674 callout_reset(&sc->sc_rngto, sc->sc_rnghz, hifn_rng, sc);
 675 }
655#endif 676#endif
656} 677}
657 678
658static void 679static void
 680hifn_rng(void *vsc)
 681{
 682 struct hifn_softc *sc = vsc;
 683
 684 mutex_spin_enter(&sc->sc_mtx);
 685 hifn_rng_locked(vsc);
 686 mutex_spin_exit(&sc->sc_mtx);
 687}
 688
 689static void
659hifn_puc_wait(struct hifn_softc *sc) 690hifn_puc_wait(struct hifn_softc *sc)
660{ 691{
661 int i; 692 int i;
662 693
663 for (i = 5000; i > 0; i--) { 694 for (i = 5000; i > 0; i--) {
664 DELAY(1); 695 DELAY(1);
665 if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET)) 696 if (!(READ_REG_0(sc, HIFN_0_PUCTRL) & HIFN_PUCTRL_RESET))
666 break; 697 break;
667 } 698 }
668 if (!i) 699 if (!i)
669 printf("%s: proc unit did not reset\n", device_xname(sc->sc_dv)); 700 printf("%s: proc unit did not reset\n", device_xname(sc->sc_dv));
670} 701}
671 702
@@ -1580,27 +1611,27 @@ hifn_dmamap_load_src(struct hifn_softc * @@ -1580,27 +1611,27 @@ hifn_dmamap_load_src(struct hifn_softc *
1580 } 1611 }
1581 } 1612 }
1582 dma->srci = idx; 1613 dma->srci = idx;
1583 dma->srcu += map->dm_nsegs; 1614 dma->srcu += map->dm_nsegs;
1584 return (idx); 1615 return (idx);
1585} 1616}
1586 1617
1587static int 1618static int
1588hifn_crypto(struct hifn_softc *sc, struct hifn_command *cmd, 1619hifn_crypto(struct hifn_softc *sc, struct hifn_command *cmd,
1589 struct cryptop *crp, int hint) 1620 struct cryptop *crp, int hint)
1590{ 1621{
1591 struct hifn_dma *dma = sc->sc_dma; 1622 struct hifn_dma *dma = sc->sc_dma;
1592 u_int32_t cmdlen; 1623 u_int32_t cmdlen;
1593 int cmdi, resi, s, err = 0; 1624 int cmdi, resi, err = 0;
1594 1625
1595 if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER, 1626 if (bus_dmamap_create(sc->sc_dmat, HIFN_MAX_DMALEN, MAX_SCATTER,
1596 HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map)) 1627 HIFN_MAX_SEGLEN, 0, BUS_DMA_NOWAIT, &cmd->src_map))
1597 return (ENOMEM); 1628 return (ENOMEM);
1598 1629
1599 if (crp->crp_flags & CRYPTO_F_IMBUF) { 1630 if (crp->crp_flags & CRYPTO_F_IMBUF) {
1600 if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map, 1631 if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->src_map,
1601 cmd->srcu.src_m, BUS_DMA_NOWAIT)) { 1632 cmd->srcu.src_m, BUS_DMA_NOWAIT)) {
1602 err = ENOMEM; 1633 err = ENOMEM;
1603 goto err_srcmap1; 1634 goto err_srcmap1;
1604 } 1635 }
1605 } else if (crp->crp_flags & CRYPTO_F_IOV) { 1636 } else if (crp->crp_flags & CRYPTO_F_IOV) {
1606 if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map, 1637 if (bus_dmamap_load_uio(sc->sc_dmat, cmd->src_map,
@@ -1710,41 +1741,37 @@ hifn_crypto(struct hifn_softc *sc, struc @@ -1710,41 +1741,37 @@ hifn_crypto(struct hifn_softc *sc, struc
1710#endif 1741#endif
1711 1742
1712 if (cmd->src_map == cmd->dst_map) 1743 if (cmd->src_map == cmd->dst_map)
1713 bus_dmamap_sync(sc->sc_dmat, cmd->src_map, 1744 bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
1714 0, cmd->src_map->dm_mapsize, 1745 0, cmd->src_map->dm_mapsize,
1715 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 1746 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
1716 else { 1747 else {
1717 bus_dmamap_sync(sc->sc_dmat, cmd->src_map, 1748 bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
1718 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 1749 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
1719 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, 1750 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
1720 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1751 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD);
1721 } 1752 }
1722 1753
1723 s = splnet(); 
1724 
1725 /* 1754 /*
1726 * need 1 cmd, and 1 res 1755 * need 1 cmd, and 1 res
1727 * need N src, and N dst 1756 * need N src, and N dst
1728 */ 1757 */
1729 if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || 1758 if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
1730 (dma->resu + 1) > HIFN_D_RES_RSIZE) { 1759 (dma->resu + 1) > HIFN_D_RES_RSIZE) {
1731 splx(s); 
1732 err = ENOMEM; 1760 err = ENOMEM;
1733 goto err_dstmap; 1761 goto err_dstmap;
1734 } 1762 }
1735 if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || 1763 if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE ||
1736 (dma->dstu + cmd->dst_map->dm_nsegs + 1) > HIFN_D_DST_RSIZE) { 1764 (dma->dstu + cmd->dst_map->dm_nsegs + 1) > HIFN_D_DST_RSIZE) {
1737 splx(s); 
1738 err = ENOMEM; 1765 err = ENOMEM;
1739 goto err_dstmap; 1766 goto err_dstmap;
1740 } 1767 }
1741 1768
1742 if (dma->cmdi == HIFN_D_CMD_RSIZE) { 1769 if (dma->cmdi == HIFN_D_CMD_RSIZE) {
1743 dma->cmdi = 0; 1770 dma->cmdi = 0;
1744 dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID | 1771 dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_VALID |
1745 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ); 1772 HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
1746 HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE, 1773 HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
1747 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1774 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1748 } 1775 }
1749 cmdi = dma->cmdi++; 1776 cmdi = dma->cmdi++;
1750 cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]); 1777 cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
@@ -1827,52 +1854,50 @@ hifn_crypto(struct hifn_softc *sc, struc @@ -1827,52 +1854,50 @@ hifn_crypto(struct hifn_softc *sc, struc
1827 if (sc->sc_d_busy == 0) { 1854 if (sc->sc_d_busy == 0) {
1828 WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA); 1855 WRITE_REG_1(sc, HIFN_1_DMA_CSR, HIFN_DMACSR_D_CTRL_ENA);
1829 sc->sc_d_busy = 1; 1856 sc->sc_d_busy = 1;
1830 } 1857 }
1831 1858
1832#ifdef HIFN_DEBUG 1859#ifdef HIFN_DEBUG
1833 if (hifn_debug) 1860 if (hifn_debug)
1834 printf("%s: command: stat %8x ier %8x\n", 1861 printf("%s: command: stat %8x ier %8x\n",
1835 device_xname(sc->sc_dv), 1862 device_xname(sc->sc_dv),
1836 READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER)); 1863 READ_REG_1(sc, HIFN_1_DMA_CSR), READ_REG_1(sc, HIFN_1_DMA_IER));
1837#endif 1864#endif
1838 1865
1839 sc->sc_active = 5; 1866 sc->sc_active = 5;
1840 splx(s); 
1841 return (err); /* success */ 1867 return (err); /* success */
1842 1868
1843err_dstmap: 1869err_dstmap:
1844 if (cmd->src_map != cmd->dst_map) 1870 if (cmd->src_map != cmd->dst_map)
1845 bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); 1871 bus_dmamap_unload(sc->sc_dmat, cmd->dst_map);
1846err_dstmap1: 1872err_dstmap1:
1847 if (cmd->src_map != cmd->dst_map) 1873 if (cmd->src_map != cmd->dst_map)
1848 bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); 1874 bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map);
1849err_srcmap: 1875err_srcmap:
1850 if (crp->crp_flags & CRYPTO_F_IMBUF && 1876 if (crp->crp_flags & CRYPTO_F_IMBUF &&
1851 cmd->srcu.src_m != cmd->dstu.dst_m) 1877 cmd->srcu.src_m != cmd->dstu.dst_m)
1852 m_freem(cmd->dstu.dst_m); 1878 m_freem(cmd->dstu.dst_m);
1853 bus_dmamap_unload(sc->sc_dmat, cmd->src_map); 1879 bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
1854err_srcmap1: 1880err_srcmap1:
1855 bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); 1881 bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
1856 return (err); 1882 return (err);
1857} 1883}
1858 1884
1859static void 1885static void
1860hifn_tick(void *vsc) 1886hifn_tick(void *vsc)
1861{ 1887{
1862 struct hifn_softc *sc = vsc; 1888 struct hifn_softc *sc = vsc;
1863 int s; 
1864 1889
1865 s = splnet(); 1890 mutex_spin_enter(&sc->sc_mtx);
1866 if (sc->sc_active == 0) { 1891 if (sc->sc_active == 0) {
1867 struct hifn_dma *dma = sc->sc_dma; 1892 struct hifn_dma *dma = sc->sc_dma;
1868 u_int32_t r = 0; 1893 u_int32_t r = 0;
1869 1894
1870 if (dma->cmdu == 0 && sc->sc_c_busy) { 1895 if (dma->cmdu == 0 && sc->sc_c_busy) {
1871 sc->sc_c_busy = 0; 1896 sc->sc_c_busy = 0;
1872 r |= HIFN_DMACSR_C_CTRL_DIS; 1897 r |= HIFN_DMACSR_C_CTRL_DIS;
1873 CLR_LED(sc, HIFN_MIPSRST_LED0); 1898 CLR_LED(sc, HIFN_MIPSRST_LED0);
1874 } 1899 }
1875 if (dma->srcu == 0 && sc->sc_s_busy) { 1900 if (dma->srcu == 0 && sc->sc_s_busy) {
1876 sc->sc_s_busy = 0; 1901 sc->sc_s_busy = 0;
1877 r |= HIFN_DMACSR_S_CTRL_DIS; 1902 r |= HIFN_DMACSR_S_CTRL_DIS;
1878 CLR_LED(sc, HIFN_MIPSRST_LED1); 1903 CLR_LED(sc, HIFN_MIPSRST_LED1);
@@ -1881,55 +1906,59 @@ hifn_tick(void *vsc) @@ -1881,55 +1906,59 @@ hifn_tick(void *vsc)
1881 sc->sc_d_busy = 0; 1906 sc->sc_d_busy = 0;
1882 r |= HIFN_DMACSR_D_CTRL_DIS; 1907 r |= HIFN_DMACSR_D_CTRL_DIS;
1883 } 1908 }
1884 if (dma->resu == 0 && sc->sc_r_busy) { 1909 if (dma->resu == 0 && sc->sc_r_busy) {
1885 sc->sc_r_busy = 0; 1910 sc->sc_r_busy = 0;
1886 r |= HIFN_DMACSR_R_CTRL_DIS; 1911 r |= HIFN_DMACSR_R_CTRL_DIS;
1887 CLR_LED(sc, HIFN_MIPSRST_LED2); 1912 CLR_LED(sc, HIFN_MIPSRST_LED2);
1888 } 1913 }
1889 if (r) 1914 if (r)
1890 WRITE_REG_1(sc, HIFN_1_DMA_CSR, r); 1915 WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
1891 } 1916 }
1892 else 1917 else
1893 sc->sc_active--; 1918 sc->sc_active--;
1894 splx(s); 
1895#ifdef __OpenBSD__ 1919#ifdef __OpenBSD__
1896 timeout_add(&sc->sc_tickto, hz); 1920 timeout_add(&sc->sc_tickto, hz);
1897#else 1921#else
1898 callout_reset(&sc->sc_tickto, hz, hifn_tick, sc); 1922 callout_reset(&sc->sc_tickto, hz, hifn_tick, sc);
1899#endif 1923#endif
 1924 mutex_spin_exit(&sc->sc_mtx);
1900} 1925}
1901 1926
1902static int 1927static int
1903hifn_intr(void *arg) 1928hifn_intr(void *arg)
1904{ 1929{
1905 struct hifn_softc *sc = arg; 1930 struct hifn_softc *sc = arg;
1906 struct hifn_dma *dma = sc->sc_dma; 1931 struct hifn_dma *dma = sc->sc_dma;
1907 u_int32_t dmacsr, restart; 1932 u_int32_t dmacsr, restart;
1908 int i, u; 1933 int i, u;
1909 1934
1910 dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR); 1935 dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
1911 1936
1912#ifdef HIFN_DEBUG 1937#ifdef HIFN_DEBUG
1913 if (hifn_debug) 1938 if (hifn_debug)
1914 printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n", 1939 printf("%s: irq: stat %08x ien %08x u %d/%d/%d/%d\n",
1915 device_xname(sc->sc_dv), 1940 device_xname(sc->sc_dv),
1916 dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), 1941 dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER),
1917 dma->cmdu, dma->srcu, dma->dstu, dma->resu); 1942 dma->cmdu, dma->srcu, dma->dstu, dma->resu);
1918#endif 1943#endif
1919 1944
 1945 mutex_spin_enter(&sc->sc_mtx);
 1946
1920 /* Nothing in the DMA unit interrupted */ 1947 /* Nothing in the DMA unit interrupted */
1921 if ((dmacsr & sc->sc_dmaier) == 0) 1948 if ((dmacsr & sc->sc_dmaier) == 0) {
 1949 mutex_spin_exit(&sc->sc_mtx);
1922 return (0); 1950 return (0);
 1951 }
1923 1952
1924 WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier); 1953 WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
1925 1954
1926 if (dmacsr & HIFN_DMACSR_ENGINE) 1955 if (dmacsr & HIFN_DMACSR_ENGINE)
1927 WRITE_REG_0(sc, HIFN_0_PUISR, READ_REG_0(sc, HIFN_0_PUISR)); 1956 WRITE_REG_0(sc, HIFN_0_PUISR, READ_REG_0(sc, HIFN_0_PUISR));
1928 1957
1929 if ((sc->sc_flags & HIFN_HAS_PUBLIC) && 1958 if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
1930 (dmacsr & HIFN_DMACSR_PUBDONE)) 1959 (dmacsr & HIFN_DMACSR_PUBDONE))
1931 WRITE_REG_1(sc, HIFN_1_PUB_STATUS, 1960 WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
1932 READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE); 1961 READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
1933 1962
1934 restart = dmacsr & (HIFN_DMACSR_R_OVER | HIFN_DMACSR_D_OVER); 1963 restart = dmacsr & (HIFN_DMACSR_R_OVER | HIFN_DMACSR_D_OVER);
1935 if (restart) 1964 if (restart)
@@ -1938,27 +1967,27 @@ hifn_intr(void *arg) @@ -1938,27 +1967,27 @@ hifn_intr(void *arg)
1938 if (sc->sc_flags & HIFN_IS_7811) { 1967 if (sc->sc_flags & HIFN_IS_7811) {
1939 if (dmacsr & HIFN_DMACSR_ILLR) 1968 if (dmacsr & HIFN_DMACSR_ILLR)
1940 printf("%s: illegal read\n", device_xname(sc->sc_dv)); 1969 printf("%s: illegal read\n", device_xname(sc->sc_dv));
1941 if (dmacsr & HIFN_DMACSR_ILLW) 1970 if (dmacsr & HIFN_DMACSR_ILLW)
1942 printf("%s: illegal write\n", device_xname(sc->sc_dv)); 1971 printf("%s: illegal write\n", device_xname(sc->sc_dv));
1943 } 1972 }
1944 1973
1945 restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT | 1974 restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
1946 HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT); 1975 HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
1947 if (restart) { 1976 if (restart) {
1948 printf("%s: abort, resetting.\n", device_xname(sc->sc_dv)); 1977 printf("%s: abort, resetting.\n", device_xname(sc->sc_dv));
1949 hifnstats.hst_abort++; 1978 hifnstats.hst_abort++;
1950 hifn_abort(sc); 1979 hifn_abort(sc);
1951 return (1); 1980 goto out;
1952 } 1981 }
1953 1982
1954 if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->resu == 0)) { 1983 if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->resu == 0)) {
1955 /* 1984 /*
1956 * If no slots to process and we receive a "waiting on 1985 * If no slots to process and we receive a "waiting on
1957 * command" interrupt, we disable the "waiting on command" 1986 * command" interrupt, we disable the "waiting on command"
1958 * (by clearing it). 1987 * (by clearing it).
1959 */ 1988 */
1960 sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT; 1989 sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
1961 WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier); 1990 WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
1962 } 1991 }
1963 1992
1964 /* clear the rings */ 1993 /* clear the rings */
@@ -2016,149 +2045,169 @@ hifn_intr(void *arg) @@ -2016,149 +2045,169 @@ hifn_intr(void *arg)
2016 HIFN_CMDR_SYNC(sc, i, 2045 HIFN_CMDR_SYNC(sc, i,
2017 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2046 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2018 break; 2047 break;
2019 } 2048 }
2020 if (i != HIFN_D_CMD_RSIZE) { 2049 if (i != HIFN_D_CMD_RSIZE) {
2021 u--; 2050 u--;
2022 HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE); 2051 HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
2023 } 2052 }
2024 if (++i == (HIFN_D_CMD_RSIZE + 1)) 2053 if (++i == (HIFN_D_CMD_RSIZE + 1))
2025 i = 0; 2054 i = 0;
2026 } 2055 }
2027 dma->cmdk = i; dma->cmdu = u; 2056 dma->cmdk = i; dma->cmdu = u;
2028 2057
 2058out:
 2059 mutex_spin_exit(&sc->sc_mtx);
2029 return (1); 2060 return (1);
2030} 2061}
2031 2062
2032/* 2063/*
2033 * Allocate a new 'session' and return an encoded session id. 'sidp' 2064 * Allocate a new 'session' and return an encoded session id. 'sidp'
2034 * contains our registration id, and should contain an encoded session 2065 * contains our registration id, and should contain an encoded session
2035 * id on successful allocation. 2066 * id on successful allocation.
2036 */ 2067 */
2037static int 2068static int
2038hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri) 2069hifn_newsession(void *arg, u_int32_t *sidp, struct cryptoini *cri)
2039{ 2070{
2040 struct cryptoini *c; 2071 struct cryptoini *c;
2041 struct hifn_softc *sc = arg; 2072 struct hifn_softc *sc = arg;
2042 int i, mac = 0, cry = 0, comp = 0; 2073 int i, mac = 0, cry = 0, comp = 0, retval = EINVAL;
2043 2074
2044 KASSERT(sc != NULL /*, ("hifn_newsession: null softc")*/); 2075 KASSERT(sc != NULL /*, ("hifn_newsession: null softc")*/);
2045 if (sidp == NULL || cri == NULL || sc == NULL) 2076 if (sidp == NULL || cri == NULL || sc == NULL)
2046 return (EINVAL); 2077 return retval;
 2078
 2079 mutex_spin_enter(&sc->sc_mtx);
2047 2080
2048 for (i = 0; i < sc->sc_maxses; i++) 2081 for (i = 0; i < sc->sc_maxses; i++)
2049 if (sc->sc_sessions[i].hs_state == HS_STATE_FREE) 2082 if (sc->sc_sessions[i].hs_state == HS_STATE_FREE)
2050 break; 2083 break;
2051 if (i == sc->sc_maxses) 2084 if (i == sc->sc_maxses) {
2052 return (ENOMEM); 2085 retval = ENOMEM;
 2086 goto out;
 2087 }
2053 2088
2054 for (c = cri; c != NULL; c = c->cri_next) { 2089 for (c = cri; c != NULL; c = c->cri_next) {
2055 switch (c->cri_alg) { 2090 switch (c->cri_alg) {
2056 case CRYPTO_MD5: 2091 case CRYPTO_MD5:
2057 case CRYPTO_SHA1: 2092 case CRYPTO_SHA1:
2058 case CRYPTO_MD5_HMAC_96: 2093 case CRYPTO_MD5_HMAC_96:
2059 case CRYPTO_SHA1_HMAC_96: 2094 case CRYPTO_SHA1_HMAC_96:
2060 if (mac) 2095 if (mac) {
2061 return (EINVAL); 2096 goto out;
 2097 }
2062 mac = 1; 2098 mac = 1;
2063 break; 2099 break;
2064 case CRYPTO_DES_CBC: 2100 case CRYPTO_DES_CBC:
2065 case CRYPTO_3DES_CBC: 2101 case CRYPTO_3DES_CBC:
2066 case CRYPTO_AES_CBC: 2102 case CRYPTO_AES_CBC:
2067 /* Note that this is an initialization 2103 /* Note that this is an initialization
2068 vector, not a cipher key; any function 2104 vector, not a cipher key; any function
2069 giving sufficient Hamming distance 2105 giving sufficient Hamming distance
2070 between outputs is fine. Use of RC4 2106 between outputs is fine. Use of RC4
2071 to generate IVs has been FIPS140-2 2107 to generate IVs has been FIPS140-2
2072 certified by several labs. */ 2108 certified by several labs. */
2073#ifdef __NetBSD__ 2109#ifdef __NetBSD__
2074 cprng_fast(sc->sc_sessions[i].hs_iv, 2110 cprng_fast(sc->sc_sessions[i].hs_iv,
2075 c->cri_alg == CRYPTO_AES_CBC ? 2111 c->cri_alg == CRYPTO_AES_CBC ?
2076 HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); 2112 HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
2077#else /* FreeBSD and OpenBSD have get_random_bytes */ 2113#else /* FreeBSD and OpenBSD have get_random_bytes */
2078 /* XXX this may read fewer, does it matter? */ 2114 /* XXX this may read fewer, does it matter? */
2079 get_random_bytes(sc->sc_sessions[i].hs_iv, 2115 get_random_bytes(sc->sc_sessions[i].hs_iv,
2080 c->cri_alg == CRYPTO_AES_CBC ? 2116 c->cri_alg == CRYPTO_AES_CBC ?
2081 HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH); 2117 HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
2082#endif 2118#endif
2083 /*FALLTHROUGH*/ 2119 /*FALLTHROUGH*/
2084 case CRYPTO_ARC4: 2120 case CRYPTO_ARC4:
2085 if (cry) 2121 if (cry) {
2086 return (EINVAL); 2122 goto out;
 2123 }
2087 cry = 1; 2124 cry = 1;
2088 break; 2125 break;
2089#ifdef HAVE_CRYPTO_LZS 2126#ifdef HAVE_CRYPTO_LZS
2090 case CRYPTO_LZS_COMP: 2127 case CRYPTO_LZS_COMP:
2091 if (comp) 2128 if (comp) {
2092 return (EINVAL); 2129 goto out;
 2130 }
2093 comp = 1; 2131 comp = 1;
2094 break; 2132 break;
2095#endif 2133#endif
2096 default: 2134 default:
2097 return (EINVAL); 2135 goto out;
2098 } 2136 }
2099 } 2137 }
2100 if (mac == 0 && cry == 0 && comp == 0) 2138 if (mac == 0 && cry == 0 && comp == 0) {
2101 return (EINVAL); 2139 goto out;
 2140 }
2102 2141
2103 /* 2142 /*
2104 * XXX only want to support compression without chaining to 2143 * XXX only want to support compression without chaining to
2105 * MAC/crypt engine right now 2144 * MAC/crypt engine right now
2106 */ 2145 */
2107 if ((comp && mac) || (comp && cry)) 2146 if ((comp && mac) || (comp && cry)) {
2108 return (EINVAL); 2147 goto out;
 2148 }
2109 2149
2110 *sidp = HIFN_SID(device_unit(sc->sc_dv), i); 2150 *sidp = HIFN_SID(device_unit(sc->sc_dv), i);
2111 sc->sc_sessions[i].hs_state = HS_STATE_USED; 2151 sc->sc_sessions[i].hs_state = HS_STATE_USED;
2112 2152
2113 return (0); 2153 retval = 0;
 2154out:
 2155 mutex_spin_exit(&sc->sc_mtx);
 2156 return retval;
2114} 2157}
2115 2158
2116/* 2159/*
2117 * Deallocate a session. 2160 * Deallocate a session.
2118 * XXX this routine should run a zero'd mac/encrypt key into context ram. 2161 * XXX this routine should run a zero'd mac/encrypt key into context ram.
2119 * XXX to blow away any keys already stored there. 2162 * XXX to blow away any keys already stored there.
2120 */ 2163 */
2121static int 2164static int
2122hifn_freesession(void *arg, u_int64_t tid) 2165hifn_freesession(void *arg, u_int64_t tid)
2123{ 2166{
2124 struct hifn_softc *sc = arg; 2167 struct hifn_softc *sc = arg;
2125 int session; 2168 int session;
2126 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff; 2169 u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
2127 2170
2128 KASSERT(sc != NULL /*, ("hifn_freesession: null softc")*/); 2171 KASSERT(sc != NULL /*, ("hifn_freesession: null softc")*/);
2129 if (sc == NULL) 2172 if (sc == NULL)
2130 return (EINVAL); 2173 return (EINVAL);
2131 2174
 2175 mutex_spin_enter(&sc->sc_mtx);
2132 session = HIFN_SESSION(sid); 2176 session = HIFN_SESSION(sid);
2133 if (session >= sc->sc_maxses) 2177 if (session >= sc->sc_maxses) {
 2178 mutex_spin_exit(&sc->sc_mtx);
2134 return (EINVAL); 2179 return (EINVAL);
 2180 }
2135 2181
2136 memset(&sc->sc_sessions[session], 0, sizeof(sc->sc_sessions[session])); 2182 memset(&sc->sc_sessions[session], 0, sizeof(sc->sc_sessions[session]));
 2183 mutex_spin_exit(&sc->sc_mtx);
2137 return (0); 2184 return (0);
2138} 2185}
2139 2186
2140static int 2187static int
2141hifn_process(void *arg, struct cryptop *crp, int hint) 2188hifn_process(void *arg, struct cryptop *crp, int hint)
2142{ 2189{
2143 struct hifn_softc *sc = arg; 2190 struct hifn_softc *sc = arg;
2144 struct hifn_command *cmd = NULL; 2191 struct hifn_command *cmd = NULL;
2145 int session, err, ivlen; 2192 int session, err, ivlen;
2146 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; 2193 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
2147 2194
2148 if (crp == NULL || crp->crp_callback == NULL) { 2195 if (crp == NULL || crp->crp_callback == NULL) {
2149 hifnstats.hst_invalid++; 2196 hifnstats.hst_invalid++;
2150 return (EINVAL); 2197 return (EINVAL);
2151 } 2198 }
 2199
 2200 mutex_spin_enter(&sc->sc_mtx);
2152 session = HIFN_SESSION(crp->crp_sid); 2201 session = HIFN_SESSION(crp->crp_sid);
2153 2202
2154 if (sc == NULL || session >= sc->sc_maxses) { 2203 if (sc == NULL || session >= sc->sc_maxses) {
2155 err = EINVAL; 2204 err = EINVAL;
2156 goto errout; 2205 goto errout;
2157 } 2206 }
2158 2207
2159 cmd = (struct hifn_command *)malloc(sizeof(struct hifn_command), 2208 cmd = (struct hifn_command *)malloc(sizeof(struct hifn_command),
2160 M_DEVBUF, M_NOWAIT|M_ZERO); 2209 M_DEVBUF, M_NOWAIT|M_ZERO);
2161 if (cmd == NULL) { 2210 if (cmd == NULL) {
2162 hifnstats.hst_nomem++; 2211 hifnstats.hst_nomem++;
2163 err = ENOMEM; 2212 err = ENOMEM;
2164 goto errout; 2213 goto errout;
@@ -2367,50 +2416,53 @@ hifn_process(void *arg, struct cryptop * @@ -2367,50 +2416,53 @@ hifn_process(void *arg, struct cryptop *
2367 } 2416 }
2368 2417
2369 cmd->crp = crp; 2418 cmd->crp = crp;
2370 cmd->session_num = session; 2419 cmd->session_num = session;
2371 cmd->softc = sc; 2420 cmd->softc = sc;
2372 2421
2373 err = hifn_crypto(sc, cmd, crp, hint); 2422 err = hifn_crypto(sc, cmd, crp, hint);
2374 if (err == 0) { 2423 if (err == 0) {
2375 if (enccrd) 2424 if (enccrd)
2376 sc->sc_sessions[session].hs_prev_op = 2425 sc->sc_sessions[session].hs_prev_op =
2377 enccrd->crd_flags & CRD_F_ENCRYPT; 2426 enccrd->crd_flags & CRD_F_ENCRYPT;
2378 if (sc->sc_sessions[session].hs_state == HS_STATE_USED) 2427 if (sc->sc_sessions[session].hs_state == HS_STATE_USED)
2379 sc->sc_sessions[session].hs_state = HS_STATE_KEY; 2428 sc->sc_sessions[session].hs_state = HS_STATE_KEY;
 2429 mutex_spin_exit(&sc->sc_mtx);
2380 return 0; 2430 return 0;
2381 } else if (err == ERESTART) { 2431 } else if (err == ERESTART) {
2382 /* 2432 /*
2383 * There weren't enough resources to dispatch the request 2433 * There weren't enough resources to dispatch the request
2384 * to the part. Notify the caller so they'll requeue this 2434 * to the part. Notify the caller so they'll requeue this
2385 * request and resubmit it again soon. 2435 * request and resubmit it again soon.
2386 */ 2436 */
2387#ifdef HIFN_DEBUG 2437#ifdef HIFN_DEBUG
2388 if (hifn_debug) 2438 if (hifn_debug)
2389 printf("%s: requeue request\n", device_xname(sc->sc_dv)); 2439 printf("%s: requeue request\n", device_xname(sc->sc_dv));
2390#endif 2440#endif
2391 free(cmd, M_DEVBUF); 2441 free(cmd, M_DEVBUF);
2392 sc->sc_needwakeup |= CRYPTO_SYMQ; 2442 sc->sc_needwakeup |= CRYPTO_SYMQ;
 2443 mutex_spin_exit(&sc->sc_mtx);
2393 return (err); 2444 return (err);
2394 } 2445 }
2395 2446
2396errout: 2447errout:
2397 if (cmd != NULL) 2448 if (cmd != NULL)
2398 free(cmd, M_DEVBUF); 2449 free(cmd, M_DEVBUF);
2399 if (err == EINVAL) 2450 if (err == EINVAL)
2400 hifnstats.hst_invalid++; 2451 hifnstats.hst_invalid++;
2401 else 2452 else
2402 hifnstats.hst_nomem++; 2453 hifnstats.hst_nomem++;
2403 crp->crp_etype = err; 2454 crp->crp_etype = err;
 2455 mutex_spin_exit(&sc->sc_mtx);
2404 crypto_done(crp); 2456 crypto_done(crp);
2405 return (0); 2457 return (0);
2406} 2458}
2407 2459
2408static void 2460static void
2409hifn_abort(struct hifn_softc *sc) 2461hifn_abort(struct hifn_softc *sc)
2410{ 2462{
2411 struct hifn_dma *dma = sc->sc_dma; 2463 struct hifn_dma *dma = sc->sc_dma;
2412 struct hifn_command *cmd; 2464 struct hifn_command *cmd;
2413 struct cryptop *crp; 2465 struct cryptop *crp;
2414 int i, u; 2466 int i, u;
2415 2467
2416 i = dma->resk; u = dma->resu; 2468 i = dma->resk; u = dma->resu;
@@ -2706,58 +2758,53 @@ hifn_compression(struct hifn_softc *sc,  @@ -2706,58 +2758,53 @@ hifn_compression(struct hifn_softc *sc,
2706 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, 2758 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
2707 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2759 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD);
2708 } 2760 }
2709 2761
2710 cmd->crp = crp; 2762 cmd->crp = crp;
2711 /* 2763 /*
2712 * Always use session 0. The modes of compression we use are 2764 * Always use session 0. The modes of compression we use are
2713 * stateless and there is always at least one compression 2765 * stateless and there is always at least one compression
2714 * context, zero. 2766 * context, zero.
2715 */ 2767 */
2716 cmd->session_num = 0; 2768 cmd->session_num = 0;
2717 cmd->softc = sc; 2769 cmd->softc = sc;
2718 2770
2719 s = splnet(); 
2720 err = hifn_compress_enter(sc, cmd); 2771 err = hifn_compress_enter(sc, cmd);
2721 splx(s); 
2722 2772
2723 if (err != 0) 2773 if (err != 0)
2724 goto fail; 2774 goto fail;
2725 return (0); 2775 return (0);
2726 2776
2727fail: 2777fail:
2728 if (cmd->dst_map != NULL) { 2778 if (cmd->dst_map != NULL) {
2729 if (cmd->dst_map->dm_nsegs > 0) 2779 if (cmd->dst_map->dm_nsegs > 0)
2730 bus_dmamap_unload(sc->sc_dmat, cmd->dst_map); 2780 bus_dmamap_unload(sc->sc_dmat, cmd->dst_map);
2731 bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map); 2781 bus_dmamap_destroy(sc->sc_dmat, cmd->dst_map);
2732 } 2782 }
2733 if (cmd->src_map != NULL) { 2783 if (cmd->src_map != NULL) {
2734 if (cmd->src_map->dm_nsegs > 0) 2784 if (cmd->src_map->dm_nsegs > 0)
2735 bus_dmamap_unload(sc->sc_dmat, cmd->src_map); 2785 bus_dmamap_unload(sc->sc_dmat, cmd->src_map);
2736 bus_dmamap_destroy(sc->sc_dmat, cmd->src_map); 2786 bus_dmamap_destroy(sc->sc_dmat, cmd->src_map);
2737 } 2787 }
2738 free(cmd, M_DEVBUF); 2788 free(cmd, M_DEVBUF);
2739 if (err == EINVAL) 2789 if (err == EINVAL)
2740 hifnstats.hst_invalid++; 2790 hifnstats.hst_invalid++;
2741 else 2791 else
2742 hifnstats.hst_nomem++; 2792 hifnstats.hst_nomem++;
2743 crp->crp_etype = err; 2793 crp->crp_etype = err;
2744 crypto_done(crp); 2794 crypto_done(crp);
2745 return (0); 2795 return (0);
2746} 2796}
2747 2797
2748/* 
2749 * must be called at splnet() 
2750 */ 
2751static int 2798static int
2752hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd) 2799hifn_compress_enter(struct hifn_softc *sc, struct hifn_command *cmd)
2753{ 2800{
2754 struct hifn_dma *dma = sc->sc_dma; 2801 struct hifn_dma *dma = sc->sc_dma;
2755 int cmdi, resi; 2802 int cmdi, resi;
2756 u_int32_t cmdlen; 2803 u_int32_t cmdlen;
2757 2804
2758 if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE || 2805 if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
2759 (dma->resu + 1) > HIFN_D_CMD_RSIZE) 2806 (dma->resu + 1) > HIFN_D_CMD_RSIZE)
2760 return (ENOMEM); 2807 return (ENOMEM);
2761 2808
2762 if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE || 2809 if ((dma->srcu + cmd->src_map->dm_nsegs) > HIFN_D_SRC_RSIZE ||
2763 (dma->dstu + cmd->dst_map->dm_nsegs) > HIFN_D_DST_RSIZE) 2810 (dma->dstu + cmd->dst_map->dm_nsegs) > HIFN_D_DST_RSIZE)
@@ -2911,27 +2958,26 @@ hifn_callback_comp(struct hifn_softc *sc @@ -2911,27 +2958,26 @@ hifn_callback_comp(struct hifn_softc *sc
2911 goto out; 2958 goto out;
2912 } 2959 }
2913 if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map, 2960 if (bus_dmamap_load_mbuf(sc->sc_dmat, cmd->dst_map,
2914 cmd->dstu.dst_m, BUS_DMA_NOWAIT)) { 2961 cmd->dstu.dst_m, BUS_DMA_NOWAIT)) {
2915 err = ENOMEM; 2962 err = ENOMEM;
2916 goto out; 2963 goto out;
2917 } 2964 }
2918 2965
2919 bus_dmamap_sync(sc->sc_dmat, cmd->src_map, 2966 bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
2920 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2967 0, cmd->src_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2921 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map, 2968 bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
2922 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2969 0, cmd->dst_map->dm_mapsize, BUS_DMASYNC_PREREAD);
2923 2970
2924 /* already at splnet... */ 
2925 err = hifn_compress_enter(sc, cmd); 2971 err = hifn_compress_enter(sc, cmd);
2926 if (err != 0) 2972 if (err != 0)
2927 goto out; 2973 goto out;
2928 return; 2974 return;
2929 } 2975 }
2930 2976
2931 olen = dstsize - (letoh16(baseres.dst_cnt) | 2977 olen = dstsize - (letoh16(baseres.dst_cnt) |
2932 (((letoh16(baseres.session) & HIFN_BASE_RES_DSTLEN_M) >> 2978 (((letoh16(baseres.session) & HIFN_BASE_RES_DSTLEN_M) >>
2933 HIFN_BASE_RES_DSTLEN_S) << 16)); 2979 HIFN_BASE_RES_DSTLEN_S) << 16));
2934 2980
2935 crp->crp_olen = olen - cmd->compcrd->crd_skip; 2981 crp->crp_olen = olen - cmd->compcrd->crd_skip;
2936 2982
2937 bus_dmamap_unload(sc->sc_dmat, cmd->src_map); 2983 bus_dmamap_unload(sc->sc_dmat, cmd->src_map);

cvs diff -r1.28 -r1.29 src/sys/dev/pci/ubsec.c (expand / switch to unified diff)

--- src/sys/dev/pci/ubsec.c 2012/10/27 17:18:35 1.28
+++ src/sys/dev/pci/ubsec.c 2013/06/13 00:55:01 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ubsec.c,v 1.28 2012/10/27 17:18:35 chs Exp $ */ 1/* $NetBSD: ubsec.c,v 1.29 2013/06/13 00:55:01 tls Exp $ */
2/* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */ 2/* $FreeBSD: src/sys/dev/ubsec/ubsec.c,v 1.6.2.6 2003/01/23 21:06:43 sam Exp $ */
3/* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */ 3/* $OpenBSD: ubsec.c,v 1.127 2003/06/04 14:04:58 jason Exp $ */
4 4
5/* 5/*
6 * Copyright (c) 2000 Jason L. Wright (jason@thought.net) 6 * Copyright (c) 2000 Jason L. Wright (jason@thought.net)
7 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org) 7 * Copyright (c) 2000 Theo de Raadt (deraadt@openbsd.org)
8 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) 8 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com)
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -25,42 +25,42 @@ @@ -25,42 +25,42 @@
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 * 30 *
31 * Effort sponsored in part by the Defense Advanced Research Projects 31 * Effort sponsored in part by the Defense Advanced Research Projects
32 * Agency (DARPA) and Air Force Research Laboratory, Air Force 32 * Agency (DARPA) and Air Force Research Laboratory, Air Force
33 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 33 * Materiel Command, USAF, under agreement number F30602-01-2-0537.
34 * 34 *
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.28 2012/10/27 17:18:35 chs Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: ubsec.c,v 1.29 2013/06/13 00:55:01 tls Exp $");
39 39
40#undef UBSEC_DEBUG 40#undef UBSEC_DEBUG
41 41
42/* 42/*
43 * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator 43 * uBsec 5[56]01, bcm580xx, bcm582x hardware crypto accelerator
44 */ 44 */
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/endian.h> 49#include <sys/endian.h>
50#ifdef __NetBSD__ 50#ifdef __NetBSD__
 51 #define UBSEC_NO_RNG /* hangs on attach */
51 #define letoh16 htole16 52 #define letoh16 htole16
52 #define letoh32 htole32 53 #define letoh32 htole32
53#define UBSEC_NO_RNG /* until statistically tested */ 
54#endif 54#endif
55#include <sys/errno.h> 55#include <sys/errno.h>
56#include <sys/malloc.h> 56#include <sys/malloc.h>
57#include <sys/kernel.h> 57#include <sys/kernel.h>
58#include <sys/mbuf.h> 58#include <sys/mbuf.h>
59#include <sys/device.h> 59#include <sys/device.h>
60#include <sys/queue.h> 60#include <sys/queue.h>
61 61
62#include <opencrypto/cryptodev.h> 62#include <opencrypto/cryptodev.h>
63#include <opencrypto/xform.h> 63#include <opencrypto/xform.h>
64#ifdef __OpenBSD__ 64#ifdef __OpenBSD__
65 #include <dev/rndvar.h> 65 #include <dev/rndvar.h>
66 #include <sys/md5k.h> 66 #include <sys/md5k.h>
@@ -109,27 +109,29 @@ extern int ubsec_debug; @@ -109,27 +109,29 @@ extern int ubsec_debug;
109int ubsec_debug=1; 109int ubsec_debug=1;
110#endif 110#endif
111 111
112static int ubsec_intr(void *); 112static int ubsec_intr(void *);
113static int ubsec_newsession(void*, u_int32_t *, struct cryptoini *); 113static int ubsec_newsession(void*, u_int32_t *, struct cryptoini *);
114static int ubsec_freesession(void*, u_int64_t); 114static int ubsec_freesession(void*, u_int64_t);
115static int ubsec_process(void*, struct cryptop *, int hint); 115static int ubsec_process(void*, struct cryptop *, int hint);
116static void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); 116static void ubsec_callback(struct ubsec_softc *, struct ubsec_q *);
117static void ubsec_feed(struct ubsec_softc *); 117static void ubsec_feed(struct ubsec_softc *);
118static void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int); 118static void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int);
119static void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *); 119static void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *);
120static void ubsec_feed2(struct ubsec_softc *); 120static void ubsec_feed2(struct ubsec_softc *);
121#ifndef UBSEC_NO_RNG 121#ifndef UBSEC_NO_RNG
122static void ubsec_rng(void *); 122static void ubsec_rng(void *);
 123static void ubsec_rng_locked(void *);
 124static void ubsec_rng_get(size_t, void *);
123#endif /* UBSEC_NO_RNG */ 125#endif /* UBSEC_NO_RNG */
124static int ubsec_dma_malloc(struct ubsec_softc *, bus_size_t, 126static int ubsec_dma_malloc(struct ubsec_softc *, bus_size_t,
125 struct ubsec_dma_alloc *, int); 127 struct ubsec_dma_alloc *, int);
126static void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *); 128static void ubsec_dma_free(struct ubsec_softc *, struct ubsec_dma_alloc *);
127static int ubsec_dmamap_aligned(bus_dmamap_t); 129static int ubsec_dmamap_aligned(bus_dmamap_t);
128 130
129static int ubsec_kprocess(void*, struct cryptkop *, int); 131static int ubsec_kprocess(void*, struct cryptkop *, int);
130static int ubsec_kprocess_modexp_sw(struct ubsec_softc *, 132static int ubsec_kprocess_modexp_sw(struct ubsec_softc *,
131 struct cryptkop *, int); 133 struct cryptkop *, int);
132static int ubsec_kprocess_modexp_hw(struct ubsec_softc *, 134static int ubsec_kprocess_modexp_hw(struct ubsec_softc *,
133 struct cryptkop *, int); 135 struct cryptkop *, int);
134static int ubsec_kprocess_rsapriv(struct ubsec_softc *, 136static int ubsec_kprocess_rsapriv(struct ubsec_softc *,
135 struct cryptkop *, int); 137 struct cryptkop *, int);
@@ -349,26 +351,29 @@ ubsec_attach(device_t parent, device_t s @@ -349,26 +351,29 @@ ubsec_attach(device_t parent, device_t s
349 aprint_error(" at %s", intrstr); 351 aprint_error(" at %s", intrstr);
350 aprint_error("\n"); 352 aprint_error("\n");
351 return; 353 return;
352 } 354 }
353 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 355 aprint_normal_dev(self, "interrupting at %s\n", intrstr);
354 356
355 sc->sc_cid = crypto_get_driverid(0); 357 sc->sc_cid = crypto_get_driverid(0);
356 if (sc->sc_cid < 0) { 358 if (sc->sc_cid < 0) {
357 aprint_error_dev(self, "couldn't get crypto driver id\n"); 359 aprint_error_dev(self, "couldn't get crypto driver id\n");
358 pci_intr_disestablish(pc, sc->sc_ih); 360 pci_intr_disestablish(pc, sc->sc_ih);
359 return; 361 return;
360 } 362 }
361 363
 364 sc->sc_rng_need = RND_POOLBITS / NBBY;
 365 mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_VM);
 366
362 SIMPLEQ_INIT(&sc->sc_freequeue); 367 SIMPLEQ_INIT(&sc->sc_freequeue);
363 dmap = sc->sc_dmaa; 368 dmap = sc->sc_dmaa;
364 for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) { 369 for (i = 0; i < UBS_MAX_NQUEUE; i++, dmap++) {
365 struct ubsec_q *q; 370 struct ubsec_q *q;
366 371
367 q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q), 372 q = (struct ubsec_q *)malloc(sizeof(struct ubsec_q),
368 M_DEVBUF, M_NOWAIT); 373 M_DEVBUF, M_NOWAIT);
369 if (q == NULL) { 374 if (q == NULL) {
370 aprint_error_dev(self, "can't allocate queue buffers\n"); 375 aprint_error_dev(self, "can't allocate queue buffers\n");
371 break; 376 break;
372 } 377 }
373 378
374 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk), 379 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_dmachunk),
@@ -420,26 +425,30 @@ ubsec_attach(device_t parent, device_t s @@ -420,26 +425,30 @@ ubsec_attach(device_t parent, device_t s
420 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass), 425 if (ubsec_dma_malloc(sc, sizeof(struct ubsec_ctx_rngbypass),
421 &sc->sc_rng.rng_q.q_ctx, 0)) { 426 &sc->sc_rng.rng_q.q_ctx, 0)) {
422 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); 427 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr);
423 goto skip_rng; 428 goto skip_rng;
424 } 429 }
425 430
426 if (ubsec_dma_malloc(sc, sizeof(u_int32_t) * 431 if (ubsec_dma_malloc(sc, sizeof(u_int32_t) *
427 UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) { 432 UBSEC_RNG_BUFSIZ, &sc->sc_rng.rng_buf, 0)) {
428 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx); 433 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_ctx);
429 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr); 434 ubsec_dma_free(sc, &sc->sc_rng.rng_q.q_mcr);
430 goto skip_rng; 435 goto skip_rng;
431 } 436 }
432 437
 438 rndsource_setcb(&sc->sc_rnd_source, ubsec_rng_get, sc);
 439 rnd_attach_source(&sc->sc_rnd_source, device_xname(sc->sc_dev),
 440 RND_TYPE_RNG,
 441 RND_FLAG_NO_ESTIMATE|RND_FLAG_HASCB);
433 if (hz >= 100) 442 if (hz >= 100)
434 sc->sc_rnghz = hz / 100; 443 sc->sc_rnghz = hz / 100;
435 else 444 else
436 sc->sc_rnghz = 1; 445 sc->sc_rnghz = 1;
437#ifdef __OpenBSD__ 446#ifdef __OpenBSD__
438 timeout_set(&sc->sc_rngto, ubsec_rng, sc); 447 timeout_set(&sc->sc_rngto, ubsec_rng, sc);
439 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 448 timeout_add(&sc->sc_rngto, sc->sc_rnghz);
440#else 449#else
441 callout_init(&sc->sc_rngto, 0); 450 callout_init(&sc->sc_rngto, 0);
442 callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc); 451 callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc);
443#endif 452#endif
444 skip_rng: 453 skip_rng:
445 if (sc->sc_rnghz) 454 if (sc->sc_rnghz)
@@ -464,29 +473,31 @@ ubsec_attach(device_t parent, device_t s @@ -464,29 +473,31 @@ ubsec_attach(device_t parent, device_t s
464 473
465/* 474/*
466 * UBSEC Interrupt routine 475 * UBSEC Interrupt routine
467 */ 476 */
468static int 477static int
469ubsec_intr(void *arg) 478ubsec_intr(void *arg)
470{ 479{
471 struct ubsec_softc *sc = arg; 480 struct ubsec_softc *sc = arg;
472 volatile u_int32_t stat; 481 volatile u_int32_t stat;
473 struct ubsec_q *q; 482 struct ubsec_q *q;
474 struct ubsec_dma *dmap; 483 struct ubsec_dma *dmap;
475 int npkts = 0, i; 484 int npkts = 0, i;
476 485
 486 mutex_spin_enter(&sc->sc_mtx);
477 stat = READ_REG(sc, BS_STAT); 487 stat = READ_REG(sc, BS_STAT);
478 stat &= sc->sc_statmask; 488 stat &= sc->sc_statmask;
479 if (stat == 0) { 489 if (stat == 0) {
 490 mutex_spin_exit(&sc->sc_mtx);
480 return (0); 491 return (0);
481 } 492 }
482 493
483 WRITE_REG(sc, BS_STAT, stat); /* IACK */ 494 WRITE_REG(sc, BS_STAT, stat); /* IACK */
484 495
485 /* 496 /*
486 * Check to see if we have any packets waiting for us 497 * Check to see if we have any packets waiting for us
487 */ 498 */
488 if ((stat & BS_STAT_MCR1_DONE)) { 499 if ((stat & BS_STAT_MCR1_DONE)) {
489 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) { 500 while (!SIMPLEQ_EMPTY(&sc->sc_qchip)) {
490 q = SIMPLEQ_FIRST(&sc->sc_qchip); 501 q = SIMPLEQ_FIRST(&sc->sc_qchip);
491 dmap = q->q_dma; 502 dmap = q->q_dma;
492 503
@@ -573,26 +584,27 @@ ubsec_intr(void *arg) @@ -573,26 +584,27 @@ ubsec_intr(void *arg)
573 ubsec_feed(sc); 584 ubsec_feed(sc);
574 } 585 }
575 586
576 if (sc->sc_needwakeup) { /* XXX check high watermark */ 587 if (sc->sc_needwakeup) { /* XXX check high watermark */
577 int wkeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ); 588 int wkeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
578#ifdef UBSEC_DEBUG 589#ifdef UBSEC_DEBUG
579 if (ubsec_debug) 590 if (ubsec_debug)
580 printf("%s: wakeup crypto (%x)\n", device_xname(sc->sc_dev), 591 printf("%s: wakeup crypto (%x)\n", device_xname(sc->sc_dev),
581 sc->sc_needwakeup); 592 sc->sc_needwakeup);
582#endif /* UBSEC_DEBUG */ 593#endif /* UBSEC_DEBUG */
583 sc->sc_needwakeup &= ~wkeup; 594 sc->sc_needwakeup &= ~wkeup;
584 crypto_unblock(sc->sc_cid, wkeup); 595 crypto_unblock(sc->sc_cid, wkeup);
585 } 596 }
 597 mutex_spin_exit(&sc->sc_mtx);
586 return (1); 598 return (1);
587} 599}
588 600
589/* 601/*
590 * ubsec_feed() - aggregate and post requests to chip 602 * ubsec_feed() - aggregate and post requests to chip
591 * OpenBSD comments: 603 * OpenBSD comments:
592 * It is assumed that the caller set splnet() 604 * It is assumed that the caller set splnet()
593 */ 605 */
594static void 606static void
595ubsec_feed(struct ubsec_softc *sc) 607ubsec_feed(struct ubsec_softc *sc)
596{ 608{
597 struct ubsec_q *q, *q2; 609 struct ubsec_q *q, *q2;
598 int npkts, i; 610 int npkts, i;
@@ -916,60 +928,60 @@ ubsec_op_cb(void *arg, bus_dma_segment_t @@ -916,60 +928,60 @@ ubsec_op_cb(void *arg, bus_dma_segment_t
916 op->mapsize = mapsize; 928 op->mapsize = mapsize;
917 op->nsegs = nsegs; 929 op->nsegs = nsegs;
918 memcpy(op->segs, seg, nsegs * sizeof (seg[0])); 930 memcpy(op->segs, seg, nsegs * sizeof (seg[0]));
919} 931}
920#endif 932#endif
921 933
922static int 934static int
923ubsec_process(void *arg, struct cryptop *crp, int hint) 935ubsec_process(void *arg, struct cryptop *crp, int hint)
924{ 936{
925 struct ubsec_q *q = NULL; 937 struct ubsec_q *q = NULL;
926#ifdef __OpenBSD__ 938#ifdef __OpenBSD__
927 int card; 939 int card;
928#endif 940#endif
929 int err = 0, i, j, s, nicealign; 941 int err = 0, i, j, nicealign;
930 struct ubsec_softc *sc; 942 struct ubsec_softc *sc;
931 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd; 943 struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
932 int encoffset = 0, macoffset = 0, cpskip, cpoffset; 944 int encoffset = 0, macoffset = 0, cpskip, cpoffset;
933 int sskip, dskip, stheend, dtheend; 945 int sskip, dskip, stheend, dtheend;
934 int16_t coffset; 946 int16_t coffset;
935 struct ubsec_session *ses; 947 struct ubsec_session *ses;
936 struct ubsec_pktctx ctx; 948 struct ubsec_pktctx ctx;
937 struct ubsec_dma *dmap = NULL; 949 struct ubsec_dma *dmap = NULL;
938 950
939 sc = arg; 951 sc = arg;
940 KASSERT(sc != NULL /*, ("ubsec_process: null softc")*/); 952 KASSERT(sc != NULL /*, ("ubsec_process: null softc")*/);
941 953
942 if (crp == NULL || crp->crp_callback == NULL || sc == NULL) { 954 if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
943 ubsecstats.hst_invalid++; 955 ubsecstats.hst_invalid++;
944 return (EINVAL); 956 return (EINVAL);
945 } 957 }
946 if (UBSEC_SESSION(crp->crp_sid) >= sc->sc_nsessions) { 958 if (UBSEC_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
947 ubsecstats.hst_badsession++; 959 ubsecstats.hst_badsession++;
948 return (EINVAL); 960 return (EINVAL);
949 } 961 }
950 962
951 s = splnet(); 963 mutex_spin_enter(&sc->sc_mtx);
952 964
953 if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) { 965 if (SIMPLEQ_EMPTY(&sc->sc_freequeue)) {
954 ubsecstats.hst_queuefull++; 966 ubsecstats.hst_queuefull++;
955 sc->sc_needwakeup |= CRYPTO_SYMQ; 967 sc->sc_needwakeup |= CRYPTO_SYMQ;
956 splx(s); 968 mutex_spin_exit(&sc->sc_mtx);
957 return(ERESTART); 969 return(ERESTART);
958 } 970 }
959 971
960 q = SIMPLEQ_FIRST(&sc->sc_freequeue); 972 q = SIMPLEQ_FIRST(&sc->sc_freequeue);
961 SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, /*q,*/ q_next); 973 SIMPLEQ_REMOVE_HEAD(&sc->sc_freequeue, /*q,*/ q_next);
962 splx(s); 974 mutex_spin_exit(&sc->sc_mtx);
963 975
964 dmap = q->q_dma; /* Save dma pointer */ 976 dmap = q->q_dma; /* Save dma pointer */
965 memset(q, 0, sizeof(struct ubsec_q)); 977 memset(q, 0, sizeof(struct ubsec_q));
966 memset(&ctx, 0, sizeof(ctx)); 978 memset(&ctx, 0, sizeof(ctx));
967 979
968 q->q_sesn = UBSEC_SESSION(crp->crp_sid); 980 q->q_sesn = UBSEC_SESSION(crp->crp_sid);
969 q->q_dma = dmap; 981 q->q_dma = dmap;
970 ses = &sc->sc_sessions[q->q_sesn]; 982 ses = &sc->sc_sessions[q->q_sesn];
971 983
972 if (crp->crp_flags & CRYPTO_F_IMBUF) { 984 if (crp->crp_flags & CRYPTO_F_IMBUF) {
973 q->q_src_m = (struct mbuf *)crp->crp_buf; 985 q->q_src_m = (struct mbuf *)crp->crp_buf;
974 q->q_dst_m = (struct mbuf *)crp->crp_buf; 986 q->q_dst_m = (struct mbuf *)crp->crp_buf;
975 } else if (crp->crp_flags & CRYPTO_F_IOV) { 987 } else if (crp->crp_flags & CRYPTO_F_IOV) {
@@ -1426,53 +1438,53 @@ ubsec_process(void *arg, struct cryptop  @@ -1426,53 +1438,53 @@ ubsec_process(void *arg, struct cryptop
1426 for (i = 0; i < 6; i++) 1438 for (i = 0; i < 6; i++)
1427 ctxl->pc_deskey[i] = ctx.pc_deskey[i]; 1439 ctxl->pc_deskey[i] = ctx.pc_deskey[i];
1428 for (i = 0; i < 5; i++) 1440 for (i = 0; i < 5; i++)
1429 ctxl->pc_hminner[i] = ctx.pc_hminner[i]; 1441 ctxl->pc_hminner[i] = ctx.pc_hminner[i];
1430 for (i = 0; i < 5; i++) 1442 for (i = 0; i < 5; i++)
1431 ctxl->pc_hmouter[i] = ctx.pc_hmouter[i]; 1443 ctxl->pc_hmouter[i] = ctx.pc_hmouter[i];
1432 ctxl->pc_iv[0] = ctx.pc_iv[0]; 1444 ctxl->pc_iv[0] = ctx.pc_iv[0];
1433 ctxl->pc_iv[1] = ctx.pc_iv[1]; 1445 ctxl->pc_iv[1] = ctx.pc_iv[1];
1434 } else 1446 } else
1435 memcpy((char *)dmap->d_alloc.dma_vaddr + 1447 memcpy((char *)dmap->d_alloc.dma_vaddr +
1436 offsetof(struct ubsec_dmachunk, d_ctx), &ctx, 1448 offsetof(struct ubsec_dmachunk, d_ctx), &ctx,
1437 sizeof(struct ubsec_pktctx)); 1449 sizeof(struct ubsec_pktctx));
1438 1450
1439 s = splnet(); 1451 mutex_spin_enter(&sc->sc_mtx);
1440 SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next); 1452 SIMPLEQ_INSERT_TAIL(&sc->sc_queue, q, q_next);
1441 sc->sc_nqueue++; 1453 sc->sc_nqueue++;
1442 ubsecstats.hst_ipackets++; 1454 ubsecstats.hst_ipackets++;
1443 ubsecstats.hst_ibytes += dmap->d_alloc.dma_map->dm_mapsize; 1455 ubsecstats.hst_ibytes += dmap->d_alloc.dma_map->dm_mapsize;
1444 if ((hint & CRYPTO_HINT_MORE) == 0 || sc->sc_nqueue >= ubsec_maxbatch) 1456 if ((hint & CRYPTO_HINT_MORE) == 0 || sc->sc_nqueue >= ubsec_maxbatch)
1445 ubsec_feed(sc); 1457 ubsec_feed(sc);
1446 splx(s); 1458 mutex_spin_exit(&sc->sc_mtx);
1447 return (0); 1459 return (0);
1448 1460
1449errout: 1461errout:
1450 if (q != NULL) { 1462 if (q != NULL) {
1451 if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m)) 1463 if ((q->q_dst_m != NULL) && (q->q_src_m != q->q_dst_m))
1452 m_freem(q->q_dst_m); 1464 m_freem(q->q_dst_m);
1453 1465
1454 if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) { 1466 if (q->q_dst_map != NULL && q->q_dst_map != q->q_src_map) {
1455 bus_dmamap_unload(sc->sc_dmat, q->q_dst_map); 1467 bus_dmamap_unload(sc->sc_dmat, q->q_dst_map);
1456 bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map); 1468 bus_dmamap_destroy(sc->sc_dmat, q->q_dst_map);
1457 } 1469 }
1458 if (q->q_src_map != NULL) { 1470 if (q->q_src_map != NULL) {
1459 bus_dmamap_unload(sc->sc_dmat, q->q_src_map); 1471 bus_dmamap_unload(sc->sc_dmat, q->q_src_map);
1460 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map); 1472 bus_dmamap_destroy(sc->sc_dmat, q->q_src_map);
1461 } 1473 }
1462 1474
1463 s = splnet(); 1475 mutex_spin_enter(&sc->sc_mtx);
1464 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next); 1476 SIMPLEQ_INSERT_TAIL(&sc->sc_freequeue, q, q_next);
1465 splx(s); 1477 mutex_spin_exit(&sc->sc_mtx);
1466 } 1478 }
1467#if 0 /* jonathan says: this openbsd code seems to be subsumed elsewhere */ 1479#if 0 /* jonathan says: this openbsd code seems to be subsumed elsewhere */
1468 if (err == EINVAL) 1480 if (err == EINVAL)
1469 ubsecstats.hst_invalid++; 1481 ubsecstats.hst_invalid++;
1470 else 1482 else
1471 ubsecstats.hst_nomem++; 1483 ubsecstats.hst_nomem++;
1472#endif 1484#endif
1473 if (err != ERESTART) { 1485 if (err != ERESTART) {
1474 crp->crp_etype = err; 1486 crp->crp_etype = err;
1475 crypto_done(crp); 1487 crypto_done(crp);
1476 } else { 1488 } else {
1477 sc->sc_needwakeup |= CRYPTO_SYMQ; 1489 sc->sc_needwakeup |= CRYPTO_SYMQ;
1478 } 1490 }
@@ -1628,33 +1640,38 @@ ubsec_callback2(struct ubsec_softc *sc,  @@ -1628,33 +1640,38 @@ ubsec_callback2(struct ubsec_softc *sc,
1628 case UBS_CTXOP_RNGBYPASS: { 1640 case UBS_CTXOP_RNGBYPASS: {
1629 struct ubsec_q2_rng *rng = (struct ubsec_q2_rng *)q; 1641 struct ubsec_q2_rng *rng = (struct ubsec_q2_rng *)q;
1630 u_int32_t *p; 1642 u_int32_t *p;
1631 int i; 1643 int i;
1632 1644
1633 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, 1645 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0,
1634 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1646 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_POSTREAD);
1635 p = (u_int32_t *)rng->rng_buf.dma_vaddr; 1647 p = (u_int32_t *)rng->rng_buf.dma_vaddr;
1636#ifndef __NetBSD__ 1648#ifndef __NetBSD__
1637 for (i = 0; i < UBSEC_RNG_BUFSIZ; p++, i++) 1649 for (i = 0; i < UBSEC_RNG_BUFSIZ; p++, i++)
1638 add_true_randomness(letoh32(*p)); 1650 add_true_randomness(letoh32(*p));
1639 rng->rng_used = 0; 1651 rng->rng_used = 0;
1640#else 1652#else
1641 /* XXX NetBSD rnd subsystem too weak */ 1653 i = UBSEC_RNG_BUFSIZ * sizeof(u_int32_t);
1642 i = 0; (void)i; /* shut off gcc warnings */ 1654 rnd_add_data(&sc->sc_rnd_source, (char *)p, i, i * NBBY);
 1655 sc->sc_rng_need -= i;
 1656 rng->rng_used = 0;
1643#endif 1657#endif
1644#ifdef __OpenBSD__ 1658#ifdef __OpenBSD__
1645 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 1659 timeout_add(&sc->sc_rngto, sc->sc_rnghz);
1646#else 1660#else
1647 callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc); 1661 if (sc->sc_rng_need > 0) {
 1662 callout_reset(&sc->sc_rngto, sc->sc_rnghz,
 1663 ubsec_rng, sc);
 1664 }
1648#endif 1665#endif
1649 break; 1666 break;
1650 } 1667 }
1651#endif 1668#endif
1652 case UBS_CTXOP_MODEXP: { 1669 case UBS_CTXOP_MODEXP: {
1653 struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q; 1670 struct ubsec_q2_modexp *me = (struct ubsec_q2_modexp *)q;
1654 u_int rlen, clen; 1671 u_int rlen, clen;
1655 1672
1656 krp = me->me_krp; 1673 krp = me->me_krp;
1657 rlen = (me->me_modbits + 7) / 8; 1674 rlen = (me->me_modbits + 7) / 8;
1658 clen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8; 1675 clen = (krp->krp_param[krp->krp_iparams].crp_nbits + 7) / 8;
1659 1676
1660 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 1677 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map,
@@ -1717,40 +1734,68 @@ ubsec_callback2(struct ubsec_softc *sc,  @@ -1717,40 +1734,68 @@ ubsec_callback2(struct ubsec_softc *sc,
1717 1734
1718 /* Can't free here, so put us on the free list. */ 1735 /* Can't free here, so put us on the free list. */
1719 SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &rp->rpr_q, q_next); 1736 SIMPLEQ_INSERT_TAIL(&sc->sc_q2free, &rp->rpr_q, q_next);
1720 break; 1737 break;
1721 } 1738 }
1722 default: 1739 default:
1723 printf("%s: unknown ctx op: %x\n", device_xname(sc->sc_dev), 1740 printf("%s: unknown ctx op: %x\n", device_xname(sc->sc_dev),
1724 letoh16(ctx->ctx_op)); 1741 letoh16(ctx->ctx_op));
1725 break; 1742 break;
1726 } 1743 }
1727} 1744}
1728 1745
1729#ifndef UBSEC_NO_RNG 1746#ifndef UBSEC_NO_RNG
 1747
 1748static void
 1749ubsec_rng_get(size_t bytes, void *vsc)
 1750{
 1751 struct ubsec_softc *sc = vsc;
 1752
 1753 mutex_spin_enter(&sc->sc_mtx);
 1754 sc->sc_rng_need = bytes;
 1755 ubsec_rng_locked(sc);
 1756 mutex_spin_exit(&sc->sc_mtx);
 1757
 1758}
 1759
1730static void 1760static void
1731ubsec_rng(void *vsc) 1761ubsec_rng(void *vsc)
1732{ 1762{
1733 struct ubsec_softc *sc = vsc; 1763 struct ubsec_softc *sc = vsc;
 1764 mutex_spin_enter(&sc->sc_mtx);
 1765 ubsec_rng_locked(sc);
 1766 mutex_spin_exit(&sc->sc_mtx);
 1767}
 1768
 1769static void
 1770ubsec_rng_locked(void *vsc)
 1771{
 1772 struct ubsec_softc *sc = vsc;
1734 struct ubsec_q2_rng *rng = &sc->sc_rng; 1773 struct ubsec_q2_rng *rng = &sc->sc_rng;
1735 struct ubsec_mcr *mcr; 1774 struct ubsec_mcr *mcr;
1736 struct ubsec_ctx_rngbypass *ctx; 1775 struct ubsec_ctx_rngbypass *ctx;
1737 int s; 
1738 1776
1739 s = splnet(); 1777 mutex_spin_enter(&sc->sc_mtx);
1740 if (rng->rng_used) { 1778 if (rng->rng_used) {
1741 splx(s); 1779 mutex_spin_exit(&sc->sc_mtx);
1742 return; 1780 return;
1743 } 1781 }
 1782
 1783 if (sc->sc_rng_need < 1) {
 1784 callout_stop(&sc->sc_rngto);
 1785 mutex_spin_exit(&sc->sc_mtx);
 1786 return;
 1787 }
 1788
1744 sc->sc_nqueue2++; 1789 sc->sc_nqueue2++;
1745 if (sc->sc_nqueue2 >= UBS_MAX_NQUEUE) 1790 if (sc->sc_nqueue2 >= UBS_MAX_NQUEUE)
1746 goto out; 1791 goto out;
1747 1792
1748 mcr = (struct ubsec_mcr *)rng->rng_q.q_mcr.dma_vaddr; 1793 mcr = (struct ubsec_mcr *)rng->rng_q.q_mcr.dma_vaddr;
1749 ctx = (struct ubsec_ctx_rngbypass *)rng->rng_q.q_ctx.dma_vaddr; 1794 ctx = (struct ubsec_ctx_rngbypass *)rng->rng_q.q_ctx.dma_vaddr;
1750 1795
1751 mcr->mcr_pkts = htole16(1); 1796 mcr->mcr_pkts = htole16(1);
1752 mcr->mcr_flags = 0; 1797 mcr->mcr_flags = 0;
1753 mcr->mcr_cmdctxp = htole32(rng->rng_q.q_ctx.dma_paddr); 1798 mcr->mcr_cmdctxp = htole32(rng->rng_q.q_ctx.dma_paddr);
1754 mcr->mcr_ipktbuf.pb_addr = mcr->mcr_ipktbuf.pb_next = 0; 1799 mcr->mcr_ipktbuf.pb_addr = mcr->mcr_ipktbuf.pb_next = 0;
1755 mcr->mcr_ipktbuf.pb_len = 0; 1800 mcr->mcr_ipktbuf.pb_len = 0;
1756 mcr->mcr_reserved = mcr->mcr_pktlen = 0; 1801 mcr->mcr_reserved = mcr->mcr_pktlen = 0;
@@ -1760,36 +1805,36 @@ ubsec_rng(void *vsc) @@ -1760,36 +1805,36 @@ ubsec_rng(void *vsc)
1760 mcr->mcr_opktbuf.pb_next = 0; 1805 mcr->mcr_opktbuf.pb_next = 0;
1761 1806
1762 ctx->rbp_len = htole16(sizeof(struct ubsec_ctx_rngbypass)); 1807 ctx->rbp_len = htole16(sizeof(struct ubsec_ctx_rngbypass));
1763 ctx->rbp_op = htole16(UBS_CTXOP_RNGSHA1); 1808 ctx->rbp_op = htole16(UBS_CTXOP_RNGSHA1);
1764 rng->rng_q.q_type = UBS_CTXOP_RNGSHA1; 1809 rng->rng_q.q_type = UBS_CTXOP_RNGSHA1;
1765 1810
1766 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0, 1811 bus_dmamap_sync(sc->sc_dmat, rng->rng_buf.dma_map, 0,
1767 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1812 rng->rng_buf.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
1768 1813
1769 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rng->rng_q, q_next); 1814 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rng->rng_q, q_next);
1770 rng->rng_used = 1; 1815 rng->rng_used = 1;
1771 ubsec_feed2(sc); 1816 ubsec_feed2(sc);
1772 ubsecstats.hst_rng++; 1817 ubsecstats.hst_rng++;
1773 splx(s); 1818 mutex_spin_exit(&sc->sc_mtx);
1774 1819
1775 return; 1820 return;
1776 1821
1777out: 1822out:
1778 /* 1823 /*
1779 * Something weird happened, generate our own call back. 1824 * Something weird happened, generate our own call back.
1780 */ 1825 */
1781 sc->sc_nqueue2--; 1826 sc->sc_nqueue2--;
1782 splx(s); 1827 mutex_spin_exit(&sc->sc_mtx);
1783#ifdef __OpenBSD__ 1828#ifdef __OpenBSD__
1784 timeout_add(&sc->sc_rngto, sc->sc_rnghz); 1829 timeout_add(&sc->sc_rngto, sc->sc_rnghz);
1785#else 1830#else
1786 callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc); 1831 callout_reset(&sc->sc_rngto, sc->sc_rnghz, ubsec_rng, sc);
1787#endif 1832#endif
1788} 1833}
1789#endif /* UBSEC_NO_RNG */ 1834#endif /* UBSEC_NO_RNG */
1790 1835
1791static int 1836static int
1792ubsec_dma_malloc(struct ubsec_softc *sc, bus_size_t size, 1837ubsec_dma_malloc(struct ubsec_softc *sc, bus_size_t size,
1793 struct ubsec_dma_alloc *dma,int mapflags) 1838 struct ubsec_dma_alloc *dma,int mapflags)
1794{ 1839{
1795 int r; 1840 int r;
@@ -2087,27 +2132,27 @@ ubsec_kprocess(void *arg, struct cryptko @@ -2087,27 +2132,27 @@ ubsec_kprocess(void *arg, struct cryptko
2087} 2132}
2088 2133
2089/* 2134/*
2090 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization) 2135 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (sw normalization)
2091 */ 2136 */
2092static int 2137static int
2093ubsec_kprocess_modexp_sw(struct ubsec_softc *sc, struct cryptkop *krp, 2138ubsec_kprocess_modexp_sw(struct ubsec_softc *sc, struct cryptkop *krp,
2094 int hint) 2139 int hint)
2095{ 2140{
2096 struct ubsec_q2_modexp *me; 2141 struct ubsec_q2_modexp *me;
2097 struct ubsec_mcr *mcr; 2142 struct ubsec_mcr *mcr;
2098 struct ubsec_ctx_modexp *ctx; 2143 struct ubsec_ctx_modexp *ctx;
2099 struct ubsec_pktbuf *epb; 2144 struct ubsec_pktbuf *epb;
2100 int s, err = 0; 2145 int err = 0;
2101 u_int nbits, normbits, mbits, shiftbits, ebits; 2146 u_int nbits, normbits, mbits, shiftbits, ebits;
2102 2147
2103 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT); 2148 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT);
2104 if (me == NULL) { 2149 if (me == NULL) {
2105 err = ENOMEM; 2150 err = ENOMEM;
2106 goto errout; 2151 goto errout;
2107 } 2152 }
2108 memset(me, 0, sizeof *me); 2153 memset(me, 0, sizeof *me);
2109 me->me_krp = krp; 2154 me->me_krp = krp;
2110 me->me_q.q_type = UBS_CTXOP_MODEXP; 2155 me->me_q.q_type = UBS_CTXOP_MODEXP;
2111 2156
2112 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]); 2157 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]);
2113 if (nbits <= 512) 2158 if (nbits <= 512)
@@ -2244,31 +2289,31 @@ ubsec_kprocess_modexp_sw(struct ubsec_so @@ -2244,31 +2289,31 @@ ubsec_kprocess_modexp_sw(struct ubsec_so
2244 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2289 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2245 * everything else. 2290 * everything else.
2246 */ 2291 */
2247 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 2292 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map,
2248 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2293 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2249 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, 2294 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map,
2250 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2295 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2251 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, 2296 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map,
2252 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2297 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
2253 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, 2298 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map,
2254 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2299 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2255 2300
2256 /* Enqueue and we're done... */ 2301 /* Enqueue and we're done... */
2257 s = splnet(); 2302 mutex_spin_enter(&sc->sc_mtx);
2258 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next); 2303 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next);
2259 ubsec_feed2(sc); 2304 ubsec_feed2(sc);
2260 ubsecstats.hst_modexp++; 2305 ubsecstats.hst_modexp++;
2261 splx(s); 2306 mutex_spin_exit(&sc->sc_mtx);
2262 2307
2263 return (0); 2308 return (0);
2264 2309
2265errout: 2310errout:
2266 if (me != NULL) { 2311 if (me != NULL) {
2267 if (me->me_q.q_mcr.dma_map != NULL) 2312 if (me->me_q.q_mcr.dma_map != NULL)
2268 ubsec_dma_free(sc, &me->me_q.q_mcr); 2313 ubsec_dma_free(sc, &me->me_q.q_mcr);
2269 if (me->me_q.q_ctx.dma_map != NULL) { 2314 if (me->me_q.q_ctx.dma_map != NULL) {
2270 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size); 2315 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size);
2271 ubsec_dma_free(sc, &me->me_q.q_ctx); 2316 ubsec_dma_free(sc, &me->me_q.q_ctx);
2272 } 2317 }
2273 if (me->me_M.dma_map != NULL) { 2318 if (me->me_M.dma_map != NULL) {
2274 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size); 2319 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size);
@@ -2292,27 +2337,27 @@ errout: @@ -2292,27 +2337,27 @@ errout:
2292} 2337}
2293 2338
2294/* 2339/*
2295 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (hw normalization) 2340 * Start computation of cr[C] = (cr[M] ^ cr[E]) mod cr[N] (hw normalization)
2296 */ 2341 */
2297static int 2342static int
2298ubsec_kprocess_modexp_hw(struct ubsec_softc *sc, struct cryptkop *krp, 2343ubsec_kprocess_modexp_hw(struct ubsec_softc *sc, struct cryptkop *krp,
2299 int hint) 2344 int hint)
2300{ 2345{
2301 struct ubsec_q2_modexp *me; 2346 struct ubsec_q2_modexp *me;
2302 struct ubsec_mcr *mcr; 2347 struct ubsec_mcr *mcr;
2303 struct ubsec_ctx_modexp *ctx; 2348 struct ubsec_ctx_modexp *ctx;
2304 struct ubsec_pktbuf *epb; 2349 struct ubsec_pktbuf *epb;
2305 int s, err = 0; 2350 int err = 0;
2306 u_int nbits, normbits, mbits, shiftbits, ebits; 2351 u_int nbits, normbits, mbits, shiftbits, ebits;
2307 2352
2308 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT); 2353 me = (struct ubsec_q2_modexp *)malloc(sizeof *me, M_DEVBUF, M_NOWAIT);
2309 if (me == NULL) { 2354 if (me == NULL) {
2310 err = ENOMEM; 2355 err = ENOMEM;
2311 goto errout; 2356 goto errout;
2312 } 2357 }
2313 memset(me, 0, sizeof *me); 2358 memset(me, 0, sizeof *me);
2314 me->me_krp = krp; 2359 me->me_krp = krp;
2315 me->me_q.q_type = UBS_CTXOP_MODEXP; 2360 me->me_q.q_type = UBS_CTXOP_MODEXP;
2316 2361
2317 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]); 2362 nbits = ubsec_ksigbits(&krp->krp_param[UBS_MODEXP_PAR_N]);
2318 if (nbits <= 512) 2363 if (nbits <= 512)
@@ -2449,30 +2494,30 @@ ubsec_kprocess_modexp_hw(struct ubsec_so @@ -2449,30 +2494,30 @@ ubsec_kprocess_modexp_hw(struct ubsec_so
2449 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2494 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2450 * everything else. 2495 * everything else.
2451 */ 2496 */
2452 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map, 2497 bus_dmamap_sync(sc->sc_dmat, me->me_M.dma_map,
2453 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2498 0, me->me_M.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2454 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map, 2499 bus_dmamap_sync(sc->sc_dmat, me->me_E.dma_map,
2455 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2500 0, me->me_E.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2456 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map, 2501 bus_dmamap_sync(sc->sc_dmat, me->me_C.dma_map,
2457 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2502 0, me->me_C.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
2458 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map, 2503 bus_dmamap_sync(sc->sc_dmat, me->me_epb.dma_map,
2459 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2504 0, me->me_epb.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2460 2505
2461 /* Enqueue and we're done... */ 2506 /* Enqueue and we're done... */
2462 s = splnet(); 2507 mutex_spin_enter(&sc->sc_mtx);
2463 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next); 2508 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &me->me_q, q_next);
2464 ubsec_feed2(sc); 2509 ubsec_feed2(sc);
2465 splx(s); 2510 mutex_spin_exit(&sc->sc_mtx);
2466 2511
2467 return (0); 2512 return (0);
2468 2513
2469errout: 2514errout:
2470 if (me != NULL) { 2515 if (me != NULL) {
2471 if (me->me_q.q_mcr.dma_map != NULL) 2516 if (me->me_q.q_mcr.dma_map != NULL)
2472 ubsec_dma_free(sc, &me->me_q.q_mcr); 2517 ubsec_dma_free(sc, &me->me_q.q_mcr);
2473 if (me->me_q.q_ctx.dma_map != NULL) { 2518 if (me->me_q.q_ctx.dma_map != NULL) {
2474 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size); 2519 memset(me->me_q.q_ctx.dma_vaddr, 0, me->me_q.q_ctx.dma_size);
2475 ubsec_dma_free(sc, &me->me_q.q_ctx); 2520 ubsec_dma_free(sc, &me->me_q.q_ctx);
2476 } 2521 }
2477 if (me->me_M.dma_map != NULL) { 2522 if (me->me_M.dma_map != NULL) {
2478 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size); 2523 memset(me->me_M.dma_vaddr, 0, me->me_M.dma_size);
@@ -2492,27 +2537,27 @@ errout: @@ -2492,27 +2537,27 @@ errout:
2492 } 2537 }
2493 krp->krp_status = err; 2538 krp->krp_status = err;
2494 crypto_kdone(krp); 2539 crypto_kdone(krp);
2495 return (0); 2540 return (0);
2496} 2541}
2497 2542
2498static int 2543static int
2499ubsec_kprocess_rsapriv(struct ubsec_softc *sc, struct cryptkop *krp, 2544ubsec_kprocess_rsapriv(struct ubsec_softc *sc, struct cryptkop *krp,
2500 int hint) 2545 int hint)
2501{ 2546{
2502 struct ubsec_q2_rsapriv *rp = NULL; 2547 struct ubsec_q2_rsapriv *rp = NULL;
2503 struct ubsec_mcr *mcr; 2548 struct ubsec_mcr *mcr;
2504 struct ubsec_ctx_rsapriv *ctx; 2549 struct ubsec_ctx_rsapriv *ctx;
2505 int s, err = 0; 2550 int err = 0;
2506 u_int padlen, msglen; 2551 u_int padlen, msglen;
2507 2552
2508 msglen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_P]); 2553 msglen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_P]);
2509 padlen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_Q]); 2554 padlen = ubsec_ksigbits(&krp->krp_param[UBS_RSAPRIV_PAR_Q]);
2510 if (msglen > padlen) 2555 if (msglen > padlen)
2511 padlen = msglen; 2556 padlen = msglen;
2512 2557
2513 if (padlen <= 256) 2558 if (padlen <= 256)
2514 padlen = 256; 2559 padlen = 256;
2515 else if (padlen <= 384) 2560 else if (padlen <= 384)
2516 padlen = 384; 2561 padlen = 384;
2517 else if (padlen <= 512) 2562 else if (padlen <= 512)
2518 padlen = 512; 2563 padlen = 512;
@@ -2645,31 +2690,31 @@ ubsec_kprocess_rsapriv(struct ubsec_soft @@ -2645,31 +2690,31 @@ ubsec_kprocess_rsapriv(struct ubsec_soft
2645 ctx->rpr_q_len = htole16(padlen); 2690 ctx->rpr_q_len = htole16(padlen);
2646 ctx->rpr_p_len = htole16(padlen); 2691 ctx->rpr_p_len = htole16(padlen);
2647 2692
2648 /* 2693 /*
2649 * ubsec_feed2 will sync mcr and ctx, we just need to sync 2694 * ubsec_feed2 will sync mcr and ctx, we just need to sync
2650 * everything else. 2695 * everything else.
2651 */ 2696 */
2652 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map, 2697 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgin.dma_map,
2653 0, rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 2698 0, rp->rpr_msgin.dma_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
2654 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map, 2699 bus_dmamap_sync(sc->sc_dmat, rp->rpr_msgout.dma_map,
2655 0, rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD); 2700 0, rp->rpr_msgout.dma_map->dm_mapsize, BUS_DMASYNC_PREREAD);
2656 2701
2657 /* Enqueue and we're done... */ 2702 /* Enqueue and we're done... */
2658 s = splnet(); 2703 mutex_spin_enter(&sc->sc_mtx);
2659 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rp->rpr_q, q_next); 2704 SIMPLEQ_INSERT_TAIL(&sc->sc_queue2, &rp->rpr_q, q_next);
2660 ubsec_feed2(sc); 2705 ubsec_feed2(sc);
2661 ubsecstats.hst_modexpcrt++; 2706 ubsecstats.hst_modexpcrt++;
2662 splx(s); 2707 mutex_spin_exit(&sc->sc_mtx);
2663 return (0); 2708 return (0);
2664 2709
2665errout: 2710errout:
2666 if (rp != NULL) { 2711 if (rp != NULL) {
2667 if (rp->rpr_q.q_mcr.dma_map != NULL) 2712 if (rp->rpr_q.q_mcr.dma_map != NULL)
2668 ubsec_dma_free(sc, &rp->rpr_q.q_mcr); 2713 ubsec_dma_free(sc, &rp->rpr_q.q_mcr);
2669 if (rp->rpr_msgin.dma_map != NULL) { 2714 if (rp->rpr_msgin.dma_map != NULL) {
2670 memset(rp->rpr_msgin.dma_vaddr, 0, rp->rpr_msgin.dma_size); 2715 memset(rp->rpr_msgin.dma_vaddr, 0, rp->rpr_msgin.dma_size);
2671 ubsec_dma_free(sc, &rp->rpr_msgin); 2716 ubsec_dma_free(sc, &rp->rpr_msgin);
2672 } 2717 }
2673 if (rp->rpr_msgout.dma_map != NULL) { 2718 if (rp->rpr_msgout.dma_map != NULL) {
2674 memset(rp->rpr_msgout.dma_vaddr, 0, rp->rpr_msgout.dma_size); 2719 memset(rp->rpr_msgout.dma_vaddr, 0, rp->rpr_msgout.dma_size);
2675 ubsec_dma_free(sc, &rp->rpr_msgout); 2720 ubsec_dma_free(sc, &rp->rpr_msgout);

cvs diff -r1.4 -r1.5 src/sys/dev/pci/ubsecvar.h (expand / switch to unified diff)

--- src/sys/dev/pci/ubsecvar.h 2012/10/27 17:18:35 1.4
+++ src/sys/dev/pci/ubsecvar.h 2013/06/13 00:55:01 1.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ubsecvar.h,v 1.4 2012/10/27 17:18:35 chs Exp $ */ 1/* $NetBSD: ubsecvar.h,v 1.5 2013/06/13 00:55:01 tls Exp $ */
2/* $OpenBSD: ubsecvar.h,v 1.36 2003/06/04 16:02:41 jason Exp $ */ 2/* $OpenBSD: ubsecvar.h,v 1.36 2003/06/04 16:02:41 jason Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2000 Theo de Raadt 5 * Copyright (c) 2000 Theo de Raadt
6 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com) 6 * Copyright (c) 2001 Patrik Lindergren (patrik@ipunplugged.com)
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -139,47 +139,50 @@ struct ubsec_q { @@ -139,47 +139,50 @@ struct ubsec_q {
139 struct mbuf *q_src_m, *q_dst_m; 139 struct mbuf *q_src_m, *q_dst_m;
140 struct uio *q_src_io, *q_dst_io; 140 struct uio *q_src_io, *q_dst_io;
141 141
142 bus_dmamap_t q_src_map; 142 bus_dmamap_t q_src_map;
143 bus_dmamap_t q_dst_map; 143 bus_dmamap_t q_dst_map;
144 144
145 int q_sesn; 145 int q_sesn;
146 int q_flags; 146 int q_flags;
147}; 147};
148 148
149struct ubsec_softc { 149struct ubsec_softc {
150 device_t sc_dev; /* generic device */ 150 device_t sc_dev; /* generic device */
151 void *sc_ih; /* interrupt handler cookie */ 151 void *sc_ih; /* interrupt handler cookie */
 152 kmutex_t sc_mtx;
152 bus_space_handle_t sc_sh; /* memory handle */ 153 bus_space_handle_t sc_sh; /* memory handle */
153 bus_space_tag_t sc_st; /* memory tag */ 154 bus_space_tag_t sc_st; /* memory tag */
154 bus_dma_tag_t sc_dmat; /* dma tag */ 155 bus_dma_tag_t sc_dmat; /* dma tag */
155 int sc_flags; /* device specific flags */ 156 int sc_flags; /* device specific flags */
156 int sc_suspended; 157 int sc_suspended;
157 int sc_needwakeup; /* notify crypto layer */ 158 int sc_needwakeup; /* notify crypto layer */
158 u_int32_t sc_statmask; /* interrupt status mask */ 159 u_int32_t sc_statmask; /* interrupt status mask */
159 int32_t sc_cid; /* crypto tag */ 160 int32_t sc_cid; /* crypto tag */
160 SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue, mcr1 */ 161 SIMPLEQ_HEAD(,ubsec_q) sc_queue; /* packet queue, mcr1 */
161 int sc_nqueue; /* count enqueued, mcr1 */ 162 int sc_nqueue; /* count enqueued, mcr1 */
162 SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip, mcr1 */ 163 SIMPLEQ_HEAD(,ubsec_q) sc_qchip; /* on chip, mcr1 */
163 int sc_nqchip; /* count on chip, mcr1 */ 164 int sc_nqchip; /* count on chip, mcr1 */
164 SIMPLEQ_HEAD(,ubsec_q) sc_freequeue; /* list of free queue elements */ 165 SIMPLEQ_HEAD(,ubsec_q) sc_freequeue; /* list of free queue elements */
165 SIMPLEQ_HEAD(,ubsec_q2) sc_queue2; /* packet queue, mcr2 */ 166 SIMPLEQ_HEAD(,ubsec_q2) sc_queue2; /* packet queue, mcr2 */
166 int sc_nqueue2; /* count enqueued, mcr2 */ 167 int sc_nqueue2; /* count enqueued, mcr2 */
167 SIMPLEQ_HEAD(,ubsec_q2) sc_qchip2; /* on chip, mcr2 */ 168 SIMPLEQ_HEAD(,ubsec_q2) sc_qchip2; /* on chip, mcr2 */
168 int sc_nsessions; /* # of sessions */ 169 int sc_nsessions; /* # of sessions */
169 struct ubsec_session *sc_sessions; /* sessions */ 170 struct ubsec_session *sc_sessions; /* sessions */
170 struct callout sc_rngto; /* rng timeout */ 171 struct callout sc_rngto; /* rng timeout */
171 int sc_rnghz; /* rng poll time */ 172 int sc_rnghz; /* rng poll time */
172 struct ubsec_q2_rng sc_rng; 173 struct ubsec_q2_rng sc_rng;
 174 krndsource_t sc_rnd_source;
 175 int sc_rng_need; /* how many bytes wanted */
173 struct ubsec_dma sc_dmaa[UBS_MAX_NQUEUE]; 176 struct ubsec_dma sc_dmaa[UBS_MAX_NQUEUE];
174 struct ubsec_q *sc_queuea[UBS_MAX_NQUEUE]; 177 struct ubsec_q *sc_queuea[UBS_MAX_NQUEUE];
175 SIMPLEQ_HEAD(,ubsec_q2) sc_q2free; /* free list */ 178 SIMPLEQ_HEAD(,ubsec_q2) sc_q2free; /* free list */
176}; 179};
177 180
178#define UBSEC_QFLAGS_COPYOUTIV 0x1 181#define UBSEC_QFLAGS_COPYOUTIV 0x1
179 182
180struct ubsec_session { 183struct ubsec_session {
181 u_int32_t ses_used; 184 u_int32_t ses_used;
182 u_int32_t ses_deskey[6]; /* 3DES key */ 185 u_int32_t ses_deskey[6]; /* 3DES key */
183 u_int32_t ses_hminner[5]; /* hmac inner state */ 186 u_int32_t ses_hminner[5]; /* hmac inner state */
184 u_int32_t ses_hmouter[5]; /* hmac outer state */ 187 u_int32_t ses_hmouter[5]; /* hmac outer state */
185 u_int32_t ses_iv[2]; /* [3]DES iv */ 188 u_int32_t ses_iv[2]; /* [3]DES iv */

cvs diff -r1.300 -r1.301 src/sys/dev/scsipi/sd.c (expand / switch to unified diff)

--- src/sys/dev/scsipi/sd.c 2013/05/29 00:47:49 1.300
+++ src/sys/dev/scsipi/sd.c 2013/06/13 00:55:01 1.301
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sd.c,v 1.300 2013/05/29 00:47:49 christos Exp $ */ 1/* $NetBSD: sd.c,v 1.301 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum. 8 * by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -37,27 +37,27 @@ @@ -37,27 +37,27 @@
37 * Mellon University, makes this software available to CMU to distribute 37 * Mellon University, makes this software available to CMU to distribute
38 * or use in any manner that they see fit as long as this message is kept with 38 * or use in any manner that they see fit as long as this message is kept with
39 * the software. For this reason TFS also grants any other persons or 39 * the software. For this reason TFS also grants any other persons or
40 * organisations permission to use or modify this software. 40 * organisations permission to use or modify this software.
41 * 41 *
42 * TFS supplies this software to be publicly redistributed 42 * TFS supplies this software to be publicly redistributed
43 * on the understanding that TFS is not responsible for the correct 43 * on the understanding that TFS is not responsible for the correct
44 * functioning of this software in any circumstances. 44 * functioning of this software in any circumstances.
45 * 45 *
46 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 46 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
47 */ 47 */
48 48
49#include <sys/cdefs.h> 49#include <sys/cdefs.h>
50__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.300 2013/05/29 00:47:49 christos Exp $"); 50__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.301 2013/06/13 00:55:01 tls Exp $");
51 51
52#include "opt_scsi.h" 52#include "opt_scsi.h"
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/systm.h> 55#include <sys/systm.h>
56#include <sys/kernel.h> 56#include <sys/kernel.h>
57#include <sys/file.h> 57#include <sys/file.h>
58#include <sys/stat.h> 58#include <sys/stat.h>
59#include <sys/ioctl.h> 59#include <sys/ioctl.h>
60#include <sys/scsiio.h> 60#include <sys/scsiio.h>
61#include <sys/buf.h> 61#include <sys/buf.h>
62#include <sys/bufq.h> 62#include <sys/bufq.h>
63#include <sys/uio.h> 63#include <sys/uio.h>
@@ -205,27 +205,27 @@ sdmatch(device_t parent, cfdata_t match, @@ -205,27 +205,27 @@ sdmatch(device_t parent, cfdata_t match,
205 205
206 return (priority); 206 return (priority);
207} 207}
208 208
209/* 209/*
210 * Attach routine common to atapi & scsi. 210 * Attach routine common to atapi & scsi.
211 */ 211 */
212static void 212static void
213sdattach(device_t parent, device_t self, void *aux) 213sdattach(device_t parent, device_t self, void *aux)
214{ 214{
215 struct sd_softc *sd = device_private(self); 215 struct sd_softc *sd = device_private(self);
216 struct scsipibus_attach_args *sa = aux; 216 struct scsipibus_attach_args *sa = aux;
217 struct scsipi_periph *periph = sa->sa_periph; 217 struct scsipi_periph *periph = sa->sa_periph;
218 int error, result, rndval = cprng_strong32(); 218 int error, result;
219 struct disk_parms *dp = &sd->params; 219 struct disk_parms *dp = &sd->params;
220 char pbuf[9]; 220 char pbuf[9];
221 221
222 SC_DEBUG(periph, SCSIPI_DB2, ("sdattach: ")); 222 SC_DEBUG(periph, SCSIPI_DB2, ("sdattach: "));
223 223
224 sd->sc_dev = self; 224 sd->sc_dev = self;
225 sd->type = (sa->sa_inqbuf.type & SID_TYPE); 225 sd->type = (sa->sa_inqbuf.type & SID_TYPE);
226 strncpy(sd->name, sa->sa_inqbuf.product, sizeof(sd->name)); 226 strncpy(sd->name, sa->sa_inqbuf.product, sizeof(sd->name));
227 if (sd->type == T_SIMPLE_DIRECT) 227 if (sd->type == T_SIMPLE_DIRECT)
228 periph->periph_quirks |= PQUIRK_ONLYBIG | PQUIRK_NOBIGMODESENSE; 228 periph->periph_quirks |= PQUIRK_ONLYBIG | PQUIRK_NOBIGMODESENSE;
229 229
230 if (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph)) == 230 if (SCSIPI_BUSTYPE_TYPE(scsipi_periph_bustype(sa->sa_periph)) ==
231 SCSIPI_BUSTYPE_SCSI && periph->periph_version == 0) 231 SCSIPI_BUSTYPE_SCSI && periph->periph_version == 0)
@@ -318,36 +318,36 @@ sdattach(device_t parent, device_t self, @@ -318,36 +318,36 @@ sdattach(device_t parent, device_t self,
318 */ 318 */
319 rnd_attach_source(&sd->rnd_source, device_xname(sd->sc_dev), 319 rnd_attach_source(&sd->rnd_source, device_xname(sd->sc_dev),
320 RND_TYPE_DISK, 0); 320 RND_TYPE_DISK, 0);
321 321
322 /* Discover wedges on this disk. */ 322 /* Discover wedges on this disk. */
323 dkwedge_discover(&sd->sc_dk); 323 dkwedge_discover(&sd->sc_dk);
324 324
325 /* 325 /*
326 * Disk insertion and removal times can be a useful source 326 * Disk insertion and removal times can be a useful source
327 * of entropy, though the estimator should never _count_ 327 * of entropy, though the estimator should never _count_
328 * these bits, on insertion, because the deltas to the 328 * these bits, on insertion, because the deltas to the
329 * nonexistent) previous event should never allow it. 329 * nonexistent) previous event should never allow it.
330 */ 330 */
331 rnd_add_uint32(&sd->rnd_source, rndval); 331 rnd_add_uint32(&sd->rnd_source, 0);
332} 332}
333 333
334static int 334static int
335sddetach(device_t self, int flags) 335sddetach(device_t self, int flags)
336{ 336{
337 struct sd_softc *sd = device_private(self); 337 struct sd_softc *sd = device_private(self);
338 int s, bmaj, cmaj, i, mn, rc, rndval = cprng_strong32(); 338 int s, bmaj, cmaj, i, mn, rc;
339 339
340 rnd_add_uint32(&sd->rnd_source, rndval); 340 rnd_add_uint32(&sd->rnd_source, 0);
341 341
342 if ((rc = disk_begindetach(&sd->sc_dk, sdlastclose, self, flags)) != 0) 342 if ((rc = disk_begindetach(&sd->sc_dk, sdlastclose, self, flags)) != 0)
343 return rc; 343 return rc;
344 344
345 /* locate the major number */ 345 /* locate the major number */
346 bmaj = bdevsw_lookup_major(&sd_bdevsw); 346 bmaj = bdevsw_lookup_major(&sd_bdevsw);
347 cmaj = cdevsw_lookup_major(&sd_cdevsw); 347 cmaj = cdevsw_lookup_major(&sd_cdevsw);
348 348
349 /* Nuke the vnodes for any open instances */ 349 /* Nuke the vnodes for any open instances */
350 for (i = 0; i < MAXPARTITIONS; i++) { 350 for (i = 0; i < MAXPARTITIONS; i++) {
351 mn = SDMINOR(device_unit(self), i); 351 mn = SDMINOR(device_unit(self), i);
352 vdevgone(bmaj, mn, mn, VBLK); 352 vdevgone(bmaj, mn, mn, VBLK);
353 vdevgone(cmaj, mn, mn, VCHR); 353 vdevgone(cmaj, mn, mn, VCHR);

cvs diff -r1.2 -r1.3 src/sys/kern/Attic/kern_rndpool.c (expand / switch to unified diff)

--- src/sys/kern/Attic/kern_rndpool.c 2012/04/17 02:50:38 1.2
+++ src/sys/kern/Attic/kern_rndpool.c 2013/06/13 00:55:01 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_rndpool.c,v 1.2 2012/04/17 02:50:38 tls Exp $ */ 1/* $NetBSD: kern_rndpool.c,v 1.3 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org>. This code uses ideas and 8 * by Michael Graff <explorer@flame.org>. This code uses ideas and
9 * algorithms from the Linux driver written by Ted Ts'o. 9 * algorithms from the Linux driver written by Ted Ts'o.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -21,49 +21,52 @@ @@ -21,49 +21,52 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: kern_rndpool.c,v 1.2 2012/04/17 02:50:38 tls Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: kern_rndpool.c,v 1.3 2013/06/13 00:55:01 tls Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37#include <sys/systm.h> 37#include <sys/systm.h>
38#include <sys/sha1.h> 38#include <sys/sha1.h>
39 39
40#include <sys/rnd.h> 40#include <sys/rnd.h>
41#include <dev/rnd_private.h> 41#include <dev/rnd_private.h>
42 42
43/* 43/*
44 * The random pool "taps" 44 * The random pool "taps"
45 */ 45 */
46#define TAP1 99 46#define TAP1 99
47#define TAP2 59 47#define TAP2 59
48#define TAP3 31 48#define TAP3 31
49#define TAP4 9 49#define TAP4 9
50#define TAP5 7 50#define TAP5 7
51 51
52/* 52/*
53 * Let others know: the pool is full. 53 * Let others know: the pool is full.
 54 *
 55 * XXX these should be per-pool if we really mean to allow multiple pools.
54 */ 56 */
55int rnd_full = 0; /* Flag: is the pool full? */ 57int rnd_full = 0; /* Flag: is the pool full? */
56int rnd_filled = 0; /* Count: how many times filled? */ 58int rnd_filled = 0; /* Count: how many times filled? */
 59int rnd_empty = 1; /* Flag: is the pool empty? */
57 60
58static inline void rndpool_add_one_word(rndpool_t *, u_int32_t); 61static inline void rndpool_add_one_word(rndpool_t *, u_int32_t);
59 62
60void 63void
61rndpool_init(rndpool_t *rp) 64rndpool_init(rndpool_t *rp)
62{ 65{
63 66
64 rp->cursor = 0; 67 rp->cursor = 0;
65 rp->rotate = 1; 68 rp->rotate = 1;
66 69
67 memset(&rp->stats, 0, sizeof(rp->stats)); 70 memset(&rp->stats, 0, sizeof(rp->stats));
68 71
69 rp->stats.curentropy = 0; 72 rp->stats.curentropy = 0;

cvs diff -r1.10 -r1.11 src/sys/kern/Attic/kern_rndq.c (expand / switch to unified diff)

--- src/sys/kern/Attic/kern_rndq.c 2013/01/26 22:22:07 1.10
+++ src/sys/kern/Attic/kern_rndq.c 2013/06/13 00:55:01 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_rndq.c,v 1.10 2013/01/26 22:22:07 tls Exp $ */ 1/* $NetBSD: kern_rndq.c,v 1.11 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2013 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon. 8 * by Michael Graff <explorer@flame.org> and Thor Lancelot Simon.
9 * This code uses ideas and algorithms from the Linux driver written by 9 * This code uses ideas and algorithms from the Linux driver written by
10 * Ted Ts'o. 10 * Ted Ts'o.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -22,40 +22,41 @@ @@ -22,40 +22,41 @@
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.10 2013/01/26 22:22:07 tls Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.11 2013/06/13 00:55:01 tls Exp $");
36 36
37#include <sys/param.h> 37#include <sys/param.h>
38#include <sys/ioctl.h> 38#include <sys/ioctl.h>
39#include <sys/fcntl.h> 39#include <sys/fcntl.h>
40#include <sys/select.h> 40#include <sys/select.h>
41#include <sys/poll.h> 41#include <sys/poll.h>
42#include <sys/kmem.h> 42#include <sys/kmem.h>
43#include <sys/mutex.h> 43#include <sys/mutex.h>
44#include <sys/proc.h> 44#include <sys/proc.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/conf.h> 46#include <sys/conf.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/callout.h> 48#include <sys/callout.h>
 49#include <sys/intr.h>
49#include <sys/rnd.h> 50#include <sys/rnd.h>
50#include <sys/vnode.h> 51#include <sys/vnode.h>
51#include <sys/pool.h> 52#include <sys/pool.h>
52#include <sys/kauth.h> 53#include <sys/kauth.h>
53#include <sys/once.h> 54#include <sys/once.h>
54#include <sys/rngtest.h> 55#include <sys/rngtest.h>
55#include <sys/cpu.h> /* XXX temporary, see rnd_detach_source */ 56#include <sys/cpu.h> /* XXX temporary, see rnd_detach_source */
56 57
57#include <dev/rnd_private.h> 58#include <dev/rnd_private.h>
58 59
59#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */ 60#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
60#include <machine/cpu_counter.h> 61#include <machine/cpu_counter.h>
61#endif 62#endif
@@ -89,30 +90,33 @@ int rnd_debug = 0; @@ -89,30 +90,33 @@ int rnd_debug = 0;
89typedef struct _rnd_sample_t { 90typedef struct _rnd_sample_t {
90 SIMPLEQ_ENTRY(_rnd_sample_t) next; 91 SIMPLEQ_ENTRY(_rnd_sample_t) next;
91 krndsource_t *source; 92 krndsource_t *source;
92 int cursor; 93 int cursor;
93 int entropy; 94 int entropy;
94 u_int32_t ts[RND_SAMPLE_COUNT]; 95 u_int32_t ts[RND_SAMPLE_COUNT];
95 u_int32_t values[RND_SAMPLE_COUNT]; 96 u_int32_t values[RND_SAMPLE_COUNT];
96} rnd_sample_t; 97} rnd_sample_t;
97 98
98/* 99/*
99 * The event queue. Fields are altered at an interrupt level. 100 * The event queue. Fields are altered at an interrupt level.
100 * All accesses must be protected with the mutex. 101 * All accesses must be protected with the mutex.
101 */ 102 */
102volatile int rnd_timeout_pending; 
103SIMPLEQ_HEAD(, _rnd_sample_t) rnd_samples; 103SIMPLEQ_HEAD(, _rnd_sample_t) rnd_samples;
104kmutex_t rnd_mtx; 104kmutex_t rnd_mtx;
105 105
 106/*
 107 * This lock protects dispatch of our soft interrupts.
 108 */
 109kmutex_t rndsoft_mtx;
106 110
107/* 111/*
108 * Entropy sinks: usually other generators waiting to be rekeyed. 112 * Entropy sinks: usually other generators waiting to be rekeyed.
109 * 113 *
110 * A sink's callback MUST NOT re-add the sink to the list, or 114 * A sink's callback MUST NOT re-add the sink to the list, or
111 * list corruption will occur. The list is protected by the 115 * list corruption will occur. The list is protected by the
112 * rndsink_mtx, which must be released before calling any sink's 116 * rndsink_mtx, which must be released before calling any sink's
113 * callback. 117 * callback.
114 */ 118 */
115TAILQ_HEAD(, rndsink) rnd_sinks; 119TAILQ_HEAD(, rndsink) rnd_sinks;
116kmutex_t rndsink_mtx; 120kmutex_t rndsink_mtx;
117 121
118/* 122/*
@@ -139,34 +143,35 @@ kcondvar_t rndpool_cv; @@ -139,34 +143,35 @@ kcondvar_t rndpool_cv;
139static krndsource_t rnd_source_no_collect = { 143static krndsource_t rnd_source_no_collect = {
140 /* LIST_ENTRY list */ 144 /* LIST_ENTRY list */
141 .name = { 'N', 'o', 'C', 'o', 'l', 'l', 'e', 'c', 't', 145 .name = { 'N', 'o', 'C', 'o', 'l', 'l', 'e', 'c', 't',
142 0, 0, 0, 0, 0, 0, 0 }, 146 0, 0, 0, 0, 0, 0, 0 },
143 .last_time = 0, .last_delta = 0, .last_delta2 = 0, .total = 0, 147 .last_time = 0, .last_delta = 0, .last_delta2 = 0, .total = 0,
144 .type = RND_TYPE_UNKNOWN, 148 .type = RND_TYPE_UNKNOWN,
145 .flags = (RND_FLAG_NO_COLLECT | 149 .flags = (RND_FLAG_NO_COLLECT |
146 RND_FLAG_NO_ESTIMATE | 150 RND_FLAG_NO_ESTIMATE |
147 RND_TYPE_UNKNOWN), 151 RND_TYPE_UNKNOWN),
148 .state = NULL, 152 .state = NULL,
149 .test_cnt = 0, 153 .test_cnt = 0,
150 .test = NULL 154 .test = NULL
151}; 155};
152 156void *rnd_process, *rnd_wakeup;
153struct callout rnd_callout, skew_callout; 157struct callout skew_callout;
154 158
155void rnd_wakeup_readers(void); 159void rnd_wakeup_readers(void);
156static inline u_int32_t rnd_estimate_entropy(krndsource_t *, u_int32_t); 160static inline u_int32_t rnd_estimate_entropy(krndsource_t *, u_int32_t);
157static inline u_int32_t rnd_counter(void); 161static inline u_int32_t rnd_counter(void);
158static void rnd_timeout(void *); 162static void rnd_intr(void *);
159static void rnd_process_events(void *); 163static void rnd_wake(void *);
 164static void rnd_process_events(void);
160u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t); /* XXX */ 165u_int32_t rnd_extract_data_locked(void *, u_int32_t, u_int32_t); /* XXX */
161static void rnd_add_data_ts(krndsource_t *, const void *const, 166static void rnd_add_data_ts(krndsource_t *, const void *const,
162 uint32_t, uint32_t, uint32_t); 167 uint32_t, uint32_t, uint32_t);
163 168
164int rnd_ready = 0; 169int rnd_ready = 0;
165int rnd_initial_entropy = 0; 170int rnd_initial_entropy = 0;
166 171
167#ifdef DIAGNOSTIC 172#ifdef DIAGNOSTIC
168static int rnd_tested = 0; 173static int rnd_tested = 0;
169static rngtest_t rnd_rt; 174static rngtest_t rnd_rt;
170static uint8_t rnd_testbits[sizeof(rnd_rt.rt_b)]; 175static uint8_t rnd_testbits[sizeof(rnd_rt.rt_b)];
171#endif 176#endif
172 177
@@ -186,91 +191,161 @@ rnd_counter(void) @@ -186,91 +191,161 @@ rnd_counter(void)
186#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */ 191#if defined(__HAVE_CPU_COUNTER) && !defined(_RUMPKERNEL) /* XXX: bad pooka */
187 if (cpu_hascounter()) 192 if (cpu_hascounter())
188 return (cpu_counter32()); 193 return (cpu_counter32());
189#endif 194#endif
190 if (rnd_ready) { 195 if (rnd_ready) {
191 microtime(&tv); 196 microtime(&tv);
192 return (tv.tv_sec * 1000000 + tv.tv_usec); 197 return (tv.tv_sec * 1000000 + tv.tv_usec);
193 } 198 }
194 /* when called from rnd_init, its too early to call microtime safely */ 199 /* when called from rnd_init, its too early to call microtime safely */
195 return (0); 200 return (0);
196} 201}
197 202
198/* 203/*
 204 * We may be called from low IPL -- protect our softint.
 205 */
 206
 207static inline void
 208rnd_schedule_softint(void *softint)
 209{
 210 mutex_spin_enter(&rndsoft_mtx);
 211 softint_schedule(softint);
 212 mutex_spin_exit(&rndsoft_mtx);
 213}
 214
 215/*
 216 * XXX repulsive: we can't initialize our softints in rnd_init
 217 * XXX (too early) so we wrap the points where we'd schedule them, thus.
 218 */
 219static inline void
 220rnd_schedule_process(void)
 221{
 222 if (__predict_true(rnd_process)) {
 223 rnd_schedule_softint(rnd_process);
 224 return;
 225 }
 226 if (!cold) {
 227 rnd_process = softint_establish(SOFTINT_SERIAL|SOFTINT_MPSAFE,
 228 rnd_intr, NULL);
 229 }
 230 rnd_process_events();
 231}
 232
 233static inline void
 234rnd_schedule_wakeup(void)
 235{
 236 if (__predict_true(rnd_wakeup)) {
 237 rnd_schedule_softint(rnd_wakeup);
 238 return;
 239 }
 240 if (!cold) {
 241 rnd_wakeup = softint_establish(SOFTINT_CLOCK|SOFTINT_MPSAFE,
 242 rnd_wake, NULL);
 243 }
 244 rnd_wakeup_readers();
 245}
 246
 247/*
 248 * Tell any sources with "feed me" callbacks that we are hungry.
 249 */
 250static void
 251rnd_getmore(size_t byteswanted)
 252{
 253 krndsource_t *rs;
 254
 255 KASSERT(mutex_owned(&rndpool_mtx));
 256
 257 LIST_FOREACH(rs, &rnd_sources, list) {
 258 if (rs->flags & RND_FLAG_HASCB) {
 259 KASSERT(rs->get != NULL);
 260 KASSERT(rs->getarg != NULL);
 261 rs->get((size_t)byteswanted, rs->getarg);
 262#ifdef RND_VERBOSE
 263 printf("rnd: asking source %s for %d bytes\n",
 264 rs->name, (int)byteswanted);
 265#endif
 266 }
 267 }
 268}
 269
 270/*
199 * Check to see if there are readers waiting on us. If so, kick them. 271 * Check to see if there are readers waiting on us. If so, kick them.
200 */ 272 */
201void 273void
202rnd_wakeup_readers(void) 274rnd_wakeup_readers(void)
203{ 275{
204 rndsink_t *sink, *tsink; 276 rndsink_t *sink, *tsink;
 277 size_t entropy_count;
205 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk); 278 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk);
206 279
207 mutex_spin_enter(&rndpool_mtx); 280 mutex_spin_enter(&rndpool_mtx);
208 if (rndpool_get_entropy_count(&rnd_pool) < RND_ENTROPY_THRESHOLD * 8) { 281 entropy_count = rndpool_get_entropy_count(&rnd_pool);
 282 if (entropy_count < RND_ENTROPY_THRESHOLD * 8) {
 283 rnd_empty = 1;
209 mutex_spin_exit(&rndpool_mtx); 284 mutex_spin_exit(&rndpool_mtx);
210 return; 285 return;
 286 } else {
 287#ifdef RND_VERBOSE
 288 if (__predict_false(!rnd_initial_entropy)) {
 289 printf("rnd: have initial entropy (%u)\n",
 290 (unsigned int)entropy_count);
 291 }
 292#endif
 293 rnd_empty = 0;
 294 rnd_initial_entropy = 1;
211 } 295 }
212 296
213 /* 297 /*
214 * First, take care of in-kernel consumers needing rekeying. 298 * First, take care of consumers needing rekeying.
215 */ 299 */
216 mutex_spin_enter(&rndsink_mtx); 300 mutex_spin_enter(&rndsink_mtx);
217 TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) { 301 TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) {
218 if (!mutex_tryenter(&sink->mtx)) { 302 if (!mutex_tryenter(&sink->mtx)) {
219#ifdef RND_VERBOSE 303#ifdef RND_VERBOSE
220 printf("rnd_wakeup_readers: " 304 printf("rnd_wakeup_readers: "
221 "skipping busy rndsink\n"); 305 "skipping busy rndsink\n");
222#endif 306#endif
223 continue; 307 continue;
224 } 308 }
225 309
226 KASSERT(RSTATE_PENDING == sink->state); 310 KASSERT(RSTATE_PENDING == sink->state);
227  311
228 if ((sink->len + RND_ENTROPY_THRESHOLD) * 8 < 312 if (sink->len * 8 < rndpool_get_entropy_count(&rnd_pool)) {
229 rndpool_get_entropy_count(&rnd_pool)) { 
230 /* We have enough entropy to sink some here. */ 313 /* We have enough entropy to sink some here. */
231 if (rndpool_extract_data(&rnd_pool, sink->data, 314 if (rndpool_extract_data(&rnd_pool, sink->data,
232 sink->len, RND_EXTRACT_GOOD) 315 sink->len, RND_EXTRACT_GOOD)
233 != sink->len) { 316 != sink->len) {
234 panic("could not extract estimated " 317 panic("could not extract estimated "
235 "entropy from pool"); 318 "entropy from pool");
236 } 319 }
237 sink->state = RSTATE_HASBITS; 320 sink->state = RSTATE_HASBITS;
238 /* Move this sink to the list of pending callbacks */ 321 /* Move this sink to the list of pending callbacks */
239 TAILQ_REMOVE(&rnd_sinks, sink, tailq); 322 TAILQ_REMOVE(&rnd_sinks, sink, tailq);
240 TAILQ_INSERT_HEAD(&sunk, sink, tailq); 323 TAILQ_INSERT_HEAD(&sunk, sink, tailq);
241 } else { 324 } else {
242 mutex_exit(&sink->mtx); 
243 } 
244 } 
245 mutex_spin_exit(&rndsink_mtx); 
246  
247 /* 
248 * If we still have enough new bits to do something, feed userspace. 
249 */ 
250 if (rndpool_get_entropy_count(&rnd_pool) > RND_ENTROPY_THRESHOLD * 8) { 
251#ifdef RND_VERBOSE 325#ifdef RND_VERBOSE
252 if (!rnd_initial_entropy) 326 printf("sink wants %d, we have %d, asking for more\n",
253 printf("rnd: have initial entropy (%u)\n", 327 (int)sink->len * 8,
254 rndpool_get_entropy_count(&rnd_pool)); 328 (int)rndpool_get_entropy_count(&rnd_pool));
255#endif 329#endif
256 rnd_initial_entropy = 1; 330 mutex_spin_exit(&sink->mtx);
257 mutex_spin_exit(&rndpool_mtx); 331 rnd_getmore(sink->len * 8);
258 } else { 332 }
259 mutex_spin_exit(&rndpool_mtx); 
260 } 333 }
 334 mutex_spin_exit(&rndsink_mtx);
 335 mutex_spin_exit(&rndpool_mtx);
261 336
262 /* 337 /*
263 * Now that we have dropped the mutex, we can run sinks' callbacks. 338 * Now that we have dropped the mutexes, we can run sinks' callbacks.
264 * Since we have reused the "tailq" member of the sink structure for 339 * Since we have reused the "tailq" member of the sink structure for
265 * this temporary on-stack queue, the callback must NEVER re-add 340 * this temporary on-stack queue, the callback must NEVER re-add
266 * the sink to the main queue, or our on-stack queue will become 341 * the sink to the main queue, or our on-stack queue will become
267 * corrupt. 342 * corrupt.
268 */ 343 */
269 while ((sink = TAILQ_FIRST(&sunk))) { 344 while ((sink = TAILQ_FIRST(&sunk))) {
270#ifdef RND_VERBOSE 345#ifdef RND_VERBOSE
271 printf("supplying %d bytes to entropy sink \"%s\"" 346 printf("supplying %d bytes to entropy sink \"%s\""
272 " (cb %p, arg %p).\n", 347 " (cb %p, arg %p).\n",
273 (int)sink->len, sink->name, sink->cb, sink->arg); 348 (int)sink->len, sink->name, sink->cb, sink->arg);
274#endif 349#endif
275 sink->state = RSTATE_HASBITS; 350 sink->state = RSTATE_HASBITS;
276 sink->cb(sink->arg); 351 sink->cb(sink->arg);
@@ -368,29 +443,27 @@ rnd_skew(void *arg) @@ -368,29 +443,27 @@ rnd_skew(void *arg)
368 * rnd_init() must be called very early on in the boot process, so 443 * rnd_init() must be called very early on in the boot process, so
369 * the pool is ready for other devices to attach as sources. 444 * the pool is ready for other devices to attach as sources.
370 */ 445 */
371void 446void
372rnd_init(void) 447rnd_init(void)
373{ 448{
374 u_int32_t c; 449 u_int32_t c;
375 450
376 if (rnd_ready) 451 if (rnd_ready)
377 return; 452 return;
378 453
379 mutex_init(&rnd_mtx, MUTEX_DEFAULT, IPL_VM); 454 mutex_init(&rnd_mtx, MUTEX_DEFAULT, IPL_VM);
380 mutex_init(&rndsink_mtx, MUTEX_DEFAULT, IPL_VM); 455 mutex_init(&rndsink_mtx, MUTEX_DEFAULT, IPL_VM);
381 456 mutex_init(&rndsoft_mtx, MUTEX_DEFAULT, IPL_VM);
382 callout_init(&rnd_callout, CALLOUT_MPSAFE); 
383 callout_setfunc(&rnd_callout, rnd_timeout, NULL); 
384 457
385 /* 458 /*
386 * take a counter early, hoping that there's some variance in 459 * take a counter early, hoping that there's some variance in
387 * the following operations 460 * the following operations
388 */ 461 */
389 c = rnd_counter(); 462 c = rnd_counter();
390 463
391 LIST_INIT(&rnd_sources); 464 LIST_INIT(&rnd_sources);
392 SIMPLEQ_INIT(&rnd_samples); 465 SIMPLEQ_INIT(&rnd_samples);
393 TAILQ_INIT(&rnd_sinks); 466 TAILQ_INIT(&rnd_sinks);
394 467
395 rndpool_init(&rnd_pool); 468 rndpool_init(&rnd_pool);
396 mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM); 469 mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM);
@@ -747,46 +820,30 @@ rnd_add_data_ts(krndsource_t *rs, const  @@ -747,46 +820,30 @@ rnd_add_data_ts(krndsource_t *rs, const
747 820
748 /* 821 /*
749 * If we didn't finish any sample buffers, we're done. 822 * If we didn't finish any sample buffers, we're done.
750 */ 823 */
751 if (!filled) { 824 if (!filled) {
752 return; 825 return;
753 } 826 }
754 827
755 mutex_spin_enter(&rnd_mtx); 828 mutex_spin_enter(&rnd_mtx);
756 while ((state = SIMPLEQ_FIRST(&tmp_samples))) { 829 while ((state = SIMPLEQ_FIRST(&tmp_samples))) {
757 SIMPLEQ_REMOVE_HEAD(&tmp_samples, next); 830 SIMPLEQ_REMOVE_HEAD(&tmp_samples, next);
758 SIMPLEQ_INSERT_HEAD(&rnd_samples, state, next); 831 SIMPLEQ_INSERT_HEAD(&rnd_samples, state, next);
759 } 832 }
760 
761 /* 
762 * If we are still starting up, cause immediate processing of 
763 * the queued samples. Otherwise, if the timeout isn't 
764 * pending, have it run in the near future. 
765 */ 
766 if (__predict_false(cold)) { 
767#ifdef RND_VERBOSE 
768 printf("rnd: directly processing boot-time events.\n"); 
769#endif 
770 rnd_process_events(NULL); /* Drops lock! */ 
771 return; 
772 } 
773 if (rnd_timeout_pending == 0) { 
774 rnd_timeout_pending = 1; 
775 mutex_spin_exit(&rnd_mtx); 
776 callout_schedule(&rnd_callout, 1); 
777 return; 
778 } 
779 mutex_spin_exit(&rnd_mtx); 833 mutex_spin_exit(&rnd_mtx);
 834
 835 /* Cause processing of queued samples */
 836 rnd_schedule_process();
780} 837}
781 838
782static int 839static int
783rnd_hwrng_test(rnd_sample_t *sample) 840rnd_hwrng_test(rnd_sample_t *sample)
784{ 841{
785 krndsource_t *source = sample->source; 842 krndsource_t *source = sample->source;
786 size_t cmplen; 843 size_t cmplen;
787 uint8_t *v1, *v2; 844 uint8_t *v1, *v2;
788 size_t resid, totest; 845 size_t resid, totest;
789 846
790 KASSERT(source->type == RND_TYPE_RNG); 847 KASSERT(source->type == RND_TYPE_RNG);
791 848
792 /* 849 /*
@@ -827,69 +884,97 @@ rnd_hwrng_test(rnd_sample_t *sample) @@ -827,69 +884,97 @@ rnd_hwrng_test(rnd_sample_t *sample)
827 return 1; 884 return 1;
828 } 885 }
829 source->test_cnt = -1; 886 source->test_cnt = -1;
830 memset(source->test, 0, sizeof(*source->test)); 887 memset(source->test, 0, sizeof(*source->test));
831 } 888 }
832 return 0; 889 return 0;
833} 890}
834 891
835/* 892/*
836 * Process the events in the ring buffer. Called by rnd_timeout or 893 * Process the events in the ring buffer. Called by rnd_timeout or
837 * by the add routines directly if the callout has never fired (that 894 * by the add routines directly if the callout has never fired (that
838 * is, if we are "cold" -- just booted). 895 * is, if we are "cold" -- just booted).
839 * 896 *
840 * Call with rnd_mtx held -- WILL RELEASE IT. 
841 */ 897 */
842static void 898static void
843rnd_process_events(void *arg) 899rnd_process_events(void)
844{ 900{
845 rnd_sample_t *sample; 901 rnd_sample_t *sample = NULL;
846 krndsource_t *source, *badsource = NULL; 902 krndsource_t *source, *badsource = NULL;
 903 static krndsource_t *last_source;
847 u_int32_t entropy; 904 u_int32_t entropy;
 905 size_t pool_entropy;
 906 int found = 0, wake = 0;
848 SIMPLEQ_HEAD(, _rnd_sample_t) dq_samples = 907 SIMPLEQ_HEAD(, _rnd_sample_t) dq_samples =
849 SIMPLEQ_HEAD_INITIALIZER(dq_samples); 908 SIMPLEQ_HEAD_INITIALIZER(dq_samples);
850 SIMPLEQ_HEAD(, _rnd_sample_t) df_samples = 909 SIMPLEQ_HEAD(, _rnd_sample_t) df_samples =
851 SIMPLEQ_HEAD_INITIALIZER(df_samples); 910 SIMPLEQ_HEAD_INITIALIZER(df_samples);
852 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk); 911 TAILQ_HEAD(, rndsink) sunk = TAILQ_HEAD_INITIALIZER(sunk);
853 912
854 /* 913 /*
855 * Sample queue is protected by rnd_mtx, drain to onstack queue 914 * Sample queue is protected by rnd_mtx, drain to onstack queue
856 * and drop lock. 915 * and drop lock.
857 */ 916 */
858 917
 918 mutex_spin_enter(&rnd_mtx);
859 while ((sample = SIMPLEQ_FIRST(&rnd_samples))) { 919 while ((sample = SIMPLEQ_FIRST(&rnd_samples))) {
 920 found++;
860 SIMPLEQ_REMOVE_HEAD(&rnd_samples, next); 921 SIMPLEQ_REMOVE_HEAD(&rnd_samples, next);
861 /* 922 /*
862 * We repeat this check here, since it is possible 923 * We repeat this check here, since it is possible
863 * the source was disabled before we were called, but 924 * the source was disabled before we were called, but
864 * after the entry was queued. 925 * after the entry was queued.
865 */ 926 */
866 if (__predict_false(sample->source->flags 927 if (__predict_false(sample->source->flags
867 & RND_FLAG_NO_COLLECT)) { 928 & RND_FLAG_NO_COLLECT)) {
868 SIMPLEQ_INSERT_TAIL(&df_samples, sample, next); 929 SIMPLEQ_INSERT_TAIL(&df_samples, sample, next);
869 } else { 930 } else {
870 SIMPLEQ_INSERT_TAIL(&dq_samples, sample, next); 931 SIMPLEQ_INSERT_TAIL(&dq_samples, sample, next);
871 } 932 }
872 } 933 }
873 mutex_spin_exit(&rnd_mtx); 934 mutex_spin_exit(&rnd_mtx);
874 935
875 /* Don't thrash the rndpool mtx either. Hold, add all samples. */ 936 /* Don't thrash the rndpool mtx either. Hold, add all samples. */
876 mutex_spin_enter(&rndpool_mtx); 937 mutex_spin_enter(&rndpool_mtx);
 938
 939 pool_entropy = rndpool_get_entropy_count(&rnd_pool);
 940 if (pool_entropy > RND_ENTROPY_THRESHOLD * 8) {
 941 wake++;
 942 } else {
 943 rnd_empty = 1;
 944 rnd_getmore((RND_POOLBITS - pool_entropy) / 8);
 945#ifdef RND_VERBOSE
 946 printf("rnd: empty, asking for %d bits\n",
 947 (int)((RND_POOLBITS - pool_entropy) / 8));
 948#endif
 949 }
 950
877 while ((sample = SIMPLEQ_FIRST(&dq_samples))) { 951 while ((sample = SIMPLEQ_FIRST(&dq_samples))) {
878 SIMPLEQ_REMOVE_HEAD(&dq_samples, next); 952 SIMPLEQ_REMOVE_HEAD(&dq_samples, next);
879 source = sample->source; 953 source = sample->source;
880 entropy = sample->entropy; 954 entropy = sample->entropy;
881 955
882 /* 956 /*
 957 * Don't provide a side channel for timing attacks on
 958 * low-rate sources: require mixing with some other
 959 * source before we schedule a wakeup.
 960 */
 961 if (!wake &&
 962 (source != last_source || source->flags & RND_FLAG_FAST)) {
 963 wake++;
 964 }
 965 last_source = source;
 966
 967 /*
883 * Hardware generators are great but sometimes they 968 * Hardware generators are great but sometimes they
884 * have...hardware issues. Don't use any data from 969 * have...hardware issues. Don't use any data from
885 * them unless it passes some tests. 970 * them unless it passes some tests.
886 */ 971 */
887 if (source->type == RND_TYPE_RNG) { 972 if (source->type == RND_TYPE_RNG) {
888 if (__predict_false(rnd_hwrng_test(sample))) { 973 if (__predict_false(rnd_hwrng_test(sample))) {
889 /* 974 /*
890 * Detach the bad source. See below. 975 * Detach the bad source. See below.
891 */ 976 */
892 badsource = source; 977 badsource = source;
893 printf("rnd: detaching source \"%s\".", 978 printf("rnd: detaching source \"%s\".",
894 badsource->name); 979 badsource->name);
895 break; 980 break;
@@ -915,72 +1000,75 @@ rnd_process_events(void *arg) @@ -915,72 +1000,75 @@ rnd_process_events(void *arg)
915 * point at which we detected a problem onwards. 1000 * point at which we detected a problem onwards.
916 */ 1001 */
917 rnd_detach_source(badsource); 1002 rnd_detach_source(badsource);
918 while ((sample = SIMPLEQ_FIRST(&dq_samples))) { 1003 while ((sample = SIMPLEQ_FIRST(&dq_samples))) {
919 SIMPLEQ_REMOVE_HEAD(&dq_samples, next); 1004 SIMPLEQ_REMOVE_HEAD(&dq_samples, next);
920 rnd_sample_free(sample); 1005 rnd_sample_free(sample);
921 } 1006 }
922 } 1007 }
923 while ((sample = SIMPLEQ_FIRST(&df_samples))) { 1008 while ((sample = SIMPLEQ_FIRST(&df_samples))) {
924 SIMPLEQ_REMOVE_HEAD(&df_samples, next); 1009 SIMPLEQ_REMOVE_HEAD(&df_samples, next);
925 rnd_sample_free(sample); 1010 rnd_sample_free(sample);
926 } 1011 }
927 1012
 1013
928 /* 1014 /*
929 * Wake up any potential readers waiting. 1015 * Wake up any potential readers waiting.
930 */ 1016 */
931 rnd_wakeup_readers(); 1017 if (wake) {
 1018 rnd_schedule_wakeup();
 1019 }
932} 1020}
933 1021
934/* 
935 * Timeout, run to process the events in the ring buffer. 
936 */ 
937static void 1022static void
938rnd_timeout(void *arg) 1023rnd_intr(void *arg)
939{ 1024{
940 mutex_spin_enter(&rnd_mtx); 1025 rnd_process_events();
941 rnd_timeout_pending = 0; 1026}
942 rnd_process_events(arg); 1027
 1028static void
 1029rnd_wake(void *arg)
 1030{
 1031 rnd_wakeup_readers();
943} 1032}
944 1033
945u_int32_t 1034u_int32_t
946rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags) 1035rnd_extract_data_locked(void *p, u_int32_t len, u_int32_t flags)
947{ 1036{
948 static int timed_in; 1037 static int timed_in;
 1038 int entropy_count;
949 1039
950 KASSERT(mutex_owned(&rndpool_mtx)); 1040 KASSERT(mutex_owned(&rndpool_mtx));
951 if (__predict_false(!timed_in)) { 1041 if (__predict_false(!timed_in)) {
952 if (boottime.tv_sec) { 1042 if (boottime.tv_sec) {
953 rndpool_add_data(&rnd_pool, &boottime, 1043 rndpool_add_data(&rnd_pool, &boottime,
954 sizeof(boottime), 0); 1044 sizeof(boottime), 0);
955 } 1045 }
956 timed_in++; 1046 timed_in++;
957 } 1047 }
958 if (__predict_false(!rnd_initial_entropy)) { 1048 if (__predict_false(!rnd_initial_entropy)) {
959 u_int32_t c; 1049 u_int32_t c;
960 1050
961#ifdef RND_VERBOSE 1051#ifdef RND_VERBOSE
962 printf("rnd: WARNING! initial entropy low (%u).\n", 1052 printf("rnd: WARNING! initial entropy low (%u).\n",
963 rndpool_get_entropy_count(&rnd_pool)); 1053 rndpool_get_entropy_count(&rnd_pool));
964#endif 1054#endif
965 /* Try once again to put something in the pool */ 1055 /* Try once again to put something in the pool */
966 c = rnd_counter(); 1056 c = rnd_counter();
967 rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1); 1057 rndpool_add_data(&rnd_pool, &c, sizeof(u_int32_t), 1);
968 } 1058 }
969 1059
970#ifdef DIAGNOSTIC 1060#ifdef DIAGNOSTIC
971 while (!rnd_tested) { 1061 while (!rnd_tested) {
972 int entropy_count; 
973 
974 entropy_count = rndpool_get_entropy_count(&rnd_pool); 1062 entropy_count = rndpool_get_entropy_count(&rnd_pool);
975#ifdef RND_VERBOSE 1063#ifdef RND_VERBOSE
976 printf("rnd: starting statistical RNG test, entropy = %d.\n", 1064 printf("rnd: starting statistical RNG test, entropy = %d.\n",
977 entropy_count); 1065 entropy_count);
978#endif 1066#endif
979 if (rndpool_extract_data(&rnd_pool, rnd_rt.rt_b, 1067 if (rndpool_extract_data(&rnd_pool, rnd_rt.rt_b,
980 sizeof(rnd_rt.rt_b), RND_EXTRACT_ANY) 1068 sizeof(rnd_rt.rt_b), RND_EXTRACT_ANY)
981 != sizeof(rnd_rt.rt_b)) { 1069 != sizeof(rnd_rt.rt_b)) {
982 panic("rnd: could not get bits for statistical test"); 1070 panic("rnd: could not get bits for statistical test");
983 } 1071 }
984 /* 1072 /*
985 * Stash the tested bits so we can put them back in the 1073 * Stash the tested bits so we can put them back in the
986 * pool, restoring the entropy count. DO NOT rely on 1074 * pool, restoring the entropy count. DO NOT rely on
@@ -1002,26 +1090,30 @@ rnd_extract_data_locked(void *p, u_int32 @@ -1002,26 +1090,30 @@ rnd_extract_data_locked(void *p, u_int32
1002 continue; 1090 continue;
1003 } 1091 }
1004 memset(&rnd_rt, 0, sizeof(rnd_rt)); 1092 memset(&rnd_rt, 0, sizeof(rnd_rt));
1005 rndpool_add_data(&rnd_pool, rnd_testbits, sizeof(rnd_testbits), 1093 rndpool_add_data(&rnd_pool, rnd_testbits, sizeof(rnd_testbits),
1006 entropy_count); 1094 entropy_count);
1007 memset(rnd_testbits, 0, sizeof(rnd_testbits)); 1095 memset(rnd_testbits, 0, sizeof(rnd_testbits));
1008#ifdef RND_VERBOSE 1096#ifdef RND_VERBOSE
1009 printf("rnd: statistical RNG test done, entropy = %d.\n", 1097 printf("rnd: statistical RNG test done, entropy = %d.\n",
1010 rndpool_get_entropy_count(&rnd_pool)); 1098 rndpool_get_entropy_count(&rnd_pool));
1011#endif 1099#endif
1012 rnd_tested++; 1100 rnd_tested++;
1013 } 1101 }
1014#endif 1102#endif
 1103 entropy_count = rndpool_get_entropy_count(&rnd_pool);
 1104 if (entropy_count < (RND_ENTROPY_THRESHOLD * 2 + len) * 8) {
 1105 rnd_getmore(RND_POOLBITS - entropy_count * 8);
 1106 }
1015 return rndpool_extract_data(&rnd_pool, p, len, flags); 1107 return rndpool_extract_data(&rnd_pool, p, len, flags);
1016} 1108}
1017 1109
1018u_int32_t 1110u_int32_t
1019rnd_extract_data(void *p, u_int32_t len, u_int32_t flags) 1111rnd_extract_data(void *p, u_int32_t len, u_int32_t flags)
1020{ 1112{
1021 uint32_t retval; 1113 uint32_t retval;
1022 1114
1023 mutex_spin_enter(&rndpool_mtx); 1115 mutex_spin_enter(&rndpool_mtx);
1024 retval = rnd_extract_data_locked(p, len, flags); 1116 retval = rnd_extract_data_locked(p, len, flags);
1025 mutex_spin_exit(&rndpool_mtx); 1117 mutex_spin_exit(&rndpool_mtx);
1026 return retval; 1118 return retval;
1027} 1119}
@@ -1031,33 +1123,27 @@ rndsink_attach(rndsink_t *rs) @@ -1031,33 +1123,27 @@ rndsink_attach(rndsink_t *rs)
1031{ 1123{
1032#ifdef RND_VERBOSE 1124#ifdef RND_VERBOSE
1033 printf("rnd: entropy sink \"%s\" wants %d bytes of data.\n", 1125 printf("rnd: entropy sink \"%s\" wants %d bytes of data.\n",
1034 rs->name, (int)rs->len); 1126 rs->name, (int)rs->len);
1035#endif 1127#endif
1036 1128
1037 KASSERT(mutex_owned(&rs->mtx)); 1129 KASSERT(mutex_owned(&rs->mtx));
1038 KASSERT(rs->state = RSTATE_PENDING); 1130 KASSERT(rs->state = RSTATE_PENDING);
1039 1131
1040 mutex_spin_enter(&rndsink_mtx); 1132 mutex_spin_enter(&rndsink_mtx);
1041 TAILQ_INSERT_TAIL(&rnd_sinks, rs, tailq); 1133 TAILQ_INSERT_TAIL(&rnd_sinks, rs, tailq);
1042 mutex_spin_exit(&rndsink_mtx); 1134 mutex_spin_exit(&rndsink_mtx);
1043 1135
1044 mutex_spin_enter(&rnd_mtx); 1136 rnd_schedule_process();
1045 if (rnd_timeout_pending == 0) { 
1046 rnd_timeout_pending = 1; 
1047 callout_schedule(&rnd_callout, 1); 
1048 } 
1049 mutex_spin_exit(&rnd_mtx); 
1050 
1051} 1137}
1052 1138
1053void 1139void
1054rndsink_detach(rndsink_t *rs) 1140rndsink_detach(rndsink_t *rs)
1055{ 1141{
1056 rndsink_t *sink, *tsink; 1142 rndsink_t *sink, *tsink;
1057#ifdef RND_VERBOSE 1143#ifdef RND_VERBOSE
1058 printf("rnd: entropy sink \"%s\" no longer wants data.\n", rs->name); 1144 printf("rnd: entropy sink \"%s\" no longer wants data.\n", rs->name);
1059#endif 1145#endif
1060 KASSERT(mutex_owned(&rs->mtx)); 1146 KASSERT(mutex_owned(&rs->mtx));
1061 1147
1062 mutex_spin_enter(&rndsink_mtx); 1148 mutex_spin_enter(&rndsink_mtx);
1063 TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) { 1149 TAILQ_FOREACH_SAFE(sink, &rnd_sinks, tailq, tsink) {

cvs diff -r1.16 -r1.17 src/sys/kern/subr_cprng.c (expand / switch to unified diff)

--- src/sys/kern/subr_cprng.c 2013/03/28 18:06:48 1.16
+++ src/sys/kern/subr_cprng.c 2013/06/13 00:55:01 1.17
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: subr_cprng.c,v 1.16 2013/03/28 18:06:48 tls Exp $ */ 1/* $NetBSD: subr_cprng.c,v 1.17 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc. 4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Thor Lancelot Simon. 8 * by Thor Lancelot Simon.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -36,27 +36,27 @@ @@ -36,27 +36,27 @@
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kmem.h> 37#include <sys/kmem.h>
38#include <sys/mutex.h> 38#include <sys/mutex.h>
39#include <sys/rngtest.h> 39#include <sys/rngtest.h>
40#include <sys/rnd.h> 40#include <sys/rnd.h>
41#include <dev/rnd_private.h> 41#include <dev/rnd_private.h>
42 42
43#if defined(__HAVE_CPU_COUNTER) 43#if defined(__HAVE_CPU_COUNTER)
44#include <machine/cpu_counter.h> 44#include <machine/cpu_counter.h>
45#endif 45#endif
46 46
47#include <sys/cprng.h> 47#include <sys/cprng.h>
48 48
49__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.16 2013/03/28 18:06:48 tls Exp $"); 49__KERNEL_RCSID(0, "$NetBSD: subr_cprng.c,v 1.17 2013/06/13 00:55:01 tls Exp $");
50 50
51void 51void
52cprng_init(void) 52cprng_init(void)
53{ 53{
54 nist_ctr_initialize(); 54 nist_ctr_initialize();
55} 55}
56 56
57static inline uint32_t 57static inline uint32_t
58cprng_counter(void) 58cprng_counter(void)
59{ 59{
60 struct timeval tv; 60 struct timeval tv;
61 61
62#if defined(__HAVE_CPU_COUNTER) 62#if defined(__HAVE_CPU_COUNTER)
@@ -190,28 +190,37 @@ cprng_strong_create(const char *const na @@ -190,28 +190,37 @@ cprng_strong_create(const char *const na
190 190
191 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl); 191 mutex_init(&c->mtx, MUTEX_DEFAULT, ipl);
192 192
193 if (c->flags & CPRNG_USE_CV) { 193 if (c->flags & CPRNG_USE_CV) {
194 cv_init(&c->cv, (const char *)c->name); 194 cv_init(&c->cv, (const char *)c->name);
195 } 195 }
196 196
197 selinit(&c->selq); 197 selinit(&c->selq);
198 198
199 r = cprng_entropy_try(key, sizeof(key)); 199 r = cprng_entropy_try(key, sizeof(key));
200 if (r != sizeof(key)) { 200 if (r != sizeof(key)) {
201 if (c->flags & CPRNG_INIT_ANY) { 201 if (c->flags & CPRNG_INIT_ANY) {
202#ifdef DEBUG 202#ifdef DEBUG
203 printf("cprng %s: WARNING insufficient " 203 /*
204 "entropy at creation.\n", name); 204 * If we have ever crossed the pool's
 205 * minimum-entropy threshold, then we are
 206 * providing cryptographically strong
 207 * random output -- if not information-
 208 * theoretically strong. Warn elsewise.
 209 */
 210 if (!rnd_initial_entropy) {
 211 printf("cprng %s: WARNING insufficient "
 212 "entropy at creation.\n", name);
 213 }
205#endif 214#endif
206 } else { 215 } else {
207 hard++; 216 hard++;
208 } 217 }
209 getmore++; 218 getmore++;
210 } 219 }
211  220
212 if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key), 221 if (nist_ctr_drbg_instantiate(&c->drbg, key, sizeof(key),
213 &cc, sizeof(cc), name, strlen(name))) { 222 &cc, sizeof(cc), name, strlen(name))) {
214 panic("cprng %s: instantiation failed.", name); 223 panic("cprng %s: instantiation failed.", name);
215 } 224 }
216 225
217 if (getmore) { 226 if (getmore) {

cvs diff -r1.35 -r1.36 src/sys/sys/rnd.h (expand / switch to unified diff)

--- src/sys/sys/rnd.h 2013/01/26 19:05:11 1.35
+++ src/sys/sys/rnd.h 2013/06/13 00:55:01 1.36
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: rnd.h,v 1.35 2013/01/26 19:05:11 tls Exp $ */ 1/* $NetBSD: rnd.h,v 1.36 2013/06/13 00:55:01 tls Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Michael Graff <explorer@flame.org>. This code uses ideas and 8 * by Michael Graff <explorer@flame.org>. This code uses ideas and
9 * algorithms from the Linux driver written by Ted Ts'o. 9 * algorithms from the Linux driver written by Ted Ts'o.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -82,26 +82,27 @@ typedef struct @@ -82,26 +82,27 @@ typedef struct
82typedef struct { 82typedef struct {
83 char name[16]; /* device name */ 83 char name[16]; /* device name */
84 uint32_t total; /* entropy from this source */ 84 uint32_t total; /* entropy from this source */
85 uint32_t type; /* type */ 85 uint32_t type; /* type */
86 uint32_t flags; /* flags */ 86 uint32_t flags; /* flags */
87} rndsource_t; 87} rndsource_t;
88 88
89/* 89/*
90 * Flags to control the source. Low byte is type, upper bits are flags. 90 * Flags to control the source. Low byte is type, upper bits are flags.
91 */ 91 */
92#define RND_FLAG_NO_ESTIMATE 0x00000100 /* don't estimate entropy */ 92#define RND_FLAG_NO_ESTIMATE 0x00000100 /* don't estimate entropy */
93#define RND_FLAG_NO_COLLECT 0x00000200 /* don't collect entropy */ 93#define RND_FLAG_NO_COLLECT 0x00000200 /* don't collect entropy */
94#define RND_FLAG_FAST 0x00000400 /* process samples in bulk */ 94#define RND_FLAG_FAST 0x00000400 /* process samples in bulk */
 95#define RND_FLAG_HASCB 0x00000800 /* has get callback */
95 96
96#define RND_TYPE_UNKNOWN 0 /* unknown source */ 97#define RND_TYPE_UNKNOWN 0 /* unknown source */
97#define RND_TYPE_DISK 1 /* source is physical disk */ 98#define RND_TYPE_DISK 1 /* source is physical disk */
98#define RND_TYPE_NET 2 /* source is a network device */ 99#define RND_TYPE_NET 2 /* source is a network device */
99#define RND_TYPE_TAPE 3 /* source is a tape drive */ 100#define RND_TYPE_TAPE 3 /* source is a tape drive */
100#define RND_TYPE_TTY 4 /* source is a tty device */ 101#define RND_TYPE_TTY 4 /* source is a tty device */
101#define RND_TYPE_RNG 5 /* source is a hardware RNG */ 102#define RND_TYPE_RNG 5 /* source is a hardware RNG */
102#define RND_TYPE_SKEW 6 /* source is skew between clocks */ 103#define RND_TYPE_SKEW 6 /* source is skew between clocks */
103#define RND_TYPE_ENV 7 /* source is temp or fan sensor */ 104#define RND_TYPE_ENV 7 /* source is temp or fan sensor */
104#define RND_TYPE_VM 8 /* source is VM system events */ 105#define RND_TYPE_VM 8 /* source is VM system events */
105#define RND_TYPE_POWER 9 /* source is power events */ 106#define RND_TYPE_POWER 9 /* source is power events */
106#define RND_TYPE_MAX 9 /* last type id used */ 107#define RND_TYPE_MAX 9 /* last type id used */
107 108
@@ -117,28 +118,37 @@ typedef struct { @@ -117,28 +118,37 @@ typedef struct {
117 118
118typedef struct krndsource { 119typedef struct krndsource {
119 LIST_ENTRY(krndsource) list; /* the linked list */ 120 LIST_ENTRY(krndsource) list; /* the linked list */
120 char name[16]; /* device name */ 121 char name[16]; /* device name */
121 uint32_t last_time; /* last time recorded */ 122 uint32_t last_time; /* last time recorded */
122 uint32_t last_delta; /* last delta value */ 123 uint32_t last_delta; /* last delta value */
123 uint32_t last_delta2; /* last delta2 value */ 124 uint32_t last_delta2; /* last delta2 value */
124 uint32_t total; /* entropy from this source */ 125 uint32_t total; /* entropy from this source */
125 uint32_t type; /* type */ 126 uint32_t type; /* type */
126 uint32_t flags; /* flags */ 127 uint32_t flags; /* flags */
127 void *state; /* state information */ 128 void *state; /* state information */
128 size_t test_cnt; /* how much test data accumulated? */ 129 size_t test_cnt; /* how much test data accumulated? */
129 rngtest_t *test; /* test data for RNG type sources */ 130 rngtest_t *test; /* test data for RNG type sources */
 131 void (*get)(size_t, void *); /* pool wants N bytes (badly) */
 132 void *getarg; /* argument to get-function */
130} krndsource_t; 133} krndsource_t;
131 134
 135static inline void
 136rndsource_setcb(struct krndsource *const rs, void *const cb, void *const arg)
 137{
 138 rs->get = cb;
 139 rs->getarg = arg;
 140}
 141
132enum rsink_st { 142enum rsink_st {
133 RSTATE_IDLE = 0, 143 RSTATE_IDLE = 0,
134 RSTATE_PENDING, 144 RSTATE_PENDING,
135 RSTATE_HASBITS 145 RSTATE_HASBITS
136}; 146};
137 147
138typedef struct rndsink { 148typedef struct rndsink {
139 TAILQ_ENTRY(rndsink) tailq; /* the queue */ 149 TAILQ_ENTRY(rndsink) tailq; /* the queue */
140 kmutex_t mtx; /* lock to seed or unregister */ 150 kmutex_t mtx; /* lock to seed or unregister */
141 enum rsink_st state; /* in-use? filled? */ 151 enum rsink_st state; /* in-use? filled? */
142 void (*cb)(void *); /* callback function when ready */ 152 void (*cb)(void *); /* callback function when ready */
143 void *arg; /* callback function argument */ 153 void *arg; /* callback function argument */
144 char name[16]; /* sink name */ 154 char name[16]; /* sink name */
@@ -176,26 +186,27 @@ void rnd_detach_source(krndsource_t *); @@ -176,26 +186,27 @@ void rnd_detach_source(krndsource_t *);
176void rndsink_attach(rndsink_t *); 186void rndsink_attach(rndsink_t *);
177void rndsink_detach(rndsink_t *); 187void rndsink_detach(rndsink_t *);
178 188
179void rnd_seed(void *, size_t); 189void rnd_seed(void *, size_t);
180 190
181static inline void 191static inline void
182rnd_add_uint32(krndsource_t *kr, uint32_t val) 192rnd_add_uint32(krndsource_t *kr, uint32_t val)
183{ 193{
184 if (RND_ENABLED(kr)) { 194 if (RND_ENABLED(kr)) {
185 _rnd_add_uint32(kr, val); 195 _rnd_add_uint32(kr, val);
186 } 196 }
187} 197}
188 198
 199extern int rnd_empty;
189extern int rnd_full; 200extern int rnd_full;
190extern int rnd_filled; 201extern int rnd_filled;
191extern int rnd_initial_entropy; 202extern int rnd_initial_entropy;
192 203
193#endif /* _KERNEL */ 204#endif /* _KERNEL */
194 205
195#define RND_MAXSTATCOUNT 10 /* 10 sources at once max */ 206#define RND_MAXSTATCOUNT 10 /* 10 sources at once max */
196 207
197/* 208/*
198 * return "count" random entries, starting at "start" 209 * return "count" random entries, starting at "start"
199 */ 210 */
200typedef struct { 211typedef struct {
201 uint32_t start; 212 uint32_t start;