Wed Mar 18 15:32:28 2009 UTC ()
* allow to specify PROT_READ/PROT_WRITE when mmapping a file
* add msync


(pooka)
diff -r1.19 -r1.20 src/sys/rump/include/rump/rumpuser.h
diff -r1.36 -r1.37 src/sys/rump/librump/rumpuser/rumpuser.c
diff -r1.4 -r1.5 src/sys/rump/net/lib/libshmif/if_shmem.c

cvs diff -r1.19 -r1.20 src/sys/rump/include/rump/rumpuser.h (switch to unified diff)

--- src/sys/rump/include/rump/rumpuser.h 2009/02/28 15:49:12 1.19
+++ src/sys/rump/include/rump/rumpuser.h 2009/03/18 15:32:27 1.20
@@ -1,172 +1,177 @@ @@ -1,172 +1,177 @@
1/* $NetBSD: rumpuser.h,v 1.19 2009/02/28 15:49:12 pooka Exp $ */ 1/* $NetBSD: rumpuser.h,v 1.20 2009/03/18 15:32:27 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by Google Summer of Code. 6 * Development of this software was supported by Google Summer of Code.
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 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30#ifndef _RUMP_RUMPUSER_H_ 30#ifndef _RUMP_RUMPUSER_H_
31#define _RUMP_RUMPUSER_H_ 31#define _RUMP_RUMPUSER_H_
32 32
33#include <sys/stdint.h> 33#include <sys/stdint.h>
34 34
35struct msghdr; 35struct msghdr;
36struct pollfd; 36struct pollfd;
37struct sockaddr; 37struct sockaddr;
38 38
39typedef void (*kernel_lockfn)(int); 39typedef void (*kernel_lockfn)(int);
40typedef void (*kernel_unlockfn)(int, int *); 40typedef void (*kernel_unlockfn)(int, int *);
41 41
42int rumpuser_getfileinfo(const char *, uint64_t *, int *, int *); 42int rumpuser_getfileinfo(const char *, uint64_t *, int *, int *);
43#define RUMPUSER_FT_DIR 1 43#define RUMPUSER_FT_DIR 1
44#define RUMPUSER_FT_REG 2 44#define RUMPUSER_FT_REG 2
45#define RUMPUSER_FT_BLK 3 45#define RUMPUSER_FT_BLK 3
46#define RUMPUSER_FT_OTHER 4 46#define RUMPUSER_FT_OTHER 4
47int rumpuser_nanosleep(uint64_t *, uint64_t *, int *); 47int rumpuser_nanosleep(uint64_t *, uint64_t *, int *);
48 48
49#define rumpuser_malloc(a,b) rumpuser__malloc(a,b,__func__,__LINE__); 49#define rumpuser_malloc(a,b) rumpuser__malloc(a,b,__func__,__LINE__);
50#define rumpuser_realloc(a,b,c) rumpuser__realloc(a,b,c,__func__,__LINE__); 50#define rumpuser_realloc(a,b,c) rumpuser__realloc(a,b,c,__func__,__LINE__);
51 51
52void *rumpuser__malloc(size_t, int, const char *, int); 52void *rumpuser__malloc(size_t, int, const char *, int);
53void *rumpuser__realloc(void *, size_t, int, const char *, int); 53void *rumpuser__realloc(void *, size_t, int, const char *, int);
54void rumpuser_free(void *); 54void rumpuser_free(void *);
55 55
56void *rumpuser_anonmmap(size_t, int, int, int *); 56void *rumpuser_anonmmap(size_t, int, int, int *);
57void *rumpuser_filemmap(int fd, off_t, size_t, int, int, int *); 57#define RUMPUSER_FILEMMAP_READ 0x01
 58#define RUMPUSER_FILEMMAP_WRITE 0x02
 59#define RUMPUSER_FILEMMAP_TRUNCATE 0x04
 60#define RUMPUSER_FILEMMAP_SHARED 0x08
 61void *rumpuser_filemmap(int fd, off_t, size_t, int, int *);
58void rumpuser_unmap(void *, size_t); 62void rumpuser_unmap(void *, size_t);
 63int rumpuser_memsync(void *, size_t, int *);
59 64
60int rumpuser_open(const char *, int, int *); 65int rumpuser_open(const char *, int, int *);
61int rumpuser_ioctl(int, u_long, void *, int *); 66int rumpuser_ioctl(int, u_long, void *, int *);
62int rumpuser_close(int, int *); 67int rumpuser_close(int, int *);
63int rumpuser_fsync(int, int *); 68int rumpuser_fsync(int, int *);
64 69
65typedef void (*rump_biodone_fn)(void *, size_t, int); 70typedef void (*rump_biodone_fn)(void *, size_t, int);
66 71
67ssize_t rumpuser_read(int, void *, size_t, int *); 72ssize_t rumpuser_read(int, void *, size_t, int *);
68ssize_t rumpuser_pread(int, void *, size_t, off_t, int *); 73ssize_t rumpuser_pread(int, void *, size_t, off_t, int *);
69ssize_t rumpuser_write(int, const void *, size_t, int *); 74ssize_t rumpuser_write(int, const void *, size_t, int *);
70ssize_t rumpuser_pwrite(int, const void *, size_t, off_t, int *); 75ssize_t rumpuser_pwrite(int, const void *, size_t, off_t, int *);
71void rumpuser_read_bio(int, void *, size_t, off_t, rump_biodone_fn, void *); 76void rumpuser_read_bio(int, void *, size_t, off_t, rump_biodone_fn, void *);
72void rumpuser_write_bio(int, const void *, size_t, off_t,rump_biodone_fn,void*); 77void rumpuser_write_bio(int, const void *, size_t, off_t,rump_biodone_fn,void*);
73 78
74struct rumpuser_iovec { 79struct rumpuser_iovec {
75 void *iov_base; 80 void *iov_base;
76 uint64_t iov_len; 81 uint64_t iov_len;
77}; 82};
78ssize_t rumpuser_readv(int, const struct rumpuser_iovec *, int, int *); 83ssize_t rumpuser_readv(int, const struct rumpuser_iovec *, int, int *);
79ssize_t rumpuser_writev(int, const struct rumpuser_iovec *, int, int *); 84ssize_t rumpuser_writev(int, const struct rumpuser_iovec *, int, int *);
80 85
81int rumpuser_gettime(uint64_t *, uint64_t *, int *); 86int rumpuser_gettime(uint64_t *, uint64_t *, int *);
82int rumpuser_getenv(const char *, char *, size_t, int *); 87int rumpuser_getenv(const char *, char *, size_t, int *);
83 88
84int rumpuser_gethostname(char *, size_t, int *); 89int rumpuser_gethostname(char *, size_t, int *);
85 90
86char *rumpuser_realpath(const char *, char *, int *); 91char *rumpuser_realpath(const char *, char *, int *);
87 92
88int rumpuser_poll(struct pollfd *, int, int, int *); 93int rumpuser_poll(struct pollfd *, int, int, int *);
89 94
90int rumpuser_putchar(int, int *); 95int rumpuser_putchar(int, int *);
91 96
92void rumpuser_panic(void); 97void rumpuser_panic(void);
93 98
94void rumpuser_seterrno(int); 99void rumpuser_seterrno(int);
95 100
96int rumpuser_writewatchfile_setup(int, int, intptr_t, int *); 101int rumpuser_writewatchfile_setup(int, int, intptr_t, int *);
97int rumpuser_writewatchfile_wait(int, intptr_t *, int *); 102int rumpuser_writewatchfile_wait(int, intptr_t *, int *);
98 103
99/* rumpuser_pth */ 104/* rumpuser_pth */
100void rumpuser_thrinit(kernel_lockfn, kernel_unlockfn, int); 105void rumpuser_thrinit(kernel_lockfn, kernel_unlockfn, int);
101int rumpuser_bioinit(rump_biodone_fn); 106int rumpuser_bioinit(rump_biodone_fn);
102 107
103int rumpuser_thread_create(void *(*f)(void *), void *, const char *); 108int rumpuser_thread_create(void *(*f)(void *), void *, const char *);
104void rumpuser_thread_exit(void); 109void rumpuser_thread_exit(void);
105 110
106struct rumpuser_mtx; 111struct rumpuser_mtx;
107 112
108void rumpuser_mutex_init(struct rumpuser_mtx **); 113void rumpuser_mutex_init(struct rumpuser_mtx **);
109void rumpuser_mutex_recursive_init(struct rumpuser_mtx **); 114void rumpuser_mutex_recursive_init(struct rumpuser_mtx **);
110void rumpuser_mutex_enter(struct rumpuser_mtx *); 115void rumpuser_mutex_enter(struct rumpuser_mtx *);
111int rumpuser_mutex_tryenter(struct rumpuser_mtx *); 116int rumpuser_mutex_tryenter(struct rumpuser_mtx *);
112void rumpuser_mutex_exit(struct rumpuser_mtx *); 117void rumpuser_mutex_exit(struct rumpuser_mtx *);
113void rumpuser_mutex_destroy(struct rumpuser_mtx *); 118void rumpuser_mutex_destroy(struct rumpuser_mtx *);
114int rumpuser_mutex_held(struct rumpuser_mtx *); 119int rumpuser_mutex_held(struct rumpuser_mtx *);
115 120
116struct rumpuser_rw; 121struct rumpuser_rw;
117 122
118void rumpuser_rw_init(struct rumpuser_rw **); 123void rumpuser_rw_init(struct rumpuser_rw **);
119void rumpuser_rw_enter(struct rumpuser_rw *, int); 124void rumpuser_rw_enter(struct rumpuser_rw *, int);
120int rumpuser_rw_tryenter(struct rumpuser_rw *, int); 125int rumpuser_rw_tryenter(struct rumpuser_rw *, int);
121void rumpuser_rw_exit(struct rumpuser_rw *); 126void rumpuser_rw_exit(struct rumpuser_rw *);
122void rumpuser_rw_destroy(struct rumpuser_rw *); 127void rumpuser_rw_destroy(struct rumpuser_rw *);
123int rumpuser_rw_held(struct rumpuser_rw *); 128int rumpuser_rw_held(struct rumpuser_rw *);
124int rumpuser_rw_rdheld(struct rumpuser_rw *); 129int rumpuser_rw_rdheld(struct rumpuser_rw *);
125int rumpuser_rw_wrheld(struct rumpuser_rw *); 130int rumpuser_rw_wrheld(struct rumpuser_rw *);
126 131
127struct rumpuser_cv; 132struct rumpuser_cv;
128 133
129void rumpuser_cv_init(struct rumpuser_cv **); 134void rumpuser_cv_init(struct rumpuser_cv **);
130void rumpuser_cv_destroy(struct rumpuser_cv *); 135void rumpuser_cv_destroy(struct rumpuser_cv *);
131void rumpuser_cv_wait(struct rumpuser_cv *, struct rumpuser_mtx *); 136void rumpuser_cv_wait(struct rumpuser_cv *, struct rumpuser_mtx *);
132int rumpuser_cv_timedwait(struct rumpuser_cv *, struct rumpuser_mtx *, 137int rumpuser_cv_timedwait(struct rumpuser_cv *, struct rumpuser_mtx *,
133 struct timespec *); 138 struct timespec *);
134void rumpuser_cv_signal(struct rumpuser_cv *); 139void rumpuser_cv_signal(struct rumpuser_cv *);
135void rumpuser_cv_broadcast(struct rumpuser_cv *); 140void rumpuser_cv_broadcast(struct rumpuser_cv *);
136int rumpuser_cv_has_waiters(struct rumpuser_cv *); 141int rumpuser_cv_has_waiters(struct rumpuser_cv *);
137 142
138struct lwp; 143struct lwp;
139 144
140void rumpuser_set_curlwp(struct lwp *); 145void rumpuser_set_curlwp(struct lwp *);
141struct lwp *rumpuser_get_curlwp(void); 146struct lwp *rumpuser_get_curlwp(void);
142 147
143/* "aio" stuff for being able to fire of a B_ASYNC I/O and continue */ 148/* "aio" stuff for being able to fire of a B_ASYNC I/O and continue */
144struct rumpuser_aio { 149struct rumpuser_aio {
145 int rua_fd; 150 int rua_fd;
146 uint8_t *rua_data; 151 uint8_t *rua_data;
147 size_t rua_dlen; 152 size_t rua_dlen;
148 off_t rua_off; 153 off_t rua_off;
149 void *rua_bp; 154 void *rua_bp;
150 int rua_op; 155 int rua_op;
151}; 156};
152 157
153#define N_AIOS 128 158#define N_AIOS 128
154extern struct rumpuser_mtx rumpuser_aio_mtx; 159extern struct rumpuser_mtx rumpuser_aio_mtx;
155extern struct rumpuser_cv rumpuser_aio_cv; 160extern struct rumpuser_cv rumpuser_aio_cv;
156extern struct rumpuser_aio rumpuser_aios[N_AIOS]; 161extern struct rumpuser_aio rumpuser_aios[N_AIOS];
157extern int rumpuser_aio_head, rumpuser_aio_tail; 162extern int rumpuser_aio_head, rumpuser_aio_tail;
158 163
159/* rumpuser_net */ 164/* rumpuser_net */
160 165
161int rumpuser_net_socket(int, int, int, int *); 166int rumpuser_net_socket(int, int, int, int *);
162int rumpuser_net_sendmsg(int, const struct msghdr *, int, int *); 167int rumpuser_net_sendmsg(int, const struct msghdr *, int, int *);
163int rumpuser_net_recvmsg(int, struct msghdr *, int, int *); 168int rumpuser_net_recvmsg(int, struct msghdr *, int, int *);
164int rumpuser_net_connect(int, const struct sockaddr *, int, int *); 169int rumpuser_net_connect(int, const struct sockaddr *, int, int *);
165int rumpuser_net_bind(int, const struct sockaddr *, int, int *); 170int rumpuser_net_bind(int, const struct sockaddr *, int, int *);
166int rumpuser_net_accept(int, struct sockaddr *, int *, int *); 171int rumpuser_net_accept(int, struct sockaddr *, int *, int *);
167int rumpuser_net_listen(int, int, int *); 172int rumpuser_net_listen(int, int, int *);
168enum rumpuser_getnametype { RUMPUSER_SOCKNAME, RUMPUSER_PEERNAME }; 173enum rumpuser_getnametype { RUMPUSER_SOCKNAME, RUMPUSER_PEERNAME };
169int rumpuser_net_getname(int, struct sockaddr *, int *, 174int rumpuser_net_getname(int, struct sockaddr *, int *,
170 enum rumpuser_getnametype, int *); 175 enum rumpuser_getnametype, int *);
171 176
172#endif /* _RUMP_RUMPUSER_H_ */ 177#endif /* _RUMP_RUMPUSER_H_ */

