32703b3e50283e0c1298147e5093394091d840ef
[dragonfly.git] / sys / dev / disk / ccd / ccd.c
1 /*
2  * Copyright (c) 2007 The DragonFly Project.  All rights reserved.
3  * 
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@backplane.com>
6  * 
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  * 3. Neither the name of The DragonFly Project nor the names of its
18  *    contributors may be used to endorse or promote products derived
19  *    from this software without specific, prior written permission.
20  * 
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  * 
34  * $DragonFly: src/sys/dev/disk/ccd/ccd.c,v 1.48 2007/06/19 19:09:46 dillon Exp $
35  */
36 /*
37  * Copyright (c) 1995 Jason R. Thorpe.
38  * All rights reserved.
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. All advertising materials mentioning features or use of this software
49  *    must display the following acknowledgement:
50  *      This product includes software developed for the NetBSD Project
51  *      by Jason R. Thorpe.
52  * 4. The name of the author may not be used to endorse or promote products
53  *    derived from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
58  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
59  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
60  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
61  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
62  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
63  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
65  * SUCH DAMAGE.
66  */
67
68 /*
69  * Copyright (c) 1988 University of Utah.
70  * Copyright (c) 1990, 1993
71  *      The Regents of the University of California.  All rights reserved.
72  *
73  * This code is derived from software contributed to Berkeley by
74  * the Systems Programming Group of the University of Utah Computer
75  * Science Department.
76  *
77  * Redistribution and use in source and binary forms, with or without
78  * modification, are permitted provided that the following conditions
79  * are met:
80  * 1. Redistributions of source code must retain the above copyright
81  *    notice, this list of conditions and the following disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  *    notice, this list of conditions and the following disclaimer in the
84  *    documentation and/or other materials provided with the distribution.
85  * 3. All advertising materials mentioning features or use of this software
86  *    must display the following acknowledgement:
87  *      This product includes software developed by the University of
88  *      California, Berkeley and its contributors.
89  * 4. Neither the name of the University nor the names of its contributors
90  *    may be used to endorse or promote products derived from this software
91  *    without specific prior written permission.
92  *
93  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
94  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
95  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
96  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
97  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
98  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
99  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
101  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
102  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
103  * SUCH DAMAGE.
104  *
105  * from: Utah $Hdr: cd.c 1.6 90/11/28$
106  */
107 /*
108  * @(#)cd.c     8.2 (Berkeley) 11/16/93
109  * $FreeBSD: src/sys/dev/ccd/ccd.c,v 1.73.2.1 2001/09/11 09:49:52 kris Exp $
110  * $NetBSD: ccd.c,v 1.22 1995/12/08 19:13:26 thorpej Exp $
111  * $DragonFly: src/sys/dev/disk/ccd/ccd.c,v 1.48 2007/06/19 19:09:46 dillon Exp $
112  */
113
114 /*
115  * "Concatenated" disk driver.
116  *
117  * Original dynamic configuration support by:
118  *      Jason R. Thorpe <thorpej@nas.nasa.gov>
119  *      Numerical Aerodynamic Simulation Facility
120  *      Mail Stop 258-6
121  *      NASA Ames Research Center
122  *      Moffett Field, CA 94035
123  */
124
125 #include "use_ccd.h"
126
127 #include <sys/param.h>
128 #include <sys/systm.h>
129 #include <sys/kernel.h>
130 #include <sys/module.h>
131 #include <sys/proc.h>
132 #include <sys/buf.h>
133 #include <sys/malloc.h>
134 #include <sys/nlookup.h>
135 #include <sys/conf.h>
136 #include <sys/stat.h>
137 #include <sys/sysctl.h>
138 #include <sys/disk.h>
139 #include <sys/dtype.h>
140 #include <sys/diskslice.h>
141 #include <sys/devicestat.h>
142 #include <sys/fcntl.h>
143 #include <sys/vnode.h>
144 #include <sys/buf2.h>
145 #include <sys/ccdvar.h>
146
147 #include <vm/vm_zone.h>
148
149 #include <vfs/ufs/dinode.h>     /* XXX Used only for fs.h */
150 #include <vfs/ufs/fs.h>         /* XXX used only to get BBSIZE and SBSIZE */
151
152 #include <sys/thread2.h>
153
154 #if defined(CCDDEBUG) && !defined(DEBUG)
155 #define DEBUG
156 #endif
157
158 #ifdef DEBUG
159 #define CCDB_FOLLOW     0x01
160 #define CCDB_INIT       0x02
161 #define CCDB_IO         0x04
162 #define CCDB_LABEL      0x08
163 #define CCDB_VNODE      0x10
164 static int ccddebug = CCDB_FOLLOW | CCDB_INIT | CCDB_IO | CCDB_LABEL |
165     CCDB_VNODE;
166 SYSCTL_INT(_debug, OID_AUTO, ccddebug, CTLFLAG_RW, &ccddebug, 0, "");
167 #undef DEBUG
168 #endif
169
170 #define ccdunit(x)      dkunit(x)
171 #define ccdpart(x)      dkpart(x)
172
173 /*
174    This is how mirroring works (only writes are special):
175
176    When initiating a write, ccdbuffer() returns two "struct ccdbuf *"s
177    linked together by the cb_mirror field.  "cb_pflags &
178    CCDPF_MIRROR_DONE" is set to 0 on both of them.
179
180    When a component returns to ccdiodone(), it checks if "cb_pflags &
181    CCDPF_MIRROR_DONE" is set or not.  If not, it sets the partner's
182    flag and returns.  If it is, it means its partner has already
183    returned, so it will go to the regular cleanup.
184
185  */
186
187 struct ccdbuf {
188         struct buf      cb_buf;         /* new I/O buf */
189         struct vnode    *cb_vp;         /* related vnode */
190         struct bio      *cb_obio;       /* ptr. to original I/O buf */
191         struct ccdbuf   *cb_freenext;   /* free list link */
192         int             cb_unit;        /* target unit */
193         int             cb_comp;        /* target component */
194         int             cb_pflags;      /* mirror/parity status flag */
195         struct ccdbuf   *cb_mirror;     /* mirror counterpart */
196 };
197
198 /* bits in cb_pflags */
199 #define CCDPF_MIRROR_DONE 1     /* if set, mirror counterpart is done */
200
201 static d_open_t ccdopen;
202 static d_close_t ccdclose;
203 static d_strategy_t ccdstrategy;
204 static d_ioctl_t ccdioctl;
205 static d_dump_t ccddump;
206
207 #define NCCDFREEHIWAT   16
208
209 #define CDEV_MAJOR 74
210
211 static struct dev_ops ccd_ops = {
212         { "ccd", CDEV_MAJOR, D_DISK },
213         .d_open =       ccdopen,
214         .d_close =      ccdclose,
215         .d_read =       physread,
216         .d_write =      physwrite,
217         .d_ioctl =      ccdioctl,
218         .d_strategy =   ccdstrategy,
219         .d_dump =       ccddump
220 };
221
222 /* called during module initialization */
223 static  void ccdattach (void);
224 static  int ccd_modevent (module_t, int, void *);
225
226 /* called by biodone() at interrupt time */
227 static  void ccdiodone (struct bio *bio);
228
229 static  void ccdstart (struct ccd_softc *, struct bio *);
230 static  void ccdinterleave (struct ccd_softc *, int);
231 static  void ccdintr (struct ccd_softc *, struct bio *);
232 static  int ccdinit (struct ccddevice *, char **, struct ucred *);
233 static  int ccdlookup (char *, struct vnode **);
234 static  void ccdbuffer (struct ccdbuf **ret, struct ccd_softc *,
235                 struct bio *, off_t, caddr_t, long);
236 static  int ccdlock (struct ccd_softc *);
237 static  void ccdunlock (struct ccd_softc *);
238
239 #ifdef DEBUG
240 static  void printiinfo (struct ccdiinfo *);
241 #endif
242
243 /* Non-private for the benefit of libkvm. */
244 struct  ccd_softc *ccd_softc;
245 struct  ccddevice *ccddevs;
246 struct  ccdbuf *ccdfreebufs;
247 static  int numccdfreebufs;
248 static  int numccd = 0;
249
250 /*
251  * getccdbuf() -        Allocate and zero a ccd buffer.
252  *
253  *      This routine is called at splbio().
254  */
255
256 static __inline
257 struct ccdbuf *
258 getccdbuf(void)
259 {
260         struct ccdbuf *cbp;
261
262         /*
263          * Allocate from freelist or malloc as necessary
264          */
265         if ((cbp = ccdfreebufs) != NULL) {
266                 ccdfreebufs = cbp->cb_freenext;
267                 --numccdfreebufs;
268                 reinitbufbio(&cbp->cb_buf);
269         } else {
270                 cbp = kmalloc(sizeof(struct ccdbuf), M_DEVBUF, M_WAITOK|M_ZERO);
271                 initbufbio(&cbp->cb_buf);
272         }
273
274         /*
275          * independant struct buf initialization
276          */
277         LIST_INIT(&cbp->cb_buf.b_dep);
278         BUF_LOCKINIT(&cbp->cb_buf);
279         BUF_LOCK(&cbp->cb_buf, LK_EXCLUSIVE);
280         BUF_KERNPROC(&cbp->cb_buf);
281         cbp->cb_buf.b_flags = B_PAGING | B_BNOCLIP;
282
283         return(cbp);
284 }
285
286 /*
287  * putccdbuf() -        Free a ccd buffer.
288  *
289  *      This routine is called at splbio().
290  */
291
292 static __inline
293 void
294 putccdbuf(struct ccdbuf *cbp)
295 {
296         BUF_UNLOCK(&cbp->cb_buf);
297         BUF_LOCKFREE(&cbp->cb_buf);
298
299         if (numccdfreebufs < NCCDFREEHIWAT) {
300                 cbp->cb_freenext = ccdfreebufs;
301                 ccdfreebufs = cbp;
302                 ++numccdfreebufs;
303         } else {
304                 kfree((caddr_t)cbp, M_DEVBUF);
305         }
306 }
307
308 /*
309  * Called by main() during pseudo-device attachment.  All we need
310  * to do is allocate enough space for devices to be configured later, and
311  * add devsw entries.
312  */
313 static void
314 ccdattach(void)
315 {
316         struct disk_info info;
317         struct ccd_softc *cs;
318         int i;
319         int num = NCCD;
320
321         if (num > 1)
322                 kprintf("ccd0-%d: Concatenated disk drivers\n", num-1);
323         else
324                 kprintf("ccd0: Concatenated disk driver\n");
325
326         ccd_softc = kmalloc(num * sizeof(struct ccd_softc), M_DEVBUF, 
327                             M_WAITOK | M_ZERO);
328         ccddevs = kmalloc(num * sizeof(struct ccddevice), M_DEVBUF,
329                             M_WAITOK | M_ZERO);
330         numccd = num;
331
332         /*
333          * With normal disk devices the open simply fails if the media
334          * is not present.  With CCD we have to be able to open the
335          * raw disk to use the ioctl's to set it up, so create a dummy
336          * disk info structure so dscheck() doesn't blow up.
337          */
338         bzero(&info, sizeof(info));
339         info.d_media_blksize = DEV_BSIZE;
340
341         for (i = 0; i < numccd; ++i) {
342                 cs = &ccd_softc[i];
343                 cs->sc_dev = disk_create(i, &cs->sc_disk, &ccd_ops);
344                 cs->sc_dev->si_drv1 = cs;
345                 cs->sc_dev->si_iosize_max = 256 * 512;  /* XXX */
346                 disk_setdiskinfo(&cs->sc_disk, &info);
347         }
348 }
349
350 static int
351 ccd_modevent(module_t mod, int type, void *data)
352 {
353         int error = 0;
354
355         switch (type) {
356         case MOD_LOAD:
357                 ccdattach();
358                 break;
359
360         case MOD_UNLOAD:
361                 kprintf("ccd0: Unload not supported!\n");
362                 error = EOPNOTSUPP;
363                 break;
364
365         default:        /* MOD_SHUTDOWN etc */
366                 break;
367         }
368         return (error);
369 }
370
371 DEV_MODULE(ccd, ccd_modevent, NULL);
372
373 static int
374 ccdinit(struct ccddevice *ccd, char **cpaths, struct ucred *cred)
375 {
376         struct ccd_softc *cs = &ccd_softc[ccd->ccd_unit];
377         struct ccdcinfo *ci = NULL;     /* XXX */
378         int ix;
379         struct vnode *vp;
380         u_int64_t skip;
381         u_int64_t size;
382         u_int64_t minsize;
383         int maxsecsize;
384         struct partinfo dpart;
385         struct ccdgeom *ccg = &cs->sc_geom;
386         char tmppath[MAXPATHLEN];
387         int error = 0;
388
389 #ifdef DEBUG
390         if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
391                 kprintf("ccdinit: unit %d\n", ccd->ccd_unit);
392 #endif
393
394         cs->sc_size = 0;
395         cs->sc_ileave = ccd->ccd_interleave;
396         cs->sc_nccdisks = ccd->ccd_ndev;
397
398         /* Allocate space for the component info. */
399         cs->sc_cinfo = kmalloc(cs->sc_nccdisks * sizeof(struct ccdcinfo),
400                                 M_DEVBUF, M_WAITOK);
401
402         /*
403          * Verify that each component piece exists and record
404          * relevant information about it.
405          */
406         maxsecsize = 0;
407         minsize = 0;
408         for (ix = 0; ix < cs->sc_nccdisks; ix++) {
409                 vp = ccd->ccd_vpp[ix];
410                 ci = &cs->sc_cinfo[ix];
411                 ci->ci_vp = vp;
412
413                 /*
414                  * Copy in the pathname of the component.
415                  */
416                 bzero(tmppath, sizeof(tmppath));        /* sanity */
417                 if ((error = copyinstr(cpaths[ix], tmppath,
418                     MAXPATHLEN, &ci->ci_pathlen)) != 0) {
419 #ifdef DEBUG
420                         if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
421                                 kprintf("ccd%d: can't copy path, error = %d\n",
422                                     ccd->ccd_unit, error);
423 #endif
424                         goto fail;
425                 }
426                 ci->ci_path = kmalloc(ci->ci_pathlen, M_DEVBUF, M_WAITOK);
427                 bcopy(tmppath, ci->ci_path, ci->ci_pathlen);
428
429                 ci->ci_dev = vn_todev(vp);
430
431                 /*
432                  * Get partition information for the component.
433                  */
434                 error = VOP_IOCTL(vp, DIOCGPART, (caddr_t)&dpart, FREAD, cred);
435                 if (error) {
436 #ifdef DEBUG
437                         if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
438                                  kprintf("ccd%d: %s: ioctl failed, error = %d\n",
439                                      ccd->ccd_unit, ci->ci_path, error);
440 #endif
441                         goto fail;
442                 }
443                 if (dpart.fstype != FS_CCD && 
444                     !kuuid_is_ccd(&dpart.fstype_uuid)) {
445                         kprintf("ccd%d: %s: filesystem type must be 'ccd'\n",
446                                 ccd->ccd_unit, ci->ci_path);
447                         error = EFTYPE;
448                         goto fail;
449                 }
450                 if (maxsecsize < dpart.media_blksize)
451                         maxsecsize = dpart.media_blksize;
452
453                 /*
454                  * Skip a certain amount of storage at the beginning of
455                  * the component to make sure we don't infringe on any
456                  * reserved sectors.  This is handled entirely by
457                  * dpart.reserved_blocks but we also impose a minimum
458                  * of 16 sectors for backwards compatibility.
459                  */
460                 skip = 16;
461                 if (skip < dpart.reserved_blocks)
462                         skip = dpart.reserved_blocks;
463                 size = dpart.media_blocks - skip;
464
465                 /*
466                  * Calculate the size, truncating to an interleave
467                  * boundary if necessary.
468                  */
469                 if (cs->sc_ileave > 1)
470                         size -= size % cs->sc_ileave;
471
472                 if ((int64_t)size <= 0) {
473 #ifdef DEBUG
474                         if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
475                                 kprintf("ccd%d: %s: size == 0\n",
476                                     ccd->ccd_unit, ci->ci_path);
477 #endif
478                         error = ENODEV;
479                         goto fail;
480                 }
481
482                 /*
483                  * Calculate the smallest uniform component, used
484                  * elsewhere.
485                  */
486                 if (minsize == 0 || minsize > size)
487                         minsize = size;
488                 ci->ci_skip = skip;
489                 ci->ci_size = size;
490                 cs->sc_size += size;
491         }
492
493         /*
494          * Don't allow the interleave to be smaller than
495          * the biggest component sector.
496          */
497         if ((cs->sc_ileave > 0) &&
498             (cs->sc_ileave % (maxsecsize / DEV_BSIZE))) {
499 #ifdef DEBUG
500                 if (ccddebug & (CCDB_FOLLOW|CCDB_INIT))
501                         kprintf("ccd%d: interleave must be at least %d\n",
502                             ccd->ccd_unit, (maxsecsize / DEV_BSIZE));
503 #endif
504                 error = EINVAL;
505                 goto fail;
506         }
507
508         /*
509          * If uniform interleave is desired set all sizes to that of
510          * the smallest component.  This will guarentee that a single
511          * interleave table is generated.
512          *
513          * Lost space must be taken into account when calculating the
514          * overall size.  Half the space is lost when CCDF_MIRROR is
515          * specified.  One disk is lost when CCDF_PARITY is specified.
516          */
517         if (ccd->ccd_flags & CCDF_UNIFORM) {
518                 for (ci = cs->sc_cinfo;
519                      ci < &cs->sc_cinfo[cs->sc_nccdisks]; ci++) {
520                         ci->ci_size = minsize;
521                 }
522                 if (ccd->ccd_flags & CCDF_MIRROR) {
523                         /*
524                          * Check to see if an even number of components
525                          * have been specified.  The interleave must also
526                          * be non-zero in order for us to be able to 
527                          * guarentee the topology.
528                          */
529                         if (cs->sc_nccdisks % 2) {
530                                 kprintf("ccd%d: mirroring requires an even number of disks\n", ccd->ccd_unit );
531                                 error = EINVAL;
532                                 goto fail;
533                         }
534                         if (cs->sc_ileave == 0) {
535                                 kprintf("ccd%d: an interleave must be specified when mirroring\n", ccd->ccd_unit);
536                                 error = EINVAL;
537                                 goto fail;
538                         }
539                         cs->sc_size = (cs->sc_nccdisks/2) * minsize;
540                 } else if (ccd->ccd_flags & CCDF_PARITY) {
541                         cs->sc_size = (cs->sc_nccdisks-1) * minsize;
542                 } else {
543                         if (cs->sc_ileave == 0) {
544                                 kprintf("ccd%d: an interleave must be specified when using parity\n", ccd->ccd_unit);
545                                 error = EINVAL;
546                                 goto fail;
547                         }
548                         cs->sc_size = cs->sc_nccdisks * minsize;
549                 }
550         }
551
552         /*
553          * Construct the interleave table.
554          */
555         ccdinterleave(cs, ccd->ccd_unit);
556
557         /*
558          * Create pseudo-geometry based on 1MB cylinders.  It's
559          * pretty close.
560          */
561         ccg->ccg_secsize = maxsecsize;
562         ccg->ccg_ntracks = 1;
563         ccg->ccg_nsectors = 1024 * 1024 / ccg->ccg_secsize;
564         ccg->ccg_ncylinders = cs->sc_size / ccg->ccg_nsectors;
565
566         /*
567          * Add an devstat entry for this device.
568          */
569         devstat_add_entry(&cs->device_stats, "ccd", ccd->ccd_unit,
570                           ccg->ccg_secsize, DEVSTAT_ALL_SUPPORTED,
571                           DEVSTAT_TYPE_STORARRAY |DEVSTAT_TYPE_IF_OTHER,
572                           DEVSTAT_PRIORITY_ARRAY);
573
574         cs->sc_flags |= CCDF_INITED;
575         cs->sc_cflags = ccd->ccd_flags; /* So we can find out later... */
576         cs->sc_unit = ccd->ccd_unit;
577         return (0);
578 fail:
579         while (ci > cs->sc_cinfo) {
580                 ci--;
581                 kfree(ci->ci_path, M_DEVBUF);
582         }
583         kfree(cs->sc_cinfo, M_DEVBUF);
584         cs->sc_cinfo = NULL;
585         return (error);
586 }
587
588 static void
589 ccdinterleave(struct ccd_softc *cs, int unit)
590 {
591         struct ccdcinfo *ci, *smallci;
592         struct ccdiinfo *ii;
593         u_int64_t bn;
594         u_int64_t lbn;
595         u_int64_t size;
596         int icount;
597         int ix;
598
599 #ifdef DEBUG
600         if (ccddebug & CCDB_INIT)
601                 kprintf("ccdinterleave(%x): ileave %d\n", cs, cs->sc_ileave);
602 #endif
603
604         /*
605          * Allocate an interleave table.  The worst case occurs when each
606          * of N disks is of a different size, resulting in N interleave
607          * tables.
608          *
609          * Chances are this is too big, but we don't care.
610          */
611         icount = cs->sc_nccdisks + 1;
612         cs->sc_itable = kmalloc(icount * sizeof(struct ccdiinfo),
613                                 M_DEVBUF, M_WAITOK|M_ZERO);
614
615         /*
616          * Trivial case: no interleave (actually interleave of disk size).
617          * Each table entry represents a single component in its entirety.
618          *
619          * An interleave of 0 may not be used with a mirror or parity setup.
620          */
621         if (cs->sc_ileave == 0) {
622                 bn = 0;
623                 ii = cs->sc_itable;
624
625                 for (ix = 0; ix < cs->sc_nccdisks; ix++) {
626                         /* Allocate space for ii_index. */
627                         ii->ii_index = kmalloc(sizeof(int), M_DEVBUF, M_WAITOK);
628                         ii->ii_ndisk = 1;
629                         ii->ii_startblk = bn;
630                         ii->ii_startoff = 0;
631                         ii->ii_index[0] = ix;
632                         bn += cs->sc_cinfo[ix].ci_size;
633                         ii++;
634                 }
635                 ii->ii_ndisk = 0;
636 #ifdef DEBUG
637                 if (ccddebug & CCDB_INIT)
638                         printiinfo(cs->sc_itable);
639 #endif
640                 return;
641         }
642
643         /*
644          * The following isn't fast or pretty; it doesn't have to be.
645          */
646         size = 0;
647         bn = lbn = 0;
648         for (ii = cs->sc_itable; ii < &cs->sc_itable[icount]; ++ii) {
649                 /*
650                  * Allocate space for ii_index.  We might allocate more then
651                  * we use.
652                  */
653                 ii->ii_index = kmalloc((sizeof(int) * cs->sc_nccdisks),
654                                         M_DEVBUF, M_WAITOK);
655
656                 /*
657                  * Locate the smallest of the remaining components
658                  */
659                 smallci = NULL;
660                 ci = cs->sc_cinfo;
661                 while (ci < &cs->sc_cinfo[cs->sc_nccdisks]) {
662                         if (ci->ci_size > size &&
663                             (smallci == NULL ||
664                              ci->ci_size < smallci->ci_size)) {
665                                 smallci = ci;
666                         }
667                         ++ci;
668                 }
669
670                 /*
671                  * Nobody left, all done
672                  */
673                 if (smallci == NULL) {
674                         ii->ii_ndisk = 0;
675                         break;
676                 }
677
678                 /*
679                  * Record starting logical block using an sc_ileave blocksize.
680                  */
681                 ii->ii_startblk = bn / cs->sc_ileave;
682
683                 /*
684                  * Record starting component block using an sc_ileave 
685                  * blocksize.  This value is relative to the beginning of
686                  * a component disk.
687                  */
688                 ii->ii_startoff = lbn;
689
690                 /*
691                  * Determine how many disks take part in this interleave
692                  * and record their indices.
693                  */
694                 ix = 0;
695                 for (ci = cs->sc_cinfo; 
696                     ci < &cs->sc_cinfo[cs->sc_nccdisks]; ci++) {
697                         if (ci->ci_size >= smallci->ci_size) {
698                                 ii->ii_index[ix++] = ci - cs->sc_cinfo;
699                         }
700                 }
701                 ii->ii_ndisk = ix;
702
703                 /*
704                  * Adjust for loop
705                  */
706                 bn += ix * (smallci->ci_size - size);
707                 lbn = smallci->ci_size / cs->sc_ileave;
708                 size = smallci->ci_size;
709         }
710         if (ii == &cs->sc_itable[icount])
711                 panic("ccdinterlave software bug!  table exhausted");
712 #ifdef DEBUG
713         if (ccddebug & CCDB_INIT)
714                 printiinfo(cs->sc_itable);
715 #endif
716 }
717
718 /* ARGSUSED */
719 static int
720 ccdopen(struct dev_open_args *ap)
721 {
722         cdev_t dev = ap->a_head.a_dev;
723         int unit = ccdunit(dev);
724         struct ccd_softc *cs;
725         int error = 0;
726
727 #ifdef DEBUG
728         if (ccddebug & CCDB_FOLLOW)
729                 kprintf("ccdopen(%x, %x)\n", dev, flags);
730 #endif
731         if (unit >= numccd)
732                 return (ENXIO);
733         cs = &ccd_softc[unit];
734
735         if ((error = ccdlock(cs)) == 0) {
736                 ccdunlock(cs);
737         }
738         return (error);
739 }
740
741 /* ARGSUSED */
742 static int
743 ccdclose(struct dev_close_args *ap)
744 {
745         cdev_t dev = ap->a_head.a_dev;
746         int unit = ccdunit(dev);
747         struct ccd_softc *cs;
748         int error = 0;
749
750 #ifdef DEBUG
751         if (ccddebug & CCDB_FOLLOW)
752                 kprintf("ccdclose(%x, %x)\n", dev, flags);
753 #endif
754
755         if (unit >= numccd)
756                 return (ENXIO);
757         cs = &ccd_softc[unit];
758         if ((error = ccdlock(cs)) == 0) {
759                 ccdunlock(cs);
760         }
761         return (error);
762 }
763
764 static int
765 ccdstrategy(struct dev_strategy_args *ap)
766 {
767         cdev_t dev = ap->a_head.a_dev;
768         struct bio *bio = ap->a_bio;
769         int unit = ccdunit(dev);
770         struct bio *nbio;
771         struct buf *bp = bio->bio_buf;
772         struct ccd_softc *cs = &ccd_softc[unit];
773         u_int64_t pbn;  /* in sc_secsize chunks */
774         u_int32_t sz;   /* in sc_secsize chunks */
775
776 #ifdef DEBUG
777         if (ccddebug & CCDB_FOLLOW)
778                 kprintf("ccdstrategy(%x): unit %d\n", bp, unit);
779 #endif
780         if ((cs->sc_flags & CCDF_INITED) == 0) {
781                 bp->b_error = ENXIO;
782                 goto error;
783         }
784
785         /* If it's a nil transfer, wake up the top half now. */
786         if (bp->b_bcount == 0) {
787                 bp->b_resid = 0;
788                 goto done;
789         }
790
791         /*
792          * Do bounds checking and adjust transfer.  If there's an
793          * error, the bounds check will flag that for us.
794          */
795
796         pbn = bio->bio_offset / cs->sc_geom.ccg_secsize;
797         sz = howmany(bp->b_bcount, cs->sc_geom.ccg_secsize);
798
799         /*
800          * If out of bounds return an error.  If the request goes
801          * past EOF, clip the request as appropriate.  If exactly
802          * at EOF, return success (don't clip), but with 0 bytes
803          * of I/O.
804          *
805          * Mark EOF B_INVAL (just like bad), indicating that the
806          * contents of the buffer, if any, is invalid.
807          */
808         if ((int64_t)pbn < 0)
809                 goto bad;
810         if (pbn + sz > cs->sc_size) {
811                 if (pbn > cs->sc_size || (bp->b_flags & B_BNOCLIP))
812                         goto bad;
813                 if (pbn == cs->sc_size) {
814                         bp->b_resid = bp->b_bcount;
815                         bp->b_flags |= B_INVAL;
816                         goto done;
817                 }
818                 sz = (long)(cs->sc_size - pbn);
819                 bp->b_bcount = sz * cs->sc_geom.ccg_secsize;
820         }
821         nbio = bio;
822
823         bp->b_resid = bp->b_bcount;
824         nbio->bio_driver_info = dev;
825
826         /*
827          * "Start" the unit.
828          */
829         crit_enter();
830         ccdstart(cs, nbio);
831         crit_exit();
832         return(0);
833
834         /*
835          * note: bio, not nbio, is valid at the done label.
836          */
837 bad:
838         bp->b_error = EINVAL;
839 error:
840         bp->b_resid = bp->b_bcount;
841         bp->b_flags |= B_ERROR | B_INVAL;
842 done:
843         biodone(bio);
844         return(0);
845 }
846
847 static void
848 ccdstart(struct ccd_softc *cs, struct bio *bio)
849 {
850         long bcount, rcount;
851         struct ccdbuf *cbp[4];
852         struct buf *bp = bio->bio_buf;
853         /* XXX! : 2 reads and 2 writes for RAID 4/5 */
854         caddr_t addr;
855         off_t doffset;
856
857 #ifdef DEBUG
858         if (ccddebug & CCDB_FOLLOW)
859                 kprintf("ccdstart(%x, %x)\n", cs, bp);
860 #endif
861
862         /* Record the transaction start  */
863         devstat_start_transaction(&cs->device_stats);
864
865         /*
866          * Allocate component buffers and fire off the requests
867          */
868         doffset = bio->bio_offset;
869         addr = bp->b_data;
870
871         for (bcount = bp->b_bcount; bcount > 0; bcount -= rcount) {
872                 ccdbuffer(cbp, cs, bio, doffset, addr, bcount);
873                 rcount = cbp[0]->cb_buf.b_bcount;
874
875                 if (cs->sc_cflags & CCDF_MIRROR) {
876                         /*
877                          * Mirroring.  Writes go to both disks, reads are
878                          * taken from whichever disk seems most appropriate.
879                          *
880                          * We attempt to localize reads to the disk whos arm
881                          * is nearest the read request.  We ignore seeks due
882                          * to writes when making this determination and we
883                          * also try to avoid hogging.
884                          */
885                         if (cbp[0]->cb_buf.b_cmd != BUF_CMD_READ) {
886                                 vn_strategy(cbp[0]->cb_vp, 
887                                             &cbp[0]->cb_buf.b_bio1);
888                                 vn_strategy(cbp[1]->cb_vp, 
889                                             &cbp[1]->cb_buf.b_bio1);
890                         } else {
891                                 int pick = cs->sc_pick;
892                                 daddr_t range = cs->sc_size / 16 * cs->sc_geom.ccg_secsize;
893                                 if (doffset < cs->sc_blk[pick] - range ||
894                                     doffset > cs->sc_blk[pick] + range
895                                 ) {
896                                         cs->sc_pick = pick = 1 - pick;
897                                 }
898                                 cs->sc_blk[pick] = doffset + rcount;
899                                 vn_strategy(cbp[pick]->cb_vp, 
900                                             &cbp[pick]->cb_buf.b_bio1);
901                         }
902                 } else {
903                         /*
904                          * Not mirroring
905                          */
906                         vn_strategy(cbp[0]->cb_vp,
907                                      &cbp[0]->cb_buf.b_bio1);
908                 }
909                 doffset += rcount;
910                 addr += rcount;
911         }
912 }
913
914 /*
915  * Build a component buffer header.
916  */
917 static void
918 ccdbuffer(struct ccdbuf **cb, struct ccd_softc *cs, struct bio *bio,
919           off_t doffset, caddr_t addr, long bcount)
920 {
921         struct ccdcinfo *ci, *ci2 = NULL;       /* XXX */
922         struct ccdbuf *cbp;
923         u_int64_t bn;
924         u_int64_t cbn;
925         u_int64_t cboff;
926         off_t cbc;
927
928 #ifdef DEBUG
929         if (ccddebug & CCDB_IO)
930                 kprintf("ccdbuffer(%x, %x, %d, %x, %d)\n",
931                        cs, bp, bn, addr, bcount);
932 #endif
933         /*
934          * Determine which component bn falls in.
935          */
936         bn = doffset / cs->sc_geom.ccg_secsize;
937         cbn = bn;
938         cboff = 0;
939
940         if (cs->sc_ileave == 0) {
941                 /*
942                  * Serially concatenated and neither a mirror nor a parity
943                  * config.  This is a special case.
944                  */
945                 daddr_t sblk;
946
947                 sblk = 0;
948                 for (ci = cs->sc_cinfo; cbn >= sblk + ci->ci_size; ci++)
949                         sblk += ci->ci_size;
950                 cbn -= sblk;
951         } else {
952                 struct ccdiinfo *ii;
953                 int ccdisk, off;
954
955                 /*
956                  * Calculate cbn, the logical superblock (sc_ileave chunks),
957                  * and cboff, a normal block offset (DEV_BSIZE chunks) relative
958                  * to cbn.
959                  */
960                 cboff = cbn % cs->sc_ileave;    /* DEV_BSIZE gran */
961                 cbn = cbn / cs->sc_ileave;      /* DEV_BSIZE * ileave gran */
962
963                 /*
964                  * Figure out which interleave table to use.
965                  */
966                 for (ii = cs->sc_itable; ii->ii_ndisk; ii++) {
967                         if (ii->ii_startblk > cbn)
968                                 break;
969                 }
970                 ii--;
971
972                 /*
973                  * off is the logical superblock relative to the beginning 
974                  * of this interleave block.  
975                  */
976                 off = cbn - ii->ii_startblk;
977
978                 /*
979                  * We must calculate which disk component to use (ccdisk),
980                  * and recalculate cbn to be the superblock relative to
981                  * the beginning of the component.  This is typically done by
982                  * adding 'off' and ii->ii_startoff together.  However, 'off'
983                  * must typically be divided by the number of components in
984                  * this interleave array to be properly convert it from a
985                  * CCD-relative logical superblock number to a 
986                  * component-relative superblock number.
987                  */
988                 if (ii->ii_ndisk == 1) {
989                         /*
990                          * When we have just one disk, it can't be a mirror
991                          * or a parity config.
992                          */
993                         ccdisk = ii->ii_index[0];
994                         cbn = ii->ii_startoff + off;
995                 } else {
996                         if (cs->sc_cflags & CCDF_MIRROR) {
997                                 /*
998                                  * We have forced a uniform mapping, resulting
999                                  * in a single interleave array.  We double
1000                                  * up on the first half of the available
1001                                  * components and our mirror is in the second
1002                                  * half.  This only works with a single 
1003                                  * interleave array because doubling up
1004                                  * doubles the number of sectors, so there
1005                                  * cannot be another interleave array because
1006                                  * the next interleave array's calculations
1007                                  * would be off.
1008                                  */
1009                                 int ndisk2 = ii->ii_ndisk / 2;
1010                                 ccdisk = ii->ii_index[off % ndisk2];
1011                                 cbn = ii->ii_startoff + off / ndisk2;
1012                                 ci2 = &cs->sc_cinfo[ccdisk + ndisk2];
1013                         } else if (cs->sc_cflags & CCDF_PARITY) {
1014                                 /* 
1015                                  * XXX not implemented yet
1016                                  */
1017                                 int ndisk2 = ii->ii_ndisk - 1;
1018                                 ccdisk = ii->ii_index[off % ndisk2];
1019                                 cbn = ii->ii_startoff + off / ndisk2;
1020                                 if (cbn % ii->ii_ndisk <= ccdisk)
1021                                         ccdisk++;
1022                         } else {
1023                                 ccdisk = ii->ii_index[off % ii->ii_ndisk];
1024                                 cbn = ii->ii_startoff + off / ii->ii_ndisk;
1025                         }
1026                 }
1027
1028                 ci = &cs->sc_cinfo[ccdisk];
1029
1030                 /*
1031                  * Convert cbn from a superblock to a normal block so it
1032                  * can be used to calculate (along with cboff) the normal
1033                  * block index into this particular disk.
1034                  */
1035                 cbn *= cs->sc_ileave;
1036         }
1037
1038         /*
1039          * Fill in the component buf structure.
1040          *
1041          * NOTE: devices do not use b_bufsize, only b_bcount, but b_bcount
1042          * will be truncated on device EOF so we use b_bufsize to detect
1043          * the case.
1044          */
1045         cbp = getccdbuf();
1046         cbp->cb_buf.b_cmd = bio->bio_buf->b_cmd;
1047         cbp->cb_buf.b_flags |= bio->bio_buf->b_flags;
1048         cbp->cb_buf.b_data = addr;
1049         cbp->cb_vp = ci->ci_vp;
1050         if (cs->sc_ileave == 0)
1051               cbc = dbtob((off_t)(ci->ci_size - cbn));
1052         else
1053               cbc = dbtob((off_t)(cs->sc_ileave - cboff));
1054         cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
1055         cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
1056
1057         cbp->cb_buf.b_bio1.bio_done = ccdiodone;
1058         cbp->cb_buf.b_bio1.bio_caller_info1.ptr = cbp;
1059         cbp->cb_buf.b_bio1.bio_offset = dbtob(cbn + cboff + ci->ci_skip);
1060
1061         /*
1062          * context for ccdiodone
1063          */
1064         cbp->cb_obio = bio;
1065         cbp->cb_unit = cs - ccd_softc;
1066         cbp->cb_comp = ci - cs->sc_cinfo;
1067
1068 #ifdef DEBUG
1069         if (ccddebug & CCDB_IO)
1070                 kprintf(" dev %x(u%d): cbp %x off %lld addr %x bcnt %d\n",
1071                        ci->ci_dev, ci-cs->sc_cinfo, cbp,
1072                        cbp->cb_buf.b_bio1.bio_offset,
1073                        cbp->cb_buf.b_data, cbp->cb_buf.b_bcount);
1074 #endif
1075         cb[0] = cbp;
1076
1077         /*
1078          * Note: both I/O's setup when reading from mirror, but only one
1079          * will be executed.
1080          */
1081         if (cs->sc_cflags & CCDF_MIRROR) {
1082                 /* mirror, setup second I/O */
1083                 cbp = getccdbuf();
1084
1085                 cbp->cb_buf.b_cmd = bio->bio_buf->b_cmd;
1086                 cbp->cb_buf.b_flags |= bio->bio_buf->b_flags;
1087                 cbp->cb_buf.b_data = addr;
1088                 cbp->cb_vp = ci2->ci_vp;
1089                 if (cs->sc_ileave == 0)
1090                       cbc = dbtob((off_t)(ci->ci_size - cbn));
1091                 else
1092                       cbc = dbtob((off_t)(cs->sc_ileave - cboff));
1093                 cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount;
1094                 cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount;
1095
1096                 cbp->cb_buf.b_bio1.bio_done = ccdiodone;
1097                 cbp->cb_buf.b_bio1.bio_caller_info1.ptr = cbp;
1098                 cbp->cb_buf.b_bio1.bio_offset = dbtob(cbn + cboff + ci2->ci_skip);
1099
1100                 /*
1101                  * context for ccdiodone
1102                  */
1103                 cbp->cb_obio = bio;
1104                 cbp->cb_unit = cs - ccd_softc;
1105                 cbp->cb_comp = ci2 - cs->sc_cinfo;
1106                 cb[1] = cbp;
1107                 /* link together the ccdbuf's and clear "mirror done" flag */
1108                 cb[0]->cb_mirror = cb[1];
1109                 cb[1]->cb_mirror = cb[0];
1110                 cb[0]->cb_pflags &= ~CCDPF_MIRROR_DONE;
1111                 cb[1]->cb_pflags &= ~CCDPF_MIRROR_DONE;
1112         }
1113 }
1114
1115 static void
1116 ccdintr(struct ccd_softc *cs, struct bio *bio)
1117 {
1118         struct buf *bp = bio->bio_buf;
1119
1120 #ifdef DEBUG
1121         if (ccddebug & CCDB_FOLLOW)
1122                 kprintf("ccdintr(%x, %x)\n", cs, bp);
1123 #endif
1124         /*
1125          * Request is done for better or worse, wakeup the top half.
1126          */
1127         if (bp->b_flags & B_ERROR)
1128                 bp->b_resid = bp->b_bcount;
1129         devstat_end_transaction_buf(&cs->device_stats, bp);
1130         biodone(bio);
1131 }
1132
1133 /*
1134  * Called at interrupt time.
1135  * Mark the component as done and if all components are done,
1136  * take a ccd interrupt.
1137  */
1138 static void
1139 ccdiodone(struct bio *bio)
1140 {
1141         struct ccdbuf *cbp = bio->bio_caller_info1.ptr;
1142         struct bio *obio = cbp->cb_obio;
1143         struct buf *obp = obio->bio_buf;
1144         int unit = cbp->cb_unit;
1145         int count;
1146
1147         /*
1148          * Since we do not have exclusive access to underlying devices,
1149          * we can't keep cache translations around.
1150          */
1151         clearbiocache(bio->bio_next);
1152
1153         crit_enter();
1154 #ifdef DEBUG
1155         if (ccddebug & CCDB_FOLLOW)
1156                 kprintf("ccdiodone(%x)\n", cbp);
1157         if (ccddebug & CCDB_IO) {
1158                 kprintf("ccdiodone: bp %x bcount %d resid %d\n",
1159                        obp, obp->b_bcount, obp->b_resid);
1160                 kprintf(" dev %x(u%d), cbp %x off %lld addr %x bcnt %d\n",
1161                        cbp->cb_buf.b_dev, cbp->cb_comp, cbp,
1162                        cbp->cb_buf.b_loffset, cbp->cb_buf.b_data,
1163                        cbp->cb_buf.b_bcount);
1164         }
1165 #endif
1166
1167         /*
1168          * If an error occured, report it.  If this is a mirrored 
1169          * configuration and the first of two possible reads, do not
1170          * set the error in the bp yet because the second read may
1171          * succeed.
1172          */
1173         if (cbp->cb_buf.b_flags & B_ERROR) {
1174                 const char *msg = "";
1175
1176                 if ((ccd_softc[unit].sc_cflags & CCDF_MIRROR) &&
1177                     (cbp->cb_buf.b_cmd == BUF_CMD_READ) &&
1178                     (cbp->cb_pflags & CCDPF_MIRROR_DONE) == 0) {
1179                         /*
1180                          * We will try our read on the other disk down
1181                          * below, also reverse the default pick so if we 
1182                          * are doing a scan we do not keep hitting the
1183                          * bad disk first.
1184                          */
1185                         struct ccd_softc *cs = &ccd_softc[unit];
1186
1187                         msg = ", trying other disk";
1188                         cs->sc_pick = 1 - cs->sc_pick;
1189                         cs->sc_blk[cs->sc_pick] = obio->bio_offset;
1190                 } else {
1191                         obp->b_flags |= B_ERROR;
1192                         obp->b_error = cbp->cb_buf.b_error ? 
1193                             cbp->cb_buf.b_error : EIO;
1194                 }
1195                 kprintf("ccd%d: error %d on component %d offset %lld (ccd offset %lld)%s\n",
1196                        unit, obp->b_error, cbp->cb_comp, 
1197                        cbp->cb_buf.b_bio2.bio_offset, 
1198                        obio->bio_offset, msg);
1199         }
1200
1201         /*
1202          * Process mirror.  If we are writing, I/O has been initiated on both
1203          * buffers and we fall through only after both are finished.
1204          *
1205          * If we are reading only one I/O is initiated at a time.  If an
1206          * error occurs we initiate the second I/O and return, otherwise 
1207          * we free the second I/O without initiating it.
1208          */
1209
1210         if (ccd_softc[unit].sc_cflags & CCDF_MIRROR) {
1211                 if (cbp->cb_buf.b_cmd != BUF_CMD_READ) {
1212                         /*
1213                          * When writing, handshake with the second buffer
1214                          * to determine when both are done.  If both are not
1215                          * done, return here.
1216                          */
1217                         if ((cbp->cb_pflags & CCDPF_MIRROR_DONE) == 0) {
1218                                 cbp->cb_mirror->cb_pflags |= CCDPF_MIRROR_DONE;
1219                                 putccdbuf(cbp);
1220                                 crit_exit();
1221                                 return;
1222                         }
1223                 } else {
1224                         /*
1225                          * When reading, either dispose of the second buffer
1226                          * or initiate I/O on the second buffer if an error 
1227                          * occured with this one.
1228                          */
1229                         if ((cbp->cb_pflags & CCDPF_MIRROR_DONE) == 0) {
1230                                 if (cbp->cb_buf.b_flags & B_ERROR) {
1231                                         cbp->cb_mirror->cb_pflags |= 
1232                                             CCDPF_MIRROR_DONE;
1233                                         vn_strategy(
1234                                             cbp->cb_mirror->cb_vp, 
1235                                             &cbp->cb_mirror->cb_buf.b_bio1
1236                                         );
1237                                         putccdbuf(cbp);
1238                                         crit_exit();
1239                                         return;
1240                                 } else {
1241                                         putccdbuf(cbp->cb_mirror);
1242                                         /* fall through */
1243                                 }
1244                         }
1245                 }
1246         }
1247
1248         /*
1249          * Use our saved b_bufsize to determine if an unexpected EOF occured.
1250          */
1251         count = cbp->cb_buf.b_bufsize;
1252         putccdbuf(cbp);
1253
1254         /*
1255          * If all done, "interrupt".
1256          */
1257         obp->b_resid -= count;
1258         if (obp->b_resid < 0)
1259                 panic("ccdiodone: count");
1260         if (obp->b_resid == 0)
1261                 ccdintr(&ccd_softc[unit], obio);
1262         crit_exit();
1263 }
1264
1265 static int
1266 ccdioctl(struct dev_ioctl_args *ap)
1267 {
1268         cdev_t dev = ap->a_head.a_dev;
1269         int unit = ccdunit(dev);
1270         int i, j, lookedup = 0, error = 0;
1271         struct ccd_softc *cs;
1272         struct ccd_ioctl *ccio = (struct ccd_ioctl *)ap->a_data;
1273         struct ccddevice ccd;
1274         struct disk_info info;
1275         char **cpp;
1276         struct vnode **vpp;
1277
1278         if (unit >= numccd)
1279                 return (ENXIO);
1280         cs = &ccd_softc[unit];
1281
1282         bzero(&ccd, sizeof(ccd));
1283
1284         switch (ap->a_cmd) {
1285         case CCDIOCSET:
1286                 if (cs->sc_flags & CCDF_INITED)
1287                         return (EBUSY);
1288
1289                 if ((ap->a_fflag & FWRITE) == 0)
1290                         return (EBADF);
1291
1292                 if ((error = ccdlock(cs)) != 0)
1293                         return (error);
1294
1295                 if (ccio->ccio_ndisks > CCD_MAXNDISKS) {
1296                         ccdunlock(cs);
1297                         return (EINVAL);
1298                 }
1299  
1300                 /* Fill in some important bits. */
1301                 ccd.ccd_unit = unit;
1302                 ccd.ccd_interleave = ccio->ccio_ileave;
1303                 if (ccd.ccd_interleave == 0 &&
1304                     ((ccio->ccio_flags & CCDF_MIRROR) ||
1305                      (ccio->ccio_flags & CCDF_PARITY))) {
1306                         kprintf("ccd%d: disabling mirror/parity, interleave is 0\n", unit);
1307                         ccio->ccio_flags &= ~(CCDF_MIRROR | CCDF_PARITY);
1308                 }
1309                 if ((ccio->ccio_flags & CCDF_MIRROR) &&
1310                     (ccio->ccio_flags & CCDF_PARITY)) {
1311                         kprintf("ccd%d: can't specify both mirror and parity, using mirror\n", unit);
1312                         ccio->ccio_flags &= ~CCDF_PARITY;
1313                 }
1314                 if ((ccio->ccio_flags & (CCDF_MIRROR | CCDF_PARITY)) &&
1315                     !(ccio->ccio_flags & CCDF_UNIFORM)) {
1316                         kprintf("ccd%d: mirror/parity forces uniform flag\n",
1317                                unit);
1318                         ccio->ccio_flags |= CCDF_UNIFORM;
1319                 }
1320                 ccd.ccd_flags = ccio->ccio_flags & CCDF_USERMASK;
1321
1322                 /*
1323                  * Allocate space for and copy in the array of
1324                  * componet pathnames and device numbers.
1325                  */
1326                 cpp = kmalloc(ccio->ccio_ndisks * sizeof(char *),
1327                     M_DEVBUF, M_WAITOK);
1328                 vpp = kmalloc(ccio->ccio_ndisks * sizeof(struct vnode *),
1329                     M_DEVBUF, M_WAITOK);
1330
1331                 error = copyin((caddr_t)ccio->ccio_disks, (caddr_t)cpp,
1332                                 ccio->ccio_ndisks * sizeof(char **));
1333                 if (error) {
1334                         kfree(vpp, M_DEVBUF);
1335                         kfree(cpp, M_DEVBUF);
1336                         ccdunlock(cs);
1337                         return (error);
1338                 }
1339
1340 #ifdef DEBUG
1341                 if (ccddebug & CCDB_INIT) {
1342                         for (i = 0; i < ccio->ccio_ndisks; ++i)
1343                                 kprintf("ccdioctl: component %d: 0x%x\n",
1344                                     i, cpp[i]);
1345                 }
1346 #endif
1347
1348                 for (i = 0; i < ccio->ccio_ndisks; ++i) {
1349 #ifdef DEBUG
1350                         if (ccddebug & CCDB_INIT)
1351                                 kprintf("ccdioctl: lookedup = %d\n", lookedup);
1352 #endif
1353                         if ((error = ccdlookup(cpp[i], &vpp[i])) != 0) {
1354                                 for (j = 0; j < lookedup; ++j)
1355                                         (void)vn_close(vpp[j], FREAD|FWRITE);
1356                                 kfree(vpp, M_DEVBUF);
1357                                 kfree(cpp, M_DEVBUF);
1358                                 ccdunlock(cs);
1359                                 return (error);
1360                         }
1361                         ++lookedup;
1362                 }
1363                 ccd.ccd_cpp = cpp;
1364                 ccd.ccd_vpp = vpp;
1365                 ccd.ccd_ndev = ccio->ccio_ndisks;
1366
1367                 /*
1368                  * Initialize the ccd.  Fills in the softc for us.
1369                  */
1370                 if ((error = ccdinit(&ccd, cpp, ap->a_cred)) != 0) {
1371                         for (j = 0; j < lookedup; ++j)
1372                                 (void)vn_close(vpp[j], FREAD|FWRITE);
1373                         kfree(vpp, M_DEVBUF);
1374                         kfree(cpp, M_DEVBUF);
1375                         ccdunlock(cs);
1376                         return (error);
1377                 }
1378
1379                 /*
1380                  * The ccd has been successfully initialized, so
1381                  * we can place it into the array and read the disklabel.
1382                  */
1383                 bcopy(&ccd, &ccddevs[unit], sizeof(ccd));
1384                 ccio->ccio_unit = unit;
1385                 ccio->ccio_size = cs->sc_size;
1386
1387                 bzero(&info, sizeof(info));
1388                 info.d_media_blksize = cs->sc_geom.ccg_secsize;
1389                 info.d_media_blocks  = cs->sc_size;
1390                 info.d_nheads        = cs->sc_geom.ccg_ntracks;
1391                 info.d_secpertrack   = cs->sc_geom.ccg_nsectors;
1392                 info.d_ncylinders    = cs->sc_geom.ccg_ncylinders;
1393                 info.d_secpercyl     = info.d_nheads * info.d_secpertrack;
1394
1395                 /*
1396                  * For cases where a label is directly applied to the ccd,
1397                  * without slices, DSO_COMPATMBR forces one sector be 
1398                  * reserved for backwards compatibility.
1399                  */
1400                 info.d_dsflags       = DSO_COMPATMBR;
1401                 disk_setdiskinfo(&cs->sc_disk, &info);
1402
1403                 ccdunlock(cs);
1404
1405                 break;
1406
1407         case CCDIOCCLR:
1408                 if ((cs->sc_flags & CCDF_INITED) == 0)
1409                         return (ENXIO);
1410
1411                 if ((ap->a_fflag & FWRITE) == 0)
1412                         return (EBADF);
1413
1414                 if ((error = ccdlock(cs)) != 0)
1415                         return (error);
1416
1417                 if (dev_drefs(cs->sc_dev) > 1) {
1418                         ccdunlock(cs);
1419                         return (EBUSY);
1420                 }
1421
1422                 /*
1423                  * Free ccd_softc information and clear entry.
1424                  */
1425
1426                 /* Close the components and free their pathnames. */
1427                 for (i = 0; i < cs->sc_nccdisks; ++i) {
1428                         /*
1429                          * XXX: this close could potentially fail and
1430                          * cause Bad Things.  Maybe we need to force
1431                          * the close to happen?
1432                          */
1433 #ifdef DEBUG
1434                         if (ccddebug & CCDB_VNODE)
1435                                 vprint("CCDIOCCLR: vnode info",
1436                                     cs->sc_cinfo[i].ci_vp);
1437 #endif
1438                         (void)vn_close(cs->sc_cinfo[i].ci_vp, FREAD|FWRITE);
1439                         kfree(cs->sc_cinfo[i].ci_path, M_DEVBUF);
1440                 }
1441
1442                 /* Free interleave index. */
1443                 for (i = 0; cs->sc_itable[i].ii_ndisk; ++i)
1444                         kfree(cs->sc_itable[i].ii_index, M_DEVBUF);
1445
1446                 /* Free component info and interleave table. */
1447                 kfree(cs->sc_cinfo, M_DEVBUF);
1448                 kfree(cs->sc_itable, M_DEVBUF);
1449                 cs->sc_cinfo = NULL;
1450                 cs->sc_itable = NULL;
1451                 cs->sc_flags &= ~CCDF_INITED;
1452
1453                 /*
1454                  * Free ccddevice information and clear entry.
1455                  */
1456                 kfree(ccddevs[unit].ccd_cpp, M_DEVBUF);
1457                 kfree(ccddevs[unit].ccd_vpp, M_DEVBUF);
1458                 bcopy(&ccd, &ccddevs[unit], sizeof(ccd));
1459
1460                 /*
1461                  * And remove the devstat entry.
1462                  */
1463                 devstat_remove_entry(&cs->device_stats);
1464
1465                 /* This must be atomic. */
1466                 crit_enter();
1467                 ccdunlock(cs);
1468                 crit_exit();
1469
1470                 break;
1471
1472         default:
1473                 return (ENOTTY);
1474         }
1475
1476         return (0);
1477 }
1478
1479 static int
1480 ccddump(struct dev_dump_args *ap)
1481 {
1482         /* Not implemented. */
1483         return ENXIO;
1484 }
1485
1486 /*
1487  * Lookup the provided name in the filesystem.  If the file exists,
1488  * is a valid block device, and isn't being used by anyone else,
1489  * set *vpp to the file's vnode.
1490  */
1491 static int
1492 ccdlookup(char *path, struct vnode **vpp)
1493 {
1494         struct nlookupdata nd;
1495         struct vnode *vp;
1496         int error;
1497
1498         *vpp = NULL;
1499
1500         error = nlookup_init(&nd, path, UIO_USERSPACE, NLC_FOLLOW|NLC_LOCKVP);
1501         if (error)
1502                 return (error);
1503         if ((error = vn_open(&nd, NULL, FREAD|FWRITE, 0)) != 0) {
1504 #ifdef DEBUG
1505                 if (ccddebug & CCDB_FOLLOW|CCDB_INIT)
1506                         kprintf("ccdlookup: vn_open error = %d\n", error);
1507 #endif
1508                 goto done;
1509         }
1510         vp = nd.nl_open_vp;
1511
1512         if (vp->v_opencount > 1) {
1513                 error = EBUSY;
1514                 goto done;
1515         }
1516
1517         if (!vn_isdisk(vp, &error)) 
1518                 goto done;
1519
1520 #ifdef DEBUG
1521         if (ccddebug & CCDB_VNODE)
1522                 vprint("ccdlookup: vnode info", vp);
1523 #endif
1524
1525         vn_unlock(vp);
1526         nd.nl_open_vp = NULL;
1527         nlookup_done(&nd);
1528         *vpp = vp;                              /* leave ref intact  */
1529         return (0);
1530 done:
1531         nlookup_done(&nd);
1532         return (error);
1533 }
1534
1535 /*
1536  * Wait interruptibly for an exclusive lock.
1537  *
1538  * XXX
1539  * Several drivers do this; it should be abstracted and made MP-safe.
1540  */
1541 static int
1542 ccdlock(struct ccd_softc *cs)
1543 {
1544         int error;
1545
1546         while ((cs->sc_flags & CCDF_LOCKED) != 0) {
1547                 cs->sc_flags |= CCDF_WANTED;
1548                 if ((error = tsleep(cs, PCATCH, "ccdlck", 0)) != 0)
1549                         return (error);
1550         }
1551         cs->sc_flags |= CCDF_LOCKED;
1552         return (0);
1553 }
1554
1555 /*
1556  * Unlock and wake up any waiters.
1557  */
1558 static void
1559 ccdunlock(struct ccd_softc *cs)
1560 {
1561
1562         cs->sc_flags &= ~CCDF_LOCKED;
1563         if ((cs->sc_flags & CCDF_WANTED) != 0) {
1564                 cs->sc_flags &= ~CCDF_WANTED;
1565                 wakeup(cs);
1566         }
1567 }
1568
1569 #ifdef DEBUG
1570 static void
1571 printiinfo(struct ccdiinfo *ii)
1572 {
1573         int ix, i;
1574
1575         for (ix = 0; ii->ii_ndisk; ix++, ii++) {
1576                 kprintf(" itab[%d]: #dk %d sblk %d soff %d",
1577                        ix, ii->ii_ndisk, ii->ii_startblk, ii->ii_startoff);
1578                 for (i = 0; i < ii->ii_ndisk; i++)
1579                         kprintf(" %d", ii->ii_index[i]);
1580                 kprintf("\n");
1581         }
1582 }
1583 #endif
1584
1585 \f
1586 /* Local Variables: */
1587 /* c-argdecl-indent: 8 */
1588 /* c-continued-statement-offset: 8 */
1589 /* c-indent-level: 8 */
1590 /* End: */