| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: xmd.c,v 1.1.2.4 2010/08/28 16:27:02 uebayasi Exp $ */ | | 1 | /* $NetBSD: xmd.c,v 1.1.2.5 2010/10/30 08:51:10 uebayasi Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2010 Tsubai Masanari. All rights reserved. | | 4 | * Copyright (c) 2010 Tsubai Masanari. All rights reserved. |
5 | * Copyright (c) 2010 Masao Uebayashi. All rights reserved. | | 5 | * Copyright (c) 2010 Masao Uebayashi. 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. |
| @@ -18,52 +18,48 @@ | | | @@ -18,52 +18,48 @@ |
18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/cdefs.h> | | 30 | #include <sys/cdefs.h> |
31 | __KERNEL_RCSID(0, "$NetBSD: xmd.c,v 1.1.2.4 2010/08/28 16:27:02 uebayasi Exp $"); | | 31 | __KERNEL_RCSID(0, "$NetBSD: xmd.c,v 1.1.2.5 2010/10/30 08:51:10 uebayasi Exp $"); |
32 | | | 32 | |
33 | #include "opt_xip.h" | | 33 | #include "opt_xip.h" |
34 | #include "opt_xmd.h" | | 34 | #include "opt_xmd.h" |
35 | | | 35 | |
36 | #ifndef XIP | | | |
37 | #error xmd(4) needs options XIP | | | |
38 | #endif | | | |
39 | | | | |
40 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
41 | #include <sys/bus.h> | | 37 | #include <sys/bus.h> |
42 | #include <sys/conf.h> | | 38 | #include <sys/conf.h> |
43 | #include <sys/ioctl.h> | | 39 | #include <sys/ioctl.h> |
44 | #include <sys/kmem.h> | | 40 | #include <sys/kmem.h> |
45 | #include <sys/buf.h> | | 41 | #include <sys/buf.h> |
46 | #include <sys/bufq.h> | | 42 | #include <sys/bufq.h> |
47 | #include <sys/device.h> | | 43 | #include <sys/device.h> |
48 | #include <sys/disk.h> | | 44 | #include <sys/disk.h> |
49 | #include <sys/disklabel.h> | | 45 | #include <sys/disklabel.h> |
50 | #include <sys/stat.h> | | 46 | #include <sys/stat.h> |
51 | #include <sys/mman.h> | | 47 | #include <sys/mman.h> |
52 | #include <sys/kmem.h> | | 48 | #include <sys/kmem.h> |
53 | | | 49 | |
54 | #include <machine/vmparam.h> | | 50 | #include <machine/vmparam.h> |
55 | | | 51 | |
56 | #include <dev/xmdvar.h> | | 52 | #include <uvm/uvm_extern.h> |
57 | | | 53 | |
58 | struct xmd_softc { | | 54 | struct xmd_softc { |
59 | vaddr_t sc_addr; | | 55 | vaddr_t sc_addr; |
60 | size_t sc_size; | | 56 | size_t sc_size; |
61 | | | 57 | |
62 | void *sc_phys; | | 58 | void *sc_phys; |
63 | | | 59 | |
64 | struct disk sc_dkdev; | | 60 | struct disk sc_dkdev; |
65 | struct bufq_state *sc_buflist; | | 61 | struct bufq_state *sc_buflist; |
66 | }; | | 62 | }; |
67 | | | 63 | |
68 | void xmdattach(int); | | 64 | void xmdattach(int); |
69 | static void xmd_attach(device_t, device_t, void *); | | 65 | static void xmd_attach(device_t, device_t, void *); |
| @@ -117,29 +113,27 @@ xmdattach(int n) | | | @@ -117,29 +113,27 @@ xmdattach(int n) |
117 | cf->cf_fstate = FSTATE_NOTFOUND; | | 113 | cf->cf_fstate = FSTATE_NOTFOUND; |
118 | (void)config_attach_pseudo(cf); | | 114 | (void)config_attach_pseudo(cf); |
119 | } | | 115 | } |
120 | } | | 116 | } |
121 | | | 117 | |
122 | static void | | 118 | static void |
123 | xmd_attach(device_t parent, device_t self, void *aux) | | 119 | xmd_attach(device_t parent, device_t self, void *aux) |
124 | { | | 120 | { |
125 | struct xmd_softc *sc = device_private(self); | | 121 | struct xmd_softc *sc = device_private(self); |
126 | | | 122 | |
127 | sc->sc_addr = (vaddr_t)md_root_image; | | 123 | sc->sc_addr = (vaddr_t)md_root_image; |
128 | sc->sc_size = (size_t)md_root_size; | | 124 | sc->sc_size = (size_t)md_root_size; |
129 | | | 125 | |
130 | #ifdef XIP | | 126 | sc->sc_phys = pmap_physload_device(sc->sc_addr, sc->sc_size, PROT_READ, 0); |
131 | sc->sc_phys = xmd_machdep_physload(sc->sc_addr, sc->sc_size); | | | |
132 | #endif | | | |
133 | | | 127 | |
134 | disk_init(&sc->sc_dkdev, device_xname(self), NULL); | | 128 | disk_init(&sc->sc_dkdev, device_xname(self), NULL); |
135 | disk_attach(&sc->sc_dkdev); | | 129 | disk_attach(&sc->sc_dkdev); |
136 | | | 130 | |
137 | if (!pmf_device_register(self, NULL, NULL)) | | 131 | if (!pmf_device_register(self, NULL, NULL)) |
138 | aprint_error_dev(self, "couldn't establish power handler\n"); | | 132 | aprint_error_dev(self, "couldn't establish power handler\n"); |
139 | } | | 133 | } |
140 | | | 134 | |
141 | static int | | 135 | static int |
142 | xmd_detach(device_t self, int flags) | | 136 | xmd_detach(device_t self, int flags) |
143 | { | | 137 | { |
144 | struct xmd_softc *sc = device_private(self); | | 138 | struct xmd_softc *sc = device_private(self); |
145 | int rc; | | 139 | int rc; |
| @@ -149,29 +143,27 @@ xmd_detach(device_t self, int flags) | | | @@ -149,29 +143,27 @@ xmd_detach(device_t self, int flags) |
149 | if (sc->sc_dkdev.dk_openmask == 0) | | 143 | if (sc->sc_dkdev.dk_openmask == 0) |
150 | ; /* nothing to do */ | | 144 | ; /* nothing to do */ |
151 | else if ((flags & DETACH_FORCE) == 0) | | 145 | else if ((flags & DETACH_FORCE) == 0) |
152 | rc = EBUSY; | | 146 | rc = EBUSY; |
153 | mutex_exit(&sc->sc_dkdev.dk_openlock); | | 147 | mutex_exit(&sc->sc_dkdev.dk_openlock); |
154 | | | 148 | |
155 | if (rc != 0) | | 149 | if (rc != 0) |
156 | return rc; | | 150 | return rc; |
157 | | | 151 | |
158 | pmf_device_deregister(self); | | 152 | pmf_device_deregister(self); |
159 | disk_detach(&sc->sc_dkdev); | | 153 | disk_detach(&sc->sc_dkdev); |
160 | disk_destroy(&sc->sc_dkdev); | | 154 | disk_destroy(&sc->sc_dkdev); |
161 | | | 155 | |
162 | #ifdef XIP | | 156 | pmap_physunload_device(sc->sc_phys); |
163 | xmd_machdep_physunload(sc->sc_phys); | | | |
164 | #endif | | | |
165 | | | 157 | |
166 | return 0; | | 158 | return 0; |
167 | } | | 159 | } |
168 | | | 160 | |
169 | static int | | 161 | static int |
170 | xmd_open(dev_t dev, int flags, int fmt, struct lwp *l) | | 162 | xmd_open(dev_t dev, int flags, int fmt, struct lwp *l) |
171 | { | | 163 | { |
172 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); | | 164 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); |
173 | struct disk *dk = &sc->sc_dkdev; | | 165 | struct disk *dk = &sc->sc_dkdev; |
174 | const int part = DISKUNIT(dev); | | 166 | const int part = DISKUNIT(dev); |
175 | const int pmask = 1 << part; | | 167 | const int pmask = 1 << part; |
176 | | | 168 | |
177 | if (sc == NULL) | | 169 | if (sc == NULL) |
| @@ -200,34 +192,32 @@ xmd_close(dev_t dev, int flags, int fmt, | | | @@ -200,34 +192,32 @@ xmd_close(dev_t dev, int flags, int fmt, |
200 | } | | 192 | } |
201 | | | 193 | |
202 | int | | 194 | int |
203 | xmd_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) | | 195 | xmd_ioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) |
204 | { | | 196 | { |
205 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); | | 197 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); |
206 | const int part = DISKUNIT(dev); | | 198 | const int part = DISKUNIT(dev); |
207 | int error = 0; | | 199 | int error = 0; |
208 | | | 200 | |
209 | if (sc == NULL) | | 201 | if (sc == NULL) |
210 | return -1; | | 202 | return -1; |
211 | | | 203 | |
212 | switch (cmd) { | | 204 | switch (cmd) { |
213 | #ifdef XIP | | | |
214 | case DIOCGPHYSSEG: | | 205 | case DIOCGPHYSSEG: |
215 | if (sc->sc_phys == NULL) | | 206 | if (sc->sc_phys == NULL) |
216 | error = EINVAL; | | 207 | error = EINVAL; |
217 | else | | 208 | else |
218 | *(void **)data = sc->sc_phys; | | 209 | *(void **)data = sc->sc_phys; |
219 | break; | | 210 | break; |
220 | #endif | | | |
221 | | | 211 | |
222 | case DIOCGDINFO: | | 212 | case DIOCGDINFO: |
223 | *(struct disklabel *)data = *sc->sc_dkdev.dk_label; | | 213 | *(struct disklabel *)data = *sc->sc_dkdev.dk_label; |
224 | break; | | 214 | break; |
225 | | | 215 | |
226 | case DIOCGPART: | | 216 | case DIOCGPART: |
227 | ((struct partinfo *)data)->disklab = sc->sc_dkdev.dk_label; | | 217 | ((struct partinfo *)data)->disklab = sc->sc_dkdev.dk_label; |
228 | ((struct partinfo *)data)->part = | | 218 | ((struct partinfo *)data)->part = |
229 | &sc->sc_dkdev.dk_label->d_partitions[part]; | | 219 | &sc->sc_dkdev.dk_label->d_partitions[part]; |
230 | break; | | 220 | break; |
231 | | | 221 | |
232 | default: | | 222 | default: |
233 | error = EINVAL; | | 223 | error = EINVAL; |
| @@ -251,27 +241,27 @@ xmd_read(dev_t dev, struct uio *uio, int | | | @@ -251,27 +241,27 @@ xmd_read(dev_t dev, struct uio *uio, int |
251 | } | | 241 | } |
252 | | | 242 | |
253 | paddr_t | | 243 | paddr_t |
254 | xmd_mmap(dev_t dev, off_t off, int prot) | | 244 | xmd_mmap(dev_t dev, off_t off, int prot) |
255 | { | | 245 | { |
256 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); | | 246 | struct xmd_softc *sc = device_lookup_private(&xmd_cd, DISKUNIT(dev)); |
257 | | | 247 | |
258 | if (sc == NULL) | | 248 | if (sc == NULL) |
259 | return -1; | | 249 | return -1; |
260 | | | 250 | |
261 | if ((u_int64_t)off >= sc->sc_size) | | 251 | if ((u_int64_t)off >= sc->sc_size) |
262 | return -1; | | 252 | return -1; |
263 | | | 253 | |
264 | return xmd_machdep_mmap(sc->sc_addr, off, prot); | | 254 | return pmap_mmap(sc->sc_addr, off); |
265 | } | | 255 | } |
266 | | | 256 | |
267 | static void | | 257 | static void |
268 | xmd_strategy(struct buf *bp) | | 258 | xmd_strategy(struct buf *bp) |
269 | { | | 259 | { |
270 | struct xmd_softc *sc; | | 260 | struct xmd_softc *sc; |
271 | void *addr; | | 261 | void *addr; |
272 | size_t off, count; | | 262 | size_t off, count; |
273 | | | 263 | |
274 | sc = device_lookup_private(&xmd_cd, DISKUNIT(bp->b_dev)); | | 264 | sc = device_lookup_private(&xmd_cd, DISKUNIT(bp->b_dev)); |
275 | | | 265 | |
276 | off = bp->b_blkno << DEV_BSHIFT; | | 266 | off = bp->b_blkno << DEV_BSHIFT; |
277 | | | 267 | |