cvs diff -r1.36 -r1.37 src/sys/rump/librump/rumpuser/Attic/rumpuser.c (switch to unified diff)

--- src/sys/rump/librump/rumpuser/Attic/rumpuser.c 2009/03/18 10:22:45 1.36
+++ src/sys/rump/librump/rumpuser/Attic/rumpuser.c 2009/03/18 15:32:27 1.37
@@ -1,484 +1,496 @@ @@ -1,484 +1,496 @@
1/* $NetBSD: rumpuser.c,v 1.36 2009/03/18 10:22:45 cegger Exp $ */ 1/* $NetBSD: rumpuser.c,v 1.37 2009/03/18 15:32:27 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by Google Summer of Code 6 * Development of this software was supported by Google Summer of Code
7 * and the Finnish Cultural Foundation. 7 * and the Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
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
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * LIABILITY, 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#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32#if !defined(lint) 32#if !defined(lint)
33__RCSID("$NetBSD: rumpuser.c,v 1.36 2009/03/18 10:22:45 cegger Exp $"); 33__RCSID("$NetBSD: rumpuser.c,v 1.37 2009/03/18 15:32:27 pooka Exp $");
34#endif /* !lint */ 34#endif /* !lint */
35 35
36/* thank the maker for this */ 36/* thank the maker for this */
37#ifdef __linux__ 37#ifdef __linux__
38#define _XOPEN_SOURCE 500 38#define _XOPEN_SOURCE 500
39#define _BSD_SOURCE 39#define _BSD_SOURCE
40#define _FILE_OFFSET_BITS 64 40#define _FILE_OFFSET_BITS 64
41#include <features.h> 41#include <features.h>
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/event.h> 45#include <sys/event.h>
46#include <sys/ioctl.h> 46#include <sys/ioctl.h>
47#include <sys/mman.h> 47#include <sys/mman.h>
48#include <sys/uio.h> 48#include <sys/uio.h>
49 49
50#include <assert.h> 50#include <assert.h>
51#include <err.h> 51#include <err.h>
52#include <errno.h> 52#include <errno.h>
53#include <fcntl.h> 53#include <fcntl.h>
54#include <poll.h> 54#include <poll.h>
55#include <stdint.h> 55#include <stdint.h>
56#include <stdio.h> 56#include <stdio.h>
57#include <stdlib.h> 57#include <stdlib.h>
58#include <string.h> 58#include <string.h>
59#include <time.h> 59#include <time.h>
60#include <unistd.h> 60#include <unistd.h>
61 61
62#include <rump/rumpuser.h> 62#include <rump/rumpuser.h>
63 63
64#include "rumpuser_int.h" 64#include "rumpuser_int.h"
65 65
66int 66int
67rumpuser_getfileinfo(const char *path, uint64_t *size, int *ft, int *error) 67rumpuser_getfileinfo(const char *path, uint64_t *size, int *ft, int *error)
68{ 68{
69 struct stat sb; 69 struct stat sb;
70 int rv; 70 int rv;
71 71
72 rv = stat(path, &sb); 72 rv = stat(path, &sb);
73 if (rv == -1) { 73 if (rv == -1) {
74 *error = errno; 74 *error = errno;
75 return rv; 75 return rv;
76 } 76 }
77 77
78 *size = sb.st_size; 78 *size = sb.st_size;
79 switch (sb.st_mode & S_IFMT) { 79 switch (sb.st_mode & S_IFMT) {
80 case S_IFDIR: 80 case S_IFDIR:
81 *ft = RUMPUSER_FT_DIR; 81 *ft = RUMPUSER_FT_DIR;
82 break; 82 break;
83 case S_IFREG: 83 case S_IFREG:
84 *ft = RUMPUSER_FT_REG; 84 *ft = RUMPUSER_FT_REG;
85 break; 85 break;
86 case S_IFBLK: 86 case S_IFBLK:
87 *ft = RUMPUSER_FT_BLK; 87 *ft = RUMPUSER_FT_BLK;
88 break; 88 break;
89 default: 89 default:
90 *ft = RUMPUSER_FT_OTHER; 90 *ft = RUMPUSER_FT_OTHER;
91 break; 91 break;
92 } 92 }
93 93
94 return rv; 94 return rv;
95} 95}
96 96
97int 97int
98rumpuser_nanosleep(uint64_t *sec, uint64_t *nsec, int *error) 98rumpuser_nanosleep(uint64_t *sec, uint64_t *nsec, int *error)
99{ 99{
100 struct timespec rqt, rmt; 100 struct timespec rqt, rmt;
101 int rv; 101 int rv;
102 102
103 /*LINTED*/ 103 /*LINTED*/
104 rqt.tv_sec = *sec; 104 rqt.tv_sec = *sec;
105 /*LINTED*/ 105 /*LINTED*/
106 rqt.tv_nsec = *nsec; 106 rqt.tv_nsec = *nsec;
107 107
108 KLOCK_WRAP(rv = nanosleep(&rqt, &rmt)); 108 KLOCK_WRAP(rv = nanosleep(&rqt, &rmt));
109 if (rv == -1) 109 if (rv == -1)
110 *error = errno; 110 *error = errno;
111 111
112 *sec = rmt.tv_sec; 112 *sec = rmt.tv_sec;
113 *nsec = rmt.tv_nsec; 113 *nsec = rmt.tv_nsec;
114 114
115 return rv; 115 return rv;
116} 116}
117 117
118void * 118void *
119rumpuser__malloc(size_t howmuch, int canfail, const char *func, int line) 119rumpuser__malloc(size_t howmuch, int canfail, const char *func, int line)
120{ 120{
121 void *rv; 121 void *rv;
122 122
123 rv = malloc(howmuch); 123 rv = malloc(howmuch);
124 if (rv == NULL && canfail == 0) { 124 if (rv == NULL && canfail == 0) {
125 warn("malloc failed %s (%d)", func, line); 125 warn("malloc failed %s (%d)", func, line);
126 abort(); 126 abort();
127 } 127 }
128 128
129 if (rv) 129 if (rv)
130 memset(rv, 0, howmuch); 130 memset(rv, 0, howmuch);
131 131
132 return rv; 132 return rv;
133} 133}
134 134
135void * 135void *
136rumpuser__realloc(void *ptr, size_t howmuch, int canfail, 136rumpuser__realloc(void *ptr, size_t howmuch, int canfail,
137 const char *func, int line) 137 const char *func, int line)
138{ 138{
139 void *rv; 139 void *rv;
140 140
141 rv = realloc(ptr, howmuch); 141 rv = realloc(ptr, howmuch);
142 if (rv == NULL && canfail == 0) { 142 if (rv == NULL && canfail == 0) {
143 warn("realloc failed %s (%d)", func, line); 143 warn("realloc failed %s (%d)", func, line);
144 abort(); 144 abort();
145 } 145 }
146 146
147 return rv; 147 return rv;
148} 148}
149 149
150void 150void
151rumpuser_free(void *ptr) 151rumpuser_free(void *ptr)
152{ 152{
153 153
154 free(ptr); 154 free(ptr);
155} 155}
156 156
157void * 157void *
158rumpuser_anonmmap(size_t size, int alignbit, int exec, int *error) 158rumpuser_anonmmap(size_t size, int alignbit, int exec, int *error)
159{ 159{
160 void *rv; 160 void *rv;
161 int prot; 161 int prot;
162 162
163 prot = PROT_READ|PROT_WRITE; 163 prot = PROT_READ|PROT_WRITE;
164 if (exec) 164 if (exec)
165 prot |= PROT_EXEC; 165 prot |= PROT_EXEC;
166 /* XXX: MAP_ALIGNED() is not portable */ 166 /* XXX: MAP_ALIGNED() is not portable */
167 rv = mmap(NULL, size, prot, MAP_ANON | MAP_ALIGNED(alignbit), -1, 0); 167 rv = mmap(NULL, size, prot, MAP_ANON | MAP_ALIGNED(alignbit), -1, 0);
168 if (rv == MAP_FAILED) { 168 if (rv == MAP_FAILED) {
169 *error = errno; 169 *error = errno;
170 return NULL; 170 return NULL;
171 } 171 }
172 return rv; 172 return rv;
173} 173}
174 174
175void 175void
176rumpuser_unmap(void *addr, size_t len) 176rumpuser_unmap(void *addr, size_t len)
177{ 177{
178 int rv; 178 int rv;
179 179
180 rv = munmap(addr, len); 180 rv = munmap(addr, len);
181 assert(rv == 0); 181 assert(rv == 0);
182} 182}
183 183
184void * 184void *
185rumpuser_filemmap(int fd, off_t offset, size_t len, int shared, 185rumpuser_filemmap(int fd, off_t offset, size_t len, int flags, int *error)
186 int dotruncate, int *error) 
187{ 186{
188 void *rv; 187 void *rv;
189 int flags; 188 int mmflags, prot;
190 189
191 if (dotruncate) 190 if (flags & RUMPUSER_FILEMMAP_TRUNCATE)
192 ftruncate(fd, offset + len); 191 ftruncate(fd, offset + len);
193 192
194 flags = MAP_FILE; 193 mmflags = MAP_FILE;
195 if (shared) 194 if (flags & RUMPUSER_FILEMMAP_SHARED)
196 flags |= MAP_SHARED; 195 mmflags |= MAP_SHARED;
197 else 196 else
198 flags |= MAP_PRIVATE; 197 mmflags |= MAP_PRIVATE;
199 198
200 rv = mmap(NULL, len, PROT_READ|PROT_WRITE, flags, fd, offset); 199 prot = 0;
 200 if (flags & RUMPUSER_FILEMMAP_READ)
 201 prot |= PROT_READ;
 202 if (flags & RUMPUSER_FILEMMAP_WRITE)
 203 prot |= PROT_WRITE;
 204
 205 rv = mmap(NULL, len, PROT_READ|PROT_WRITE, mmflags, fd, offset);
201 if (rv == MAP_FAILED) { 206 if (rv == MAP_FAILED) {
202 *error = errno; 207 *error = errno;
203 return NULL; 208 return NULL;
204 } 209 }
205 210
206 *error = 0; 211 *error = 0;
207 return rv; 212 return rv;
208} 213}
209 214
210int 215int
 216rumpuser_memsync(void *addr, size_t len, int *error)
 217{
 218
 219 DOCALL_KLOCK(int, (msync(addr, len, MS_SYNC)));
 220}
 221
 222int
211rumpuser_open(const char *path, int flags, int *error) 223rumpuser_open(const char *path, int flags, int *error)
212{ 224{
213 225
214 DOCALL(int, (open(path, flags, 0644))); 226 DOCALL(int, (open(path, flags, 0644)));
215} 227}
216 228
217int 229int
218rumpuser_ioctl(int fd, u_long cmd, void *data, int *error) 230rumpuser_ioctl(int fd, u_long cmd, void *data, int *error)
219{ 231{
220 232
221 DOCALL_KLOCK(int, (ioctl(fd, cmd, data))); 233 DOCALL_KLOCK(int, (ioctl(fd, cmd, data)));
222} 234}
223 235
224int 236int
225rumpuser_close(int fd, int *error) 237rumpuser_close(int fd, int *error)
226{ 238{
227 239
228 DOCALL(int, close(fd)); 240 DOCALL(int, close(fd));
229} 241}
230 242
231int 243int
232rumpuser_fsync(int fd, int *error) 244rumpuser_fsync(int fd, int *error)
233{ 245{
234 246
235 DOCALL_KLOCK(int, fsync(fd)); 247 DOCALL_KLOCK(int, fsync(fd));
236} 248}
237 249
238ssize_t 250ssize_t
239rumpuser_read(int fd, void *data, size_t size, int *error) 251rumpuser_read(int fd, void *data, size_t size, int *error)
240{ 252{
241 ssize_t rv; 253 ssize_t rv;
242 254
243 KLOCK_WRAP(rv = read(fd, data, size)); 255 KLOCK_WRAP(rv = read(fd, data, size));
244 if (rv == -1) 256 if (rv == -1)
245 *error = errno; 257 *error = errno;
246 258
247 return rv; 259 return rv;
248} 260}
249 261
250ssize_t 262ssize_t
251rumpuser_pread(int fd, void *data, size_t size, off_t offset, int *error) 263rumpuser_pread(int fd, void *data, size_t size, off_t offset, int *error)
252{ 264{
253 ssize_t rv; 265 ssize_t rv;
254 266
255 KLOCK_WRAP(rv = pread(fd, data, size, offset)); 267 KLOCK_WRAP(rv = pread(fd, data, size, offset));
256 if (rv == -1) 268 if (rv == -1)
257 *error = errno; 269 *error = errno;
258 270
259 return rv; 271 return rv;
260} 272}
261 273
262void 274void
263rumpuser_read_bio(int fd, void *data, size_t size, off_t offset, 275rumpuser_read_bio(int fd, void *data, size_t size, off_t offset,
264 rump_biodone_fn biodone, void *biodonecookie) 276 rump_biodone_fn biodone, void *biodonecookie)
265{ 277{
266 ssize_t rv; 278 ssize_t rv;
267 int error = 0; 279 int error = 0;
268 280
269 KLOCK_WRAP(rv = rumpuser_pread(fd, data, size, offset, &error)); 281 KLOCK_WRAP(rv = rumpuser_pread(fd, data, size, offset, &error));
270 /* check against <0 instead of ==-1 to get typing below right */ 282 /* check against <0 instead of ==-1 to get typing below right */
271 if (rv < 0) 283 if (rv < 0)
272 rv = 0; 284 rv = 0;
273  285
274 /* LINTED: see above */ 286 /* LINTED: see above */
275 biodone(biodonecookie, rv, error); 287 biodone(biodonecookie, rv, error);
276} 288}
277 289
278ssize_t 290ssize_t
279rumpuser_write(int fd, const void *data, size_t size, int *error) 291rumpuser_write(int fd, const void *data, size_t size, int *error)
280{ 292{
281 ssize_t rv; 293 ssize_t rv;
282 294
283 KLOCK_WRAP(rv = write(fd, data, size)); 295 KLOCK_WRAP(rv = write(fd, data, size));
284 if (rv == -1) 296 if (rv == -1)
285 *error = errno; 297 *error = errno;
286 298
287 return rv; 299 return rv;
288} 300}
289 301
290ssize_t 302ssize_t
291rumpuser_pwrite(int fd, const void *data, size_t size, off_t offset, int *error) 303rumpuser_pwrite(int fd, const void *data, size_t size, off_t offset, int *error)
292{ 304{
293 ssize_t rv; 305 ssize_t rv;
294 306
295 KLOCK_WRAP(rv = pwrite(fd, data, size, offset)); 307 KLOCK_WRAP(rv = pwrite(fd, data, size, offset));
296 if (rv == -1) 308 if (rv == -1)
297 *error = errno; 309 *error = errno;
298 310
299 return rv; 311 return rv;
300} 312}
301 313
302void 314void
303rumpuser_write_bio(int fd, const void *data, size_t size, off_t offset, 315rumpuser_write_bio(int fd, const void *data, size_t size, off_t offset,
304 rump_biodone_fn biodone, void *biodonecookie) 316 rump_biodone_fn biodone, void *biodonecookie)
305{ 317{
306 ssize_t rv; 318 ssize_t rv;
307 int error = 0; 319 int error = 0;
308 320
309 KLOCK_WRAP(rv = rumpuser_pwrite(fd, data, size, offset, &error)); 321 KLOCK_WRAP(rv = rumpuser_pwrite(fd, data, size, offset, &error));
310 /* check against <0 instead of ==-1 to get typing below right */ 322 /* check against <0 instead of ==-1 to get typing below right */
311 if (rv < 0) 323 if (rv < 0)
312 rv = 0; 324 rv = 0;
313 325
314 /* LINTED: see above */ 326 /* LINTED: see above */
315 biodone(biodonecookie, rv, error); 327 biodone(biodonecookie, rv, error);
316} 328}
317 329
318ssize_t  330ssize_t
319rumpuser_readv(int fd, const struct rumpuser_iovec *riov, int iovcnt, 331rumpuser_readv(int fd, const struct rumpuser_iovec *riov, int iovcnt,
320 int *error) 332 int *error)
321{ 333{
322 struct iovec *iovp; 334 struct iovec *iovp;
323 ssize_t rv; 335 ssize_t rv;
324 int i; 336 int i;
325 337
326 iovp = malloc(iovcnt * sizeof(struct iovec)); 338 iovp = malloc(iovcnt * sizeof(struct iovec));
327 if (iovp == NULL) { 339 if (iovp == NULL) {
328 *error = ENOMEM; 340 *error = ENOMEM;
329 return -1; 341 return -1;
330 } 342 }
331 for (i = 0; i < iovcnt; i++) { 343 for (i = 0; i < iovcnt; i++) {
332 iovp[i].iov_base = riov[i].iov_base; 344 iovp[i].iov_base = riov[i].iov_base;
333 /*LINTED*/ 345 /*LINTED*/
334 iovp[i].iov_len = riov[i].iov_len; 346 iovp[i].iov_len = riov[i].iov_len;
335 } 347 }
336 348
337 KLOCK_WRAP(rv = readv(fd, iovp, iovcnt)); 349 KLOCK_WRAP(rv = readv(fd, iovp, iovcnt));
338 if (rv == -1) 350 if (rv == -1)
339 *error = errno; 351 *error = errno;
340 free(iovp); 352 free(iovp);
341 353
342 return rv; 354 return rv;
343} 355}
344 356
345ssize_t  357ssize_t
346rumpuser_writev(int fd, const struct rumpuser_iovec *riov, int iovcnt, 358rumpuser_writev(int fd, const struct rumpuser_iovec *riov, int iovcnt,
347 int *error) 359 int *error)
348{ 360{
349 struct iovec *iovp; 361 struct iovec *iovp;
350 ssize_t rv; 362 ssize_t rv;
351 int i; 363 int i;
352 364
353 iovp = malloc(iovcnt * sizeof(struct iovec)); 365 iovp = malloc(iovcnt * sizeof(struct iovec));
354 if (iovp == NULL) { 366 if (iovp == NULL) {
355 *error = ENOMEM; 367 *error = ENOMEM;
356 return -1; 368 return -1;
357 } 369 }
358 for (i = 0; i < iovcnt; i++) { 370 for (i = 0; i < iovcnt; i++) {
359 iovp[i].iov_base = riov[i].iov_base; 371 iovp[i].iov_base = riov[i].iov_base;
360 /*LINTED*/ 372 /*LINTED*/
361 iovp[i].iov_len = riov[i].iov_len; 373 iovp[i].iov_len = riov[i].iov_len;
362 } 374 }
363 375
364 KLOCK_WRAP(rv = writev(fd, iovp, iovcnt)); 376 KLOCK_WRAP(rv = writev(fd, iovp, iovcnt));
365 if (rv == -1) 377 if (rv == -1)
366 *error = errno; 378 *error = errno;
367 free(iovp); 379 free(iovp);
368 380
369 return rv; 381 return rv;
370} 382}
371 383
372int 384int
373rumpuser_gettime(uint64_t *sec, uint64_t *nsec, int *error) 385rumpuser_gettime(uint64_t *sec, uint64_t *nsec, int *error)
374{ 386{
375 struct timeval tv; 387 struct timeval tv;
376 int rv; 388 int rv;
377 389
378 rv = gettimeofday(&tv, NULL); 390 rv = gettimeofday(&tv, NULL);
379 if (rv == -1) { 391 if (rv == -1) {
380 *error = errno; 392 *error = errno;
381 return rv; 393 return rv;
382 } 394 }
383 395
384 *sec = tv.tv_sec; 396 *sec = tv.tv_sec;
385 *nsec = tv.tv_usec * 1000; 397 *nsec = tv.tv_usec * 1000;
386 398
387 return 0; 399 return 0;
388} 400}
389 401
390int 402int
391rumpuser_getenv(const char *name, char *buf, size_t blen, int *error) 403rumpuser_getenv(const char *name, char *buf, size_t blen, int *error)
392{ 404{
393 405
394 DOCALL(int, getenv_r(name, buf, blen)); 406 DOCALL(int, getenv_r(name, buf, blen));
395} 407}
396 408
397int 409int
398rumpuser_gethostname(char *name, size_t namelen, int *error) 410rumpuser_gethostname(char *name, size_t namelen, int *error)
399{ 411{
400 412
401 DOCALL(int, (gethostname(name, namelen))); 413 DOCALL(int, (gethostname(name, namelen)));
402} 414}
403 415
404char * 416char *
405rumpuser_realpath(const char *path, char resolvedname[MAXPATHLEN], int *error) 417rumpuser_realpath(const char *path, char resolvedname[MAXPATHLEN], int *error)
406{ 418{
407 char *rv; 419 char *rv;
408 420
409 rv = realpath(path, resolvedname); 421 rv = realpath(path, resolvedname);
410 if (rv == NULL) 422 if (rv == NULL)
411 *error = errno; 423 *error = errno;
412 else 424 else
413 *error = 0; 425 *error = 0;
414 426
415 return rv; 427 return rv;
416} 428}
417 429
418int 430int
419rumpuser_poll(struct pollfd *fds, int nfds, int timeout, int *error) 431rumpuser_poll(struct pollfd *fds, int nfds, int timeout, int *error)
420{ 432{
421 433
422 DOCALL_KLOCK(int, (poll(fds, (nfds_t)nfds, timeout))); 434 DOCALL_KLOCK(int, (poll(fds, (nfds_t)nfds, timeout)));
423} 435}
424 436
425int 437int
426rumpuser_putchar(int c, int *error) 438rumpuser_putchar(int c, int *error)
427{ 439{
428 440
429 DOCALL(int, (putchar(c))); 441 DOCALL(int, (putchar(c)));
430} 442}
431 443
432void 444void
433rumpuser_panic(void) 445rumpuser_panic(void)
434{ 446{
435 447
436 abort(); 448 abort();
437} 449}
438 450
439void 451void
440rumpuser_seterrno(int error) 452rumpuser_seterrno(int error)
441{ 453{
442 454
443 errno = error; 455 errno = error;
444} 456}
445 457
446int 458int
447rumpuser_writewatchfile_setup(int kq, int fd, intptr_t opaque, int *error) 459rumpuser_writewatchfile_setup(int kq, int fd, intptr_t opaque, int *error)
448{ 460{
449 struct kevent kev; 461 struct kevent kev;
450 462
451 if (kq == -1) { 463 if (kq == -1) {
452 kq = kqueue(); 464 kq = kqueue();
453 if (kq == -1) { 465 if (kq == -1) {
454 *error = errno; 466 *error = errno;
455 return -1; 467 return -1;
456 } 468 }
457 } 469 }
458 470
459 EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD|EV_ENABLE|EV_CLEAR, 471 EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD|EV_ENABLE|EV_CLEAR,
460 NOTE_WRITE, 0, opaque); 472 NOTE_WRITE, 0, opaque);
461 if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) { 473 if (kevent(kq, &kev, 1, NULL, 0, NULL) == -1) {
462 *error = errno; 474 *error = errno;
463 return -1; 475 return -1;
464 } 476 }
465 477
466 return kq; 478 return kq;
467} 479}
468 480
469int 481int
470rumpuser_writewatchfile_wait(int kq, intptr_t *opaque, int *error) 482rumpuser_writewatchfile_wait(int kq, intptr_t *opaque, int *error)
471{ 483{
472 struct kevent kev; 484 struct kevent kev;
473 int rv; 485 int rv;
474 486
475 KLOCK_WRAP(rv = kevent(kq, NULL, 0, &kev, 1, NULL)); 487 KLOCK_WRAP(rv = kevent(kq, NULL, 0, &kev, 1, NULL));
476 if (rv == -1) { 488 if (rv == -1) {
477 *error = errno; 489 *error = errno;
478 return -1; 490 return -1;
479 } 491 }
480 492
481 if (opaque) 493 if (opaque)
482 *opaque = kev.udata; 494 *opaque = kev.udata;
483 return rv; 495 return rv;
484} 496}

cvs diff -r1.4 -r1.5 src/sys/rump/net/lib/libshmif/if_shmem.c (switch to unified diff)

--- src/sys/rump/net/lib/libshmif/if_shmem.c 2009/03/01 20:50:04 1.4
+++ src/sys/rump/net/lib/libshmif/if_shmem.c 2009/03/18 15:32:27 1.5
@@ -1,377 +1,378 @@ @@ -1,377 +1,378 @@
1/* $NetBSD: if_shmem.c,v 1.4 2009/03/01 20:50:04 pooka Exp $ */ 1/* $NetBSD: if_shmem.c,v 1.5 2009/03/18 15:32:27 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2009 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by The Nokia Foundation. 6 * Development of this software was supported by The Nokia Foundation.
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 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.4 2009/03/01 20:50:04 pooka Exp $"); 31__KERNEL_RCSID(0, "$NetBSD: if_shmem.c,v 1.5 2009/03/18 15:32:27 pooka Exp $");
32 32
33#include <sys/param.h> 33#include <sys/param.h>
34#include <sys/fcntl.h> 34#include <sys/fcntl.h>
35#include <sys/kmem.h> 35#include <sys/kmem.h>
36#include <sys/kthread.h> 36#include <sys/kthread.h>
37#include <sys/lock.h> 37#include <sys/lock.h>
38#include <sys/atomic.h> 38#include <sys/atomic.h>
39 39
40#include <net/if.h> 40#include <net/if.h>
41#include <net/if_ether.h> 41#include <net/if_ether.h>
42 42
43#include <netinet/in.h> 43#include <netinet/in.h>
44#include <netinet/in_var.h> 44#include <netinet/in_var.h>
45 45
46#include <rump/rump.h> 46#include <rump/rump.h>
47#include <rump/rumpuser.h> 47#include <rump/rumpuser.h>
48 48
49#include "rump_private.h" 49#include "rump_private.h"
50 50
51/* 51/*
52 * A virtual ethernet interface which uses shared memory from a 52 * A virtual ethernet interface which uses shared memory from a
53 * memory mapped file as the bus. 53 * memory mapped file as the bus.
54 */ 54 */
55 55
56static int shmif_init(struct ifnet *); 56static int shmif_init(struct ifnet *);
57static int shmif_ioctl(struct ifnet *, u_long, void *); 57static int shmif_ioctl(struct ifnet *, u_long, void *);
58static void shmif_start(struct ifnet *); 58static void shmif_start(struct ifnet *);
59static void shmif_stop(struct ifnet *, int); 59static void shmif_stop(struct ifnet *, int);
60 60
61struct shmif_sc { 61struct shmif_sc {
62 struct ethercom sc_ec; 62 struct ethercom sc_ec;
63 uint8_t sc_myaddr[6]; 63 uint8_t sc_myaddr[6];
64 uint8_t *sc_busmem; 64 uint8_t *sc_busmem;
65 int sc_memfd; 65 int sc_memfd;
66 int sc_kq; 66 int sc_kq;
67 67
68 uint32_t sc_nextpacket; 68 uint32_t sc_nextpacket;
69 uint32_t sc_prevgen; 69 uint32_t sc_prevgen;
70}; 70};
71#define IFMEM_LOCK (0) 71#define IFMEM_LOCK (0)
72#define IFMEM_GENERATION (8) 72#define IFMEM_GENERATION (8)
73#define IFMEM_LASTPACKET (12) 73#define IFMEM_LASTPACKET (12)
74#define IFMEM_WAKEUP (16) 74#define IFMEM_WAKEUP (16)
75#define IFMEM_DATA (20) 75#define IFMEM_DATA (20)
76 76
77#define BUSCTRL_ATOFF(sc, off) ((uint32_t *)(sc->sc_busmem+(off))) 77#define BUSCTRL_ATOFF(sc, off) ((uint32_t *)(sc->sc_busmem+(off)))
78 78
79#define BUSMEM_SIZE 65536 /* enough? */ 79#define BUSMEM_SIZE 65536 /* enough? */
80 80
81static void shmif_rcv(void *); 81static void shmif_rcv(void *);
82 82
83static uint32_t numif; 83static uint32_t numif;
84 84
85/* 85/*
86 * This locking needs work and will misbehave severely if: 86 * This locking needs work and will misbehave severely if:
87 * 1) the backing memory has to be paged in 87 * 1) the backing memory has to be paged in
88 * 2) some lockholder exits while holding the lock 88 * 2) some lockholder exits while holding the lock
89 */ 89 */
90static void 90static void
91lockbus(struct shmif_sc *sc) 91lockbus(struct shmif_sc *sc)
92{ 92{
93 93
94 __cpu_simple_lock((__cpu_simple_lock_t *)sc->sc_busmem); 94 __cpu_simple_lock((__cpu_simple_lock_t *)sc->sc_busmem);
95} 95}
96 96
97static void 97static void
98unlockbus(struct shmif_sc *sc) 98unlockbus(struct shmif_sc *sc)
99{ 99{
100 100
101 __cpu_simple_unlock((__cpu_simple_lock_t *)sc->sc_busmem); 101 __cpu_simple_unlock((__cpu_simple_lock_t *)sc->sc_busmem);
102} 102}
103 103
104static uint32_t 104static uint32_t
105busread(struct shmif_sc *sc, void *dest, uint32_t off, size_t len) 105busread(struct shmif_sc *sc, void *dest, uint32_t off, size_t len)
106{ 106{
107 size_t chunk; 107 size_t chunk;
108 108
109 KASSERT(len < (BUSMEM_SIZE - IFMEM_DATA) && off <= BUSMEM_SIZE); 109 KASSERT(len < (BUSMEM_SIZE - IFMEM_DATA) && off <= BUSMEM_SIZE);
110 chunk = MIN(len, BUSMEM_SIZE - off); 110 chunk = MIN(len, BUSMEM_SIZE - off);
111 memcpy(dest, sc->sc_busmem + off, chunk); 111 memcpy(dest, sc->sc_busmem + off, chunk);
112 len -= chunk; 112 len -= chunk;
113 113
114 if (len == 0) 114 if (len == 0)
115 return off + chunk; 115 return off + chunk;
116 116
117 /* else, wraps around */ 117 /* else, wraps around */
118 off = IFMEM_DATA; 118 off = IFMEM_DATA;
119 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); 119 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION);
120 120
121 /* finish reading */ 121 /* finish reading */
122 memcpy((uint8_t *)dest + chunk, sc->sc_busmem + off, len); 122 memcpy((uint8_t *)dest + chunk, sc->sc_busmem + off, len);
123 return off + len; 123 return off + len;
124} 124}
125 125
126static uint32_t 126static uint32_t
127buswrite(struct shmif_sc *sc, uint32_t off, void *data, size_t len) 127buswrite(struct shmif_sc *sc, uint32_t off, void *data, size_t len)
128{ 128{
129 size_t chunk; 129 size_t chunk;
130 130
131 KASSERT(len < (BUSMEM_SIZE - IFMEM_DATA) && off <= BUSMEM_SIZE); 131 KASSERT(len < (BUSMEM_SIZE - IFMEM_DATA) && off <= BUSMEM_SIZE);
132 132
133 chunk = MIN(len, BUSMEM_SIZE - off); 133 chunk = MIN(len, BUSMEM_SIZE - off);
134 memcpy(sc->sc_busmem + off, data, chunk); 134 memcpy(sc->sc_busmem + off, data, chunk);
135 len -= chunk; 135 len -= chunk;
136 136
137 if (len == 0) 137 if (len == 0)
138 return off + chunk; 138 return off + chunk;
139 139
140 DPRINTF(("buswrite wrap: wrote %d bytes to %d, left %d to %d", 140 DPRINTF(("buswrite wrap: wrote %d bytes to %d, left %d to %d",
141 chunk, off, len, IFMEM_DATA)); 141 chunk, off, len, IFMEM_DATA));
142 142
143 /* else, wraps around */ 143 /* else, wraps around */
144 off = IFMEM_DATA; 144 off = IFMEM_DATA;
145 (*BUSCTRL_ATOFF(sc, IFMEM_GENERATION))++; 145 (*BUSCTRL_ATOFF(sc, IFMEM_GENERATION))++;
146 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); 146 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION);
147 147
148 /* finish writing */ 148 /* finish writing */
149 memcpy(sc->sc_busmem + off, (uint8_t *)data + chunk, len); 149 memcpy(sc->sc_busmem + off, (uint8_t *)data + chunk, len);
150 return off + len; 150 return off + len;
151} 151}
152 152
153static inline uint32_t 153static inline uint32_t
154advance(uint32_t oldoff, uint32_t delta) 154advance(uint32_t oldoff, uint32_t delta)
155{ 155{
156 uint32_t newoff; 156 uint32_t newoff;
157 157
158 newoff = oldoff + delta; 158 newoff = oldoff + delta;
159 if (newoff >= BUSMEM_SIZE) 159 if (newoff >= BUSMEM_SIZE)
160 newoff -= (BUSMEM_SIZE - IFMEM_DATA); 160 newoff -= (BUSMEM_SIZE - IFMEM_DATA);
161 return newoff; 161 return newoff;
162 162
163} 163}
164 164
165static uint32_t 165static uint32_t
166nextpktoff(struct shmif_sc *sc, uint32_t oldoff) 166nextpktoff(struct shmif_sc *sc, uint32_t oldoff)
167{ 167{
168 uint32_t oldlen; 168 uint32_t oldlen;
169 169
170 busread(sc, &oldlen, oldoff, 4); 170 busread(sc, &oldlen, oldoff, 4);
171 KASSERT(oldlen < BUSMEM_SIZE - IFMEM_DATA); 171 KASSERT(oldlen < BUSMEM_SIZE - IFMEM_DATA);
172 172
173 return advance(oldoff, 4 + oldlen); 173 return advance(oldoff, 4 + oldlen);
174} 174}
175 175
176int rump_shmif_create(const char *, int *); /* XXX */ 176int rump_shmif_create(const char *, int *); /* XXX */
177 177
178int 178int
179rump_shmif_create(const char *path, int *ifnum) 179rump_shmif_create(const char *path, int *ifnum)
180{ 180{
181 struct shmif_sc *sc; 181 struct shmif_sc *sc;
182 struct ifnet *ifp; 182 struct ifnet *ifp;
183 uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 }; 183 uint8_t enaddr[ETHER_ADDR_LEN] = { 0xb2, 0xa0, 0x00, 0x00, 0x00, 0x00 };
184 uint32_t randnum; 184 uint32_t randnum;
185 unsigned mynum; 185 unsigned mynum;
186 int error; 186 int error;
187 187
188 randnum = arc4random(); 188 randnum = arc4random();
189 memcpy(&enaddr[2], &randnum, 4); 189 memcpy(&enaddr[2], &randnum, 4);
190 mynum = atomic_inc_uint_nv(&numif)-1; 190 mynum = atomic_inc_uint_nv(&numif)-1;
191 191
192 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 192 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
193 ifp = &sc->sc_ec.ec_if; 193 ifp = &sc->sc_ec.ec_if;
194 memcpy(sc->sc_myaddr, enaddr, sizeof(enaddr)); 194 memcpy(sc->sc_myaddr, enaddr, sizeof(enaddr));
195 195
196 sc->sc_memfd = rumpuser_open(path, O_RDWR | O_CREAT, &error); 196 sc->sc_memfd = rumpuser_open(path, O_RDWR | O_CREAT, &error);
197 if (sc->sc_memfd == -1) 197 if (sc->sc_memfd == -1)
198 goto fail; 198 goto fail;
199 sc->sc_busmem = rumpuser_filemmap(sc->sc_memfd, 0, BUSMEM_SIZE, 199 sc->sc_busmem = rumpuser_filemmap(sc->sc_memfd, 0, BUSMEM_SIZE,
200 1, 1, &error); 200 RUMPUSER_FILEMMAP_TRUNCATE | RUMPUSER_FILEMMAP_SHARED
 201 | RUMPUSER_FILEMMAP_READ | RUMPUSER_FILEMMAP_WRITE, &error);
201 if (error) 202 if (error)
202 goto fail; 203 goto fail;
203 204
204 lockbus(sc); 205 lockbus(sc);
205 if (*BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) == 0) 206 if (*BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) == 0)
206 *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = IFMEM_DATA; 207 *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = IFMEM_DATA;
207 sc->sc_nextpacket = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); 208 sc->sc_nextpacket = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET);
208 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); 209 sc->sc_prevgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION);
209 unlockbus(sc); 210 unlockbus(sc);
210 211
211 sc->sc_kq = rumpuser_writewatchfile_setup(-1, sc->sc_memfd, 0, &error); 212 sc->sc_kq = rumpuser_writewatchfile_setup(-1, sc->sc_memfd, 0, &error);
212 if (sc->sc_kq == -1) 213 if (sc->sc_kq == -1)
213 goto fail; 214 goto fail;
214 215
215 sprintf(ifp->if_xname, "shmif%d", mynum); 216 sprintf(ifp->if_xname, "shmif%d", mynum);
216 ifp->if_softc = sc; 217 ifp->if_softc = sc;
217 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 218 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
218 ifp->if_init = shmif_init; 219 ifp->if_init = shmif_init;
219 ifp->if_ioctl = shmif_ioctl; 220 ifp->if_ioctl = shmif_ioctl;
220 ifp->if_start = shmif_start; 221 ifp->if_start = shmif_start;
221 ifp->if_stop = shmif_stop; 222 ifp->if_stop = shmif_stop;
222 ifp->if_mtu = 1518; 223 ifp->if_mtu = 1518;
223 224
224 if_attach(ifp); 225 if_attach(ifp);
225 ether_ifattach(ifp, enaddr); 226 ether_ifattach(ifp, enaddr);
226 227
227 if (ifnum) 228 if (ifnum)
228 *ifnum = mynum; 229 *ifnum = mynum;
229 return 0; 230 return 0;
230 231
231 fail: 232 fail:
232 panic("rump_shmemif_create: fixme"); 233 panic("rump_shmemif_create: fixme");
233} 234}
234 235
235static int 236static int
236shmif_init(struct ifnet *ifp) 237shmif_init(struct ifnet *ifp)
237{ 238{
238 int error = 0; 239 int error = 0;
239 240
240 if (rump_threads) { 241 if (rump_threads) {
241 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, 242 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
242 shmif_rcv, ifp, NULL, "shmif"); 243 shmif_rcv, ifp, NULL, "shmif");
243 } else { 244 } else {
244 printf("WARNING: threads not enabled, shmif NOT working\n"); 245 printf("WARNING: threads not enabled, shmif NOT working\n");
245 } 246 }
246 247
247 ifp->if_flags |= IFF_RUNNING; 248 ifp->if_flags |= IFF_RUNNING;
248 return error; 249 return error;
249} 250}
250 251
251static int 252static int
252shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data) 253shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
253{ 254{
254 int s, rv; 255 int s, rv;
255 256
256 s = splnet(); 257 s = splnet();
257 rv = ether_ioctl(ifp, cmd, data); 258 rv = ether_ioctl(ifp, cmd, data);
258 splx(s); 259 splx(s);
259 260
260 return rv; 261 return rv;
261} 262}
262 263
263/* send everything in-context */ 264/* send everything in-context */
264static void 265static void
265shmif_start(struct ifnet *ifp) 266shmif_start(struct ifnet *ifp)
266{ 267{
267 struct shmif_sc *sc = ifp->if_softc; 268 struct shmif_sc *sc = ifp->if_softc;
268 struct mbuf *m, *m0; 269 struct mbuf *m, *m0;
269 uint32_t lastoff, dataoff, npktlenoff; 270 uint32_t lastoff, dataoff, npktlenoff;
270 uint32_t pktsize = 0; 271 uint32_t pktsize = 0;
271 bool wrote = false; 272 bool wrote = false;
272 int error; 273 int error;
273 274
274 for (;;) { 275 for (;;) {
275 IF_DEQUEUE(&ifp->if_snd, m0); 276 IF_DEQUEUE(&ifp->if_snd, m0);
276 if (m0 == NULL) { 277 if (m0 == NULL) {
277 break; 278 break;
278 } 279 }
279 280
280 lockbus(sc); 281 lockbus(sc);
281 lastoff = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); 282 lastoff = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET);
282 283
283 npktlenoff = nextpktoff(sc, lastoff); 284 npktlenoff = nextpktoff(sc, lastoff);
284 dataoff = advance(npktlenoff, 4); 285 dataoff = advance(npktlenoff, 4);
285 286
286 for (m = m0; m != NULL; m = m->m_next) { 287 for (m = m0; m != NULL; m = m->m_next) {
287 pktsize += m->m_len; 288 pktsize += m->m_len;
288 dataoff = buswrite(sc, dataoff, mtod(m, void *), 289 dataoff = buswrite(sc, dataoff, mtod(m, void *),
289 m->m_len); 290 m->m_len);
290 } 291 }
291 buswrite(sc, npktlenoff, &pktsize, 4); 292 buswrite(sc, npktlenoff, &pktsize, 4);
292 *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = npktlenoff; 293 *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET) = npktlenoff;
293 unlockbus(sc); 294 unlockbus(sc);
294 295
295 m_freem(m0); 296 m_freem(m0);
296 wrote = true; 297 wrote = true;
297 298
298 DPRINTF(("shmif_start: send %d bytes at off %d\n", 299 DPRINTF(("shmif_start: send %d bytes at off %d\n",
299 pktsize, npktlenoff)); 300 pktsize, npktlenoff));
300 } 301 }
301 /* wakeup */ 302 /* wakeup */
302 if (wrote) 303 if (wrote)
303 rumpuser_pwrite(sc->sc_memfd, &error, 4, IFMEM_WAKEUP, &error); 304 rumpuser_pwrite(sc->sc_memfd, &error, 4, IFMEM_WAKEUP, &error);
304} 305}
305 306
306static void 307static void
307shmif_stop(struct ifnet *ifp, int disable) 308shmif_stop(struct ifnet *ifp, int disable)
308{ 309{
309 310
310 panic("%s: unimpl", __func__); 311 panic("%s: unimpl", __func__);
311} 312}
312 313
313static void 314static void
314shmif_rcv(void *arg) 315shmif_rcv(void *arg)
315{ 316{
316 struct ifnet *ifp = arg; 317 struct ifnet *ifp = arg;
317 struct shmif_sc *sc = ifp->if_softc; 318 struct shmif_sc *sc = ifp->if_softc;
318 struct mbuf *m = NULL; 319 struct mbuf *m = NULL;
319 struct ether_header *eth; 320 struct ether_header *eth;
320 uint32_t nextpkt, pktlen, lastpkt, busgen, lastnext; 321 uint32_t nextpkt, pktlen, lastpkt, busgen, lastnext;
321 int error; 322 int error;
322 323
323 for (;;) { 324 for (;;) {
324 if (m == NULL) { 325 if (m == NULL) {
325 m = m_gethdr(M_WAIT, MT_DATA); 326 m = m_gethdr(M_WAIT, MT_DATA);
326 MCLGET(m, M_WAIT); 327 MCLGET(m, M_WAIT);
327 } 328 }
328 329
329 DPRINTF(("waiting %d/%d\n", sc->sc_nextpacket, sc->sc_prevgen)); 330 DPRINTF(("waiting %d/%d\n", sc->sc_nextpacket, sc->sc_prevgen));
330 331
331 KASSERT(m->m_flags & M_EXT); 332 KASSERT(m->m_flags & M_EXT);
332 lockbus(sc); 333 lockbus(sc);
333 lastpkt = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET); 334 lastpkt = *BUSCTRL_ATOFF(sc, IFMEM_LASTPACKET);
334 busgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION); 335 busgen = *BUSCTRL_ATOFF(sc, IFMEM_GENERATION);
335 lastnext = nextpktoff(sc, lastpkt); 336 lastnext = nextpktoff(sc, lastpkt);
336 if ((lastnext > sc->sc_nextpacket && busgen > sc->sc_prevgen) 337 if ((lastnext > sc->sc_nextpacket && busgen > sc->sc_prevgen)
337 || (busgen > sc->sc_prevgen+1)) { 338 || (busgen > sc->sc_prevgen+1)) {
338 nextpkt = lastpkt; 339 nextpkt = lastpkt;
339 sc->sc_prevgen = busgen; 340 sc->sc_prevgen = busgen;
340 printf("DROPPING\n"); 341 printf("DROPPING\n");
341 } else { 342 } else {
342 nextpkt = sc->sc_nextpacket; 343 nextpkt = sc->sc_nextpacket;
343 } 344 }
344 345
345 /* need more data? */ 346 /* need more data? */
346 if (lastnext == nextpkt && sc->sc_prevgen == busgen){ 347 if (lastnext == nextpkt && sc->sc_prevgen == busgen){
347 unlockbus(sc); 348 unlockbus(sc);
348 error = 0; 349 error = 0;
349 rumpuser_writewatchfile_wait(sc->sc_kq, NULL, &error); 350 rumpuser_writewatchfile_wait(sc->sc_kq, NULL, &error);
350 if (__predict_false(error)) 351 if (__predict_false(error))
351 printf("shmif_rcv: wait failed %d\n", error); 352 printf("shmif_rcv: wait failed %d\n", error);
352 continue; 353 continue;
353 } 354 }
354 355
355 busread(sc, &pktlen, nextpkt, 4); 356 busread(sc, &pktlen, nextpkt, 4);
356 busread(sc, mtod(m, void *), advance(nextpkt, 4), pktlen); 357 busread(sc, mtod(m, void *), advance(nextpkt, 4), pktlen);
357 358
358 DPRINTF(("shmif_rcv: read packet of length %d at %d\n", 359 DPRINTF(("shmif_rcv: read packet of length %d at %d\n",
359 pktlen, nextpkt)); 360 pktlen, nextpkt));
360 361
361 sc->sc_nextpacket = nextpktoff(sc, nextpkt); 362 sc->sc_nextpacket = nextpktoff(sc, nextpkt);
362 sc->sc_prevgen = busgen; 363 sc->sc_prevgen = busgen;
363 unlockbus(sc); 364 unlockbus(sc);
364 365
365 m->m_len = m->m_pkthdr.len = pktlen; 366 m->m_len = m->m_pkthdr.len = pktlen;
366 m->m_pkthdr.rcvif = ifp; 367 m->m_pkthdr.rcvif = ifp;
367 368
368 /* if it's to us, don't pass up and reuse storage space */ 369 /* if it's to us, don't pass up and reuse storage space */
369 eth = mtod(m, struct ether_header *); 370 eth = mtod(m, struct ether_header *);
370 if (memcmp(eth->ether_shost, sc->sc_myaddr, 6) != 0) { 371 if (memcmp(eth->ether_shost, sc->sc_myaddr, 6) != 0) {
371 ifp->if_input(ifp, m); 372 ifp->if_input(ifp, m);
372 m = NULL; 373 m = NULL;
373 } 374 }
374 } 375 }
375 376
376 panic("shmif_worker is a lazy boy %d\n", error); 377 panic("shmif_worker is a lazy boy %d\n", error);
377} 378}