| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ld_ataraid.c,v 1.44 2016/09/27 08:05:34 pgoyette Exp $ */ | | 1 | /* $NetBSD: ld_ataraid.c,v 1.45 2018/06/03 10:20:54 martin Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2003 Wasabi Systems, Inc. | | 4 | * Copyright (c) 2003 Wasabi Systems, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. | | 7 | * Written by Jason R. Thorpe for Wasabi Systems, Inc. |
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 |
| @@ -32,32 +32,32 @@ | | | @@ -32,32 +32,32 @@ |
32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
35 | * POSSIBILITY OF SUCH DAMAGE. | | 35 | * POSSIBILITY OF SUCH DAMAGE. |
36 | */ | | 36 | */ |
37 | | | 37 | |
38 | /* | | 38 | /* |
39 | * Support for ATA RAID logical disks. | | 39 | * Support for ATA RAID logical disks. |
40 | * | | 40 | * |
41 | * Note that all the RAID happens in software here; the ATA RAID | | 41 | * Note that all the RAID happens in software here; the ATA RAID |
42 | * controllers we're dealing with (Promise, etc.) only support | | 42 | * controllers we're dealing with (Promise, etc.) only support |
43 | * configuration data on the component disks, with the BIOS supporting | | 43 | * configuration data on the component disks, with the BIOS supporting |
44 | * booting from the RAID volumes. | | 44 | * booting from the RAID volumes. |
45 | * | | 45 | * |
46 | * bio(4) support was written by Juan Romero Pardines <xtraeme@gmail.com>. | | 46 | * bio(4) support was written by Juan Romero Pardines <xtraeme@gmail.com>. |
47 | */ | | 47 | */ |
48 | | | 48 | |
49 | #include <sys/cdefs.h> | | 49 | #include <sys/cdefs.h> |
50 | __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.44 2016/09/27 08:05:34 pgoyette Exp $"); | | 50 | __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.45 2018/06/03 10:20:54 martin Exp $"); |
51 | | | 51 | |
52 | #if defined(_KERNEL_OPT) | | 52 | #if defined(_KERNEL_OPT) |
53 | #include "bio.h" | | 53 | #include "bio.h" |
54 | #endif | | 54 | #endif |
55 | | | 55 | |
56 | #include <sys/param.h> | | 56 | #include <sys/param.h> |
57 | #include <sys/systm.h> | | 57 | #include <sys/systm.h> |
58 | #include <sys/conf.h> | | 58 | #include <sys/conf.h> |
59 | #include <sys/kernel.h> | | 59 | #include <sys/kernel.h> |
60 | #include <sys/device.h> | | 60 | #include <sys/device.h> |
61 | #include <sys/buf.h> | | 61 | #include <sys/buf.h> |
62 | #include <sys/bufq.h> | | 62 | #include <sys/bufq.h> |
63 | #include <sys/dkio.h> | | 63 | #include <sys/dkio.h> |
| @@ -82,31 +82,31 @@ __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c | | | @@ -82,31 +82,31 @@ __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c |
82 | | | 82 | |
83 | #include <dev/ata/ata_raidvar.h> | | 83 | #include <dev/ata/ata_raidvar.h> |
84 | | | 84 | |
85 | #include "ioconf.h" | | 85 | #include "ioconf.h" |
86 | | | 86 | |
87 | struct ld_ataraid_softc { | | 87 | struct ld_ataraid_softc { |
88 | struct ld_softc sc_ld; | | 88 | struct ld_softc sc_ld; |
89 | | | 89 | |
90 | struct ataraid_array_info *sc_aai; | | 90 | struct ataraid_array_info *sc_aai; |
91 | struct vnode *sc_vnodes[ATA_RAID_MAX_DISKS]; | | 91 | struct vnode *sc_vnodes[ATA_RAID_MAX_DISKS]; |
92 | | | 92 | |
93 | void (*sc_iodone)(struct buf *); | | 93 | void (*sc_iodone)(struct buf *); |
94 | | | 94 | |
95 | pool_cache_t sc_cbufpool; | | 95 | pool_cache_t sc_cbufpool; |
96 | | | 96 | |
97 | SIMPLEQ_HEAD(, cbuf) sc_cbufq; | | 97 | SIMPLEQ_HEAD(, cbuf) sc_cbufq; |
98 | | | 98 | |
99 | void *sc_sih_cookie; | | 99 | void *sc_sih_cookie; |
100 | }; | | 100 | }; |
101 | | | 101 | |
102 | static int ld_ataraid_match(device_t, cfdata_t, void *); | | 102 | static int ld_ataraid_match(device_t, cfdata_t, void *); |
103 | static void ld_ataraid_attach(device_t, device_t, void *); | | 103 | static void ld_ataraid_attach(device_t, device_t, void *); |
104 | | | 104 | |
105 | static int ld_ataraid_dump(struct ld_softc *, void *, int, int); | | 105 | static int ld_ataraid_dump(struct ld_softc *, void *, int, int); |
106 | | | 106 | |
107 | static int cbufpool_ctor(void *, void *, int); | | 107 | static int cbufpool_ctor(void *, void *, int); |
108 | static void cbufpool_dtor(void *, void *); | | 108 | static void cbufpool_dtor(void *, void *); |
109 | | | 109 | |
110 | static void ld_ataraid_start_vstrategy(void *); | | 110 | static void ld_ataraid_start_vstrategy(void *); |
111 | static int ld_ataraid_start_span(struct ld_softc *, struct buf *); | | 111 | static int ld_ataraid_start_span(struct ld_softc *, struct buf *); |
112 | | | 112 | |
| @@ -115,64 +115,64 @@ static void ld_ataraid_iodone_raid0(stru | | | @@ -115,64 +115,64 @@ static void ld_ataraid_iodone_raid0(stru |
115 | | | 115 | |
116 | #if NBIO > 0 | | 116 | #if NBIO > 0 |
117 | static int ld_ataraid_bioctl(device_t, u_long, void *); | | 117 | static int ld_ataraid_bioctl(device_t, u_long, void *); |
118 | static int ld_ataraid_bioinq(struct ld_ataraid_softc *, struct bioc_inq *); | | 118 | static int ld_ataraid_bioinq(struct ld_ataraid_softc *, struct bioc_inq *); |
119 | static int ld_ataraid_biovol(struct ld_ataraid_softc *, struct bioc_vol *); | | 119 | static int ld_ataraid_biovol(struct ld_ataraid_softc *, struct bioc_vol *); |
120 | static int ld_ataraid_biodisk(struct ld_ataraid_softc *, | | 120 | static int ld_ataraid_biodisk(struct ld_ataraid_softc *, |
121 | struct bioc_disk *); | | 121 | struct bioc_disk *); |
122 | #endif | | 122 | #endif |
123 | | | 123 | |
124 | CFATTACH_DECL_NEW(ld_ataraid, sizeof(struct ld_ataraid_softc), | | 124 | CFATTACH_DECL_NEW(ld_ataraid, sizeof(struct ld_ataraid_softc), |
125 | ld_ataraid_match, ld_ataraid_attach, NULL, NULL); | | 125 | ld_ataraid_match, ld_ataraid_attach, NULL, NULL); |
126 | | | 126 | |
127 | struct cbuf { | | 127 | struct cbuf { |
128 | struct buf cb_buf; /* new I/O buf */ | | 128 | struct buf cb_buf; /* new I/O buf */ |
129 | struct buf *cb_obp; /* ptr. to original I/O buf */ | | 129 | struct buf *cb_obp; /* ptr. to original I/O buf */ |
130 | struct ld_ataraid_softc *cb_sc; /* pointer to ld softc */ | | 130 | struct ld_ataraid_softc *cb_sc; /* pointer to ld softc */ |
131 | u_int cb_comp; /* target component */ | | 131 | u_int cb_comp; /* target component */ |
132 | SIMPLEQ_ENTRY(cbuf) cb_q; /* fifo of component buffers */ | | 132 | SIMPLEQ_ENTRY(cbuf) cb_q; /* fifo of component buffers */ |
133 | struct cbuf *cb_other; /* other cbuf in case of mirror */ | | 133 | struct cbuf *cb_other; /* other cbuf in case of mirror */ |
134 | int cb_flags; | | 134 | int cb_flags; |
135 | #define CBUF_IODONE 0x00000001 /* I/O is already successfully done */ | | 135 | #define CBUF_IODONE 0x00000001 /* I/O is already successfully done */ |
136 | }; | | 136 | }; |
137 | | | 137 | |
138 | #define CBUF_GET() pool_cache_get(sc->sc_cbufpool, PR_NOWAIT); | | 138 | #define CBUF_GET() pool_cache_get(sc->sc_cbufpool, PR_NOWAIT); |
139 | #define CBUF_PUT(cbp) pool_cache_put(sc->sc_cbufpool, (cbp)) | | 139 | #define CBUF_PUT(cbp) pool_cache_put(sc->sc_cbufpool, (cbp)) |
140 | | | 140 | |
141 | static int | | 141 | static int |
142 | ld_ataraid_match(device_t parent, cfdata_t match, void *aux) | | 142 | ld_ataraid_match(device_t parent, cfdata_t match, void *aux) |
143 | { | | 143 | { |
144 | | | 144 | |
145 | return (1); | | 145 | return (1); |
146 | } | | 146 | } |
147 | | | 147 | |
148 | static void | | 148 | static void |
149 | ld_ataraid_attach(device_t parent, device_t self, void *aux) | | 149 | ld_ataraid_attach(device_t parent, device_t self, void *aux) |
150 | { | | 150 | { |
151 | struct ld_ataraid_softc *sc = device_private(self); | | 151 | struct ld_ataraid_softc *sc = device_private(self); |
152 | struct ld_softc *ld = &sc->sc_ld; | | 152 | struct ld_softc *ld = &sc->sc_ld; |
153 | struct ataraid_array_info *aai = aux; | | 153 | struct ataraid_array_info *aai = aux; |
154 | struct ataraid_disk_info *adi = NULL; | | 154 | struct ataraid_disk_info *adi = NULL; |
155 | const char *level; | | 155 | const char *level; |
156 | struct vnode *vp; | | 156 | struct vnode *vp; |
157 | char unklev[32]; | | 157 | char unklev[32]; |
158 | u_int i; | | 158 | u_int i; |
159 | | | 159 | |
160 | ld->sc_dv = self; | | 160 | ld->sc_dv = self; |
161 | | | 161 | |
162 | sc->sc_cbufpool = pool_cache_init(sizeof(struct cbuf), 0, | | 162 | sc->sc_cbufpool = pool_cache_init(sizeof(struct cbuf), 0, |
163 | 0, 0, "ldcbuf", NULL, IPL_BIO, cbufpool_ctor, cbufpool_dtor, sc); | | 163 | 0, 0, "ldcbuf", NULL, IPL_BIO, cbufpool_ctor, cbufpool_dtor, sc); |
164 | sc->sc_sih_cookie = softint_establish(SOFTINT_BIO, | | 164 | sc->sc_sih_cookie = softint_establish(SOFTINT_BIO, |
165 | ld_ataraid_start_vstrategy, sc); | | 165 | ld_ataraid_start_vstrategy, sc); |
166 | | | 166 | |
167 | sc->sc_aai = aai; /* this data persists */ | | 167 | sc->sc_aai = aai; /* this data persists */ |
168 | | | 168 | |
169 | ld->sc_maxxfer = MAXPHYS * aai->aai_width; /* XXX */ | | 169 | ld->sc_maxxfer = MAXPHYS * aai->aai_width; /* XXX */ |
170 | ld->sc_secperunit = aai->aai_capacity; | | 170 | ld->sc_secperunit = aai->aai_capacity; |
171 | ld->sc_secsize = 512; /* XXX */ | | 171 | ld->sc_secsize = 512; /* XXX */ |
172 | ld->sc_maxqueuecnt = 128; /* XXX */ | | 172 | ld->sc_maxqueuecnt = 128; /* XXX */ |
173 | ld->sc_dump = ld_ataraid_dump; | | 173 | ld->sc_dump = ld_ataraid_dump; |
174 | | | 174 | |
175 | switch (aai->aai_level) { | | 175 | switch (aai->aai_level) { |
176 | case AAI_L_SPAN: | | 176 | case AAI_L_SPAN: |
177 | level = "SPAN"; | | 177 | level = "SPAN"; |
178 | ld->sc_start = ld_ataraid_start_span; | | 178 | ld->sc_start = ld_ataraid_start_span; |
| @@ -250,91 +250,91 @@ ld_ataraid_attach(device_t parent, devic | | | @@ -250,91 +250,91 @@ ld_ataraid_attach(device_t parent, devic |
250 | finish: | | 250 | finish: |
251 | #if NBIO > 0 | | 251 | #if NBIO > 0 |
252 | if (bio_register(self, ld_ataraid_bioctl) != 0) | | 252 | if (bio_register(self, ld_ataraid_bioctl) != 0) |
253 | panic("%s: bioctl registration failed\n", | | 253 | panic("%s: bioctl registration failed\n", |
254 | device_xname(ld->sc_dv)); | | 254 | device_xname(ld->sc_dv)); |
255 | #endif | | 255 | #endif |
256 | SIMPLEQ_INIT(&sc->sc_cbufq); | | 256 | SIMPLEQ_INIT(&sc->sc_cbufq); |
257 | ldattach(ld, BUFQ_DISK_DEFAULT_STRAT); | | 257 | ldattach(ld, BUFQ_DISK_DEFAULT_STRAT); |
258 | } | | 258 | } |
259 | | | 259 | |
260 | static int | | 260 | static int |
261 | cbufpool_ctor(void *arg, void *obj, int flags) | | 261 | cbufpool_ctor(void *arg, void *obj, int flags) |
262 | { | | 262 | { |
263 | struct ld_ataraid_softc *sc = arg; | | 263 | struct ld_ataraid_softc *sc = arg; |
264 | struct ld_softc *ld = &sc->sc_ld; | | 264 | struct ld_softc *ld = &sc->sc_ld; |
265 | struct cbuf *cbp = obj; | | 265 | struct cbuf *cbp = obj; |
266 | | | 266 | |
267 | /* We release/reacquire the spinlock before calling buf_init() */ | | 267 | /* We release/reacquire the spinlock before calling buf_init() */ |
268 | mutex_exit(&ld->sc_mutex); | | 268 | mutex_exit(&ld->sc_mutex); |
269 | buf_init(&cbp->cb_buf); | | 269 | buf_init(&cbp->cb_buf); |
270 | mutex_enter(&ld->sc_mutex); | | 270 | mutex_enter(&ld->sc_mutex); |
271 | | | 271 | |
272 | return 0; | | 272 | return 0; |
273 | } | | 273 | } |
274 | | | 274 | |
275 | static void | | 275 | static void |
276 | cbufpool_dtor(void *arg, void *obj) | | 276 | cbufpool_dtor(void *arg, void *obj) |
277 | { | | 277 | { |
278 | struct cbuf *cbp = obj; | | 278 | struct cbuf *cbp = obj; |
279 | | | 279 | |
280 | buf_destroy(&cbp->cb_buf); | | 280 | buf_destroy(&cbp->cb_buf); |
281 | } | | 281 | } |
282 | | | 282 | |
283 | static struct cbuf * | | 283 | static struct cbuf * |
284 | ld_ataraid_make_cbuf(struct ld_ataraid_softc *sc, struct buf *bp, | | 284 | ld_ataraid_make_cbuf(struct ld_ataraid_softc *sc, struct buf *bp, |
285 | u_int comp, daddr_t bn, void *addr, long bcount) | | 285 | u_int comp, daddr_t bn, void *addr, long bcount) |
286 | { | | 286 | { |
287 | struct cbuf *cbp; | | 287 | struct cbuf *cbp; |
288 | | | 288 | |
289 | cbp = CBUF_GET(); | | 289 | cbp = CBUF_GET(); |
290 | if (cbp == NULL) | | 290 | if (cbp == NULL) |
291 | return NULL; | | 291 | return NULL; |
292 | cbp->cb_buf.b_flags = bp->b_flags; | | 292 | cbp->cb_buf.b_flags = bp->b_flags; |
293 | cbp->cb_buf.b_oflags = bp->b_oflags; | | 293 | cbp->cb_buf.b_oflags = bp->b_oflags; |
294 | cbp->cb_buf.b_cflags = bp->b_cflags; | | 294 | cbp->cb_buf.b_cflags = bp->b_cflags; |
295 | cbp->cb_buf.b_iodone = sc->sc_iodone; | | 295 | cbp->cb_buf.b_iodone = sc->sc_iodone; |
296 | cbp->cb_buf.b_proc = bp->b_proc; | | 296 | cbp->cb_buf.b_proc = bp->b_proc; |
297 | cbp->cb_buf.b_vp = sc->sc_vnodes[comp]; | | 297 | cbp->cb_buf.b_vp = sc->sc_vnodes[comp]; |
298 | cbp->cb_buf.b_objlock = sc->sc_vnodes[comp]->v_interlock; | | 298 | cbp->cb_buf.b_objlock = sc->sc_vnodes[comp]->v_interlock; |
299 | cbp->cb_buf.b_blkno = bn + sc->sc_aai->aai_offset; | | 299 | cbp->cb_buf.b_blkno = bn + sc->sc_aai->aai_offset; |
300 | cbp->cb_buf.b_data = addr; | | 300 | cbp->cb_buf.b_data = addr; |
301 | cbp->cb_buf.b_bcount = bcount; | | 301 | cbp->cb_buf.b_bcount = bcount; |
302 | | | 302 | |
303 | /* Context for iodone */ | | 303 | /* Context for iodone */ |
304 | cbp->cb_obp = bp; | | 304 | cbp->cb_obp = bp; |
305 | cbp->cb_sc = sc; | | 305 | cbp->cb_sc = sc; |
306 | cbp->cb_comp = comp; | | 306 | cbp->cb_comp = comp; |
307 | cbp->cb_other = NULL; | | 307 | cbp->cb_other = NULL; |
308 | cbp->cb_flags = 0; | | 308 | cbp->cb_flags = 0; |
309 | | | 309 | |
310 | return cbp; | | 310 | return cbp; |
311 | } | | 311 | } |
312 | | | 312 | |
313 | static void | | 313 | static void |
314 | ld_ataraid_start_vstrategy(void *arg) | | 314 | ld_ataraid_start_vstrategy(void *arg) |
315 | { | | 315 | { |
316 | struct ld_ataraid_softc *sc = arg; | | 316 | struct ld_ataraid_softc *sc = arg; |
317 | struct cbuf *cbp; | | 317 | struct cbuf *cbp; |
318 | | | 318 | |
319 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { | | 319 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { |
320 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); | | 320 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); |
321 | if ((cbp->cb_buf.b_flags & B_READ) == 0) { | | 321 | if ((cbp->cb_buf.b_flags & B_READ) == 0) { |
322 | mutex_enter(cbp->cb_buf.b_vp->v_interlock); | | 322 | mutex_enter(cbp->cb_buf.b_vp->v_interlock); |
323 | cbp->cb_buf.b_vp->v_numoutput++; | | 323 | cbp->cb_buf.b_vp->v_numoutput++; |
324 | mutex_exit(cbp->cb_buf.b_vp->v_interlock); | | 324 | mutex_exit(cbp->cb_buf.b_vp->v_interlock); |
325 | } | | 325 | } |
326 | VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf); | | 326 | VOP_STRATEGY(cbp->cb_buf.b_vp, &cbp->cb_buf); |
327 | } | | 327 | } |
328 | } | | 328 | } |
329 | | | 329 | |
330 | static int | | 330 | static int |
331 | ld_ataraid_start_span(struct ld_softc *ld, struct buf *bp) | | 331 | ld_ataraid_start_span(struct ld_softc *ld, struct buf *bp) |
332 | { | | 332 | { |
333 | struct ld_ataraid_softc *sc = (void *) ld; | | 333 | struct ld_ataraid_softc *sc = (void *) ld; |
334 | struct ataraid_array_info *aai = sc->sc_aai; | | 334 | struct ataraid_array_info *aai = sc->sc_aai; |
335 | struct ataraid_disk_info *adi; | | 335 | struct ataraid_disk_info *adi; |
336 | struct cbuf *cbp; | | 336 | struct cbuf *cbp; |
337 | char *addr; | | 337 | char *addr; |
338 | daddr_t bn; | | 338 | daddr_t bn; |
339 | long bcount, rcount; | | 339 | long bcount, rcount; |
340 | u_int comp; | | 340 | u_int comp; |
| @@ -351,64 +351,64 @@ ld_ataraid_start_span(struct ld_softc *l | | | @@ -351,64 +351,64 @@ ld_ataraid_start_span(struct ld_softc *l |
351 | adi = &aai->aai_disks[++comp]; | | 351 | adi = &aai->aai_disks[++comp]; |
352 | } | | 352 | } |
353 | | | 353 | |
354 | bp->b_resid = bp->b_bcount; | | 354 | bp->b_resid = bp->b_bcount; |
355 | | | 355 | |
356 | for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { | | 356 | for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { |
357 | rcount = bp->b_bcount; | | 357 | rcount = bp->b_bcount; |
358 | if ((adi->adi_compsize - bn) < btodb(rcount)) | | 358 | if ((adi->adi_compsize - bn) < btodb(rcount)) |
359 | rcount = dbtob(adi->adi_compsize - bn); | | 359 | rcount = dbtob(adi->adi_compsize - bn); |
360 | | | 360 | |
361 | cbp = ld_ataraid_make_cbuf(sc, bp, comp, bn, addr, rcount); | | 361 | cbp = ld_ataraid_make_cbuf(sc, bp, comp, bn, addr, rcount); |
362 | if (cbp == NULL) { | | 362 | if (cbp == NULL) { |
363 | /* Free the already allocated component buffers. */ | | 363 | /* Free the already allocated component buffers. */ |
364 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { | | 364 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { |
365 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); | | 365 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); |
366 | CBUF_PUT(cbp); | | 366 | CBUF_PUT(cbp); |
367 | } | | 367 | } |
368 | return EAGAIN; | | 368 | return EAGAIN; |
369 | } | | 369 | } |
370 | | | 370 | |
371 | /* | | 371 | /* |
372 | * For a span, we always know we advance to the next disk, | | 372 | * For a span, we always know we advance to the next disk, |
373 | * and always start at offset 0 on that disk. | | 373 | * and always start at offset 0 on that disk. |
374 | */ | | 374 | */ |
375 | adi = &aai->aai_disks[++comp]; | | 375 | adi = &aai->aai_disks[++comp]; |
376 | bn = 0; | | 376 | bn = 0; |
377 | | | 377 | |
378 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q); | | 378 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q); |
379 | addr += rcount; | | 379 | addr += rcount; |
380 | } | | 380 | } |
381 | | | 381 | |
382 | /* Now fire off the requests. */ | | 382 | /* Now fire off the requests. */ |
383 | softint_schedule(sc->sc_sih_cookie); | | 383 | softint_schedule(sc->sc_sih_cookie); |
384 | | | 384 | |
385 | return 0; | | 385 | return 0; |
386 | } | | 386 | } |
387 | | | 387 | |
388 | static int | | 388 | static int |
389 | ld_ataraid_start_raid0(struct ld_softc *ld, struct buf *bp) | | 389 | ld_ataraid_start_raid0(struct ld_softc *ld, struct buf *bp) |
390 | { | | 390 | { |
391 | struct ld_ataraid_softc *sc = (void *)ld; | | 391 | struct ld_ataraid_softc *sc = (void *)ld; |
392 | struct ataraid_array_info *aai = sc->sc_aai; | | 392 | struct ataraid_array_info *aai = sc->sc_aai; |
393 | struct ataraid_disk_info *adi; | | 393 | struct ataraid_disk_info *adi; |
394 | struct cbuf *cbp, *other_cbp; | | 394 | struct cbuf *cbp, *other_cbp; |
395 | char *addr; | | 395 | char *addr; |
396 | daddr_t bn, cbn, tbn, off; | | 396 | daddr_t bn, cbn, tbn, off; |
397 | long bcount, rcount; | | 397 | long bcount, rcount; |
398 | u_int comp; | | 398 | u_int comp; |
399 | const int read = bp->b_flags & B_READ; | | 399 | const int read = bp->b_flags & B_READ; |
400 | const int mirror = aai->aai_level & AAI_L_RAID1; | | 400 | const int mirror = aai->aai_level & AAI_L_RAID1; |
401 | int error = 0; | | 401 | int error = 0; |
402 | | | 402 | |
403 | /* Allocate component buffers. */ | | 403 | /* Allocate component buffers. */ |
404 | addr = bp->b_data; | | 404 | addr = bp->b_data; |
405 | bn = bp->b_rawblkno; | | 405 | bn = bp->b_rawblkno; |
406 | | | 406 | |
407 | bp->b_resid = bp->b_bcount; | | 407 | bp->b_resid = bp->b_bcount; |
408 | | | 408 | |
409 | for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { | | 409 | for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) { |
410 | tbn = bn / aai->aai_interleave; | | 410 | tbn = bn / aai->aai_interleave; |
411 | off = bn % aai->aai_interleave; | | 411 | off = bn % aai->aai_interleave; |
412 | | | 412 | |
413 | if (__predict_false(tbn == aai->aai_capacity / | | 413 | if (__predict_false(tbn == aai->aai_capacity / |
414 | aai->aai_interleave)) { | | 414 | aai->aai_interleave)) { |
| @@ -441,55 +441,55 @@ try_mirror: | | | @@ -441,55 +441,55 @@ try_mirror: |
441 | /* | | 441 | /* |
442 | * No component available. | | 442 | * No component available. |
443 | */ | | 443 | */ |
444 | error = EIO; | | 444 | error = EIO; |
445 | goto free_and_exit; | | 445 | goto free_and_exit; |
446 | } | | 446 | } |
447 | | | 447 | |
448 | cbp = ld_ataraid_make_cbuf(sc, bp, comp, cbn, addr, rcount); | | 448 | cbp = ld_ataraid_make_cbuf(sc, bp, comp, cbn, addr, rcount); |
449 | if (cbp == NULL) { | | 449 | if (cbp == NULL) { |
450 | resource_shortage: | | 450 | resource_shortage: |
451 | error = EAGAIN; | | 451 | error = EAGAIN; |
452 | free_and_exit: | | 452 | free_and_exit: |
453 | /* Free the already allocated component buffers. */ | | 453 | /* Free the already allocated component buffers. */ |
454 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { | | 454 | while ((cbp = SIMPLEQ_FIRST(&sc->sc_cbufq)) != NULL) { |
455 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); | | 455 | SIMPLEQ_REMOVE_HEAD(&sc->sc_cbufq, cb_q); |
456 | CBUF_PUT(cbp); | | 456 | CBUF_PUT(cbp); |
457 | } | | 457 | } |
458 | return error; | | 458 | return error; |
459 | } | | 459 | } |
460 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q); | | 460 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, cbp, cb_q); |
461 | if (mirror && !read && comp < aai->aai_width) { | | 461 | if (mirror && !read && comp < aai->aai_width) { |
462 | comp += aai->aai_width; | | 462 | comp += aai->aai_width; |
463 | adi = &aai->aai_disks[comp]; | | 463 | adi = &aai->aai_disks[comp]; |
464 | if (adi->adi_status & ADI_S_ONLINE) { | | 464 | if (adi->adi_status & ADI_S_ONLINE) { |
465 | other_cbp = ld_ataraid_make_cbuf(sc, bp, | | 465 | other_cbp = ld_ataraid_make_cbuf(sc, bp, |
466 | comp, cbn, addr, rcount); | | 466 | comp, cbn, addr, rcount); |
467 | if (other_cbp == NULL) | | 467 | if (other_cbp == NULL) |
468 | goto resource_shortage; | | 468 | goto resource_shortage; |
469 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, | | 469 | SIMPLEQ_INSERT_TAIL(&sc->sc_cbufq, |
470 | other_cbp, cb_q); | | 470 | other_cbp, cb_q); |
471 | other_cbp->cb_other = cbp; | | 471 | other_cbp->cb_other = cbp; |
472 | cbp->cb_other = other_cbp; | | 472 | cbp->cb_other = other_cbp; |
473 | } | | 473 | } |
474 | } | | 474 | } |
475 | bn += btodb(rcount); | | 475 | bn += btodb(rcount); |
476 | addr += rcount; | | 476 | addr += rcount; |
477 | } | | 477 | } |
478 | | | 478 | |
479 | /* Now fire off the requests. */ | | 479 | /* Now fire off the requests. */ |
480 | softint_schedule(sc->sc_sih_cookie); | | 480 | softint_schedule(sc->sc_sih_cookie); |
481 | | | 481 | |
482 | return error; | | 482 | return error; |
483 | } | | 483 | } |
484 | | | 484 | |
485 | /* | | 485 | /* |
486 | * Called at interrupt time. Mark the component as done and if all | | 486 | * Called at interrupt time. Mark the component as done and if all |
487 | * components are done, take an "interrupt". | | 487 | * components are done, take an "interrupt". |
488 | */ | | 488 | */ |
489 | static void | | 489 | static void |
490 | ld_ataraid_iodone_raid0(struct buf *vbp) | | 490 | ld_ataraid_iodone_raid0(struct buf *vbp) |
491 | { | | 491 | { |
492 | struct cbuf *cbp = (struct cbuf *) vbp, *other_cbp; | | 492 | struct cbuf *cbp = (struct cbuf *) vbp, *other_cbp; |
493 | struct buf *bp = cbp->cb_obp; | | 493 | struct buf *bp = cbp->cb_obp; |
494 | struct ld_ataraid_softc *sc = cbp->cb_sc; | | 494 | struct ld_ataraid_softc *sc = cbp->cb_sc; |
495 | struct ataraid_array_info *aai = sc->sc_aai; | | 495 | struct ataraid_array_info *aai = sc->sc_aai; |
| @@ -612,27 +612,27 @@ ld_ataraid_bioinq(struct ld_ataraid_soft | | | @@ -612,27 +612,27 @@ ld_ataraid_bioinq(struct ld_ataraid_soft |
612 | | | 612 | |
613 | /* there's always one volume per ld device */ | | 613 | /* there's always one volume per ld device */ |
614 | bi->bi_novol = 1; | | 614 | bi->bi_novol = 1; |
615 | bi->bi_nodisk = aai->aai_ndisks; | | 615 | bi->bi_nodisk = aai->aai_ndisks; |
616 | | | 616 | |
617 | return 0; | | 617 | return 0; |
618 | } | | 618 | } |
619 | | | 619 | |
620 | static int | | 620 | static int |
621 | ld_ataraid_biovol(struct ld_ataraid_softc *sc, struct bioc_vol *bv) | | 621 | ld_ataraid_biovol(struct ld_ataraid_softc *sc, struct bioc_vol *bv) |
622 | { | | 622 | { |
623 | struct ataraid_array_info *aai = sc->sc_aai; | | 623 | struct ataraid_array_info *aai = sc->sc_aai; |
624 | struct ld_softc *ld = &sc->sc_ld; | | 624 | struct ld_softc *ld = &sc->sc_ld; |
625 | #define to_kibytes(ld,s) (ld->sc_secsize*(s)/1024) | | 625 | #define to_kibytes(ld,s) (ld->sc_secsize*(s)/1024) |
626 | | | 626 | |
627 | /* Fill in data for _this_ volume */ | | 627 | /* Fill in data for _this_ volume */ |
628 | bv->bv_percent = -1; | | 628 | bv->bv_percent = -1; |
629 | bv->bv_seconds = 0; | | 629 | bv->bv_seconds = 0; |
630 | | | 630 | |
631 | switch (aai->aai_status) { | | 631 | switch (aai->aai_status) { |
632 | case AAI_S_READY: | | 632 | case AAI_S_READY: |
633 | bv->bv_status = BIOC_SVONLINE; | | 633 | bv->bv_status = BIOC_SVONLINE; |
634 | break; | | 634 | break; |
635 | case AAI_S_DEGRADED: | | 635 | case AAI_S_DEGRADED: |
636 | bv->bv_status = BIOC_SVDEGRADED; | | 636 | bv->bv_status = BIOC_SVDEGRADED; |
637 | break; | | 637 | break; |
638 | } | | 638 | } |
| @@ -713,27 +713,27 @@ ld_ataraid_biodisk(struct ld_ataraid_sof | | | @@ -713,27 +713,27 @@ ld_ataraid_biodisk(struct ld_ataraid_sof |
713 | strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial)); | | 713 | strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial)); |
714 | | | 714 | |
715 | return 0; | | 715 | return 0; |
716 | } | | 716 | } |
717 | #endif /* NBIO > 0 */ | | 717 | #endif /* NBIO > 0 */ |
718 | | | 718 | |
719 | MODULE(MODULE_CLASS_DRIVER, ld_ataraid, "ld,ataraid"); | | 719 | MODULE(MODULE_CLASS_DRIVER, ld_ataraid, "ld,ataraid"); |
720 | | | 720 | |
721 | #ifdef _MODULE | | 721 | #ifdef _MODULE |
722 | /* | | 722 | /* |
723 | * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_ataraid" | | 723 | * XXX Don't allow ioconf.c to redefine the "struct cfdriver ld_ataraid" |
724 | * XXX it will be defined in the common-code module | | 724 | * XXX it will be defined in the common-code module |
725 | */ | | 725 | */ |
726 | #undef CFDRIVER_DECL | | 726 | #undef CFDRIVER_DECL |
727 | #define CFDRIVER_DECL(name, class, attr) | | 727 | #define CFDRIVER_DECL(name, class, attr) |
728 | #include "ioconf.c" | | 728 | #include "ioconf.c" |
729 | #endif | | 729 | #endif |
730 | | | 730 | |
731 | static int | | 731 | static int |
732 | ld_ataraid_modcmd(modcmd_t cmd, void *opaque) | | 732 | ld_ataraid_modcmd(modcmd_t cmd, void *opaque) |
733 | { | | 733 | { |
734 | #ifdef _MODULE | | 734 | #ifdef _MODULE |
735 | /* | | 735 | /* |
736 | * We ignore the cfdriver_vec[] that ioconf provides, since | | 736 | * We ignore the cfdriver_vec[] that ioconf provides, since |
737 | * the cfdrivers are attached already. | | 737 | * the cfdrivers are attached already. |
738 | */ | | 738 | */ |
739 | static struct cfdriver * const no_cfdriver_vec[] = { NULL }; | | 739 | static struct cfdriver * const no_cfdriver_vec[] = { NULL }; |