[BACK]Return to softraid.c CVS log [TXT][DIR] Up to [local] / sys / dev

Annotation of sys/dev/softraid.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: softraid.c,v 1.82 2007/06/24 05:34:35 dlg Exp $ */
                      2: /*
                      3:  * Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17:
                     18: #include "bio.h"
                     19:
                     20: #include <sys/param.h>
                     21: #include <sys/systm.h>
                     22: #include <sys/buf.h>
                     23: #include <sys/device.h>
                     24: #include <sys/ioctl.h>
                     25: #include <sys/proc.h>
                     26: #include <sys/malloc.h>
                     27: #include <sys/kernel.h>
                     28: #include <sys/disk.h>
                     29: #include <sys/rwlock.h>
                     30: #include <sys/queue.h>
                     31: #include <sys/fcntl.h>
                     32: #include <sys/disklabel.h>
                     33: #include <sys/mount.h>
                     34: #include <sys/sensors.h>
                     35: #include <sys/stat.h>
                     36: #include <sys/conf.h>
                     37: #include <sys/uio.h>
                     38:
                     39: #include <crypto/cryptodev.h>
                     40:
                     41: #include <scsi/scsi_all.h>
                     42: #include <scsi/scsiconf.h>
                     43: #include <scsi/scsi_disk.h>
                     44:
                     45: #include <dev/softraidvar.h>
                     46: #include <dev/rndvar.h>
                     47:
                     48: /* #define SR_FANCY_STATS */
                     49:
                     50: #ifdef SR_DEBUG
                     51: #define SR_FANCY_STATS
                     52: uint32_t       sr_debug = 0
                     53:                    /* | SR_D_CMD */
                     54:                    /* | SR_D_MISC */
                     55:                    /* | SR_D_INTR */
                     56:                    /* | SR_D_IOCTL */
                     57:                    /* | SR_D_CCB */
                     58:                    /* | SR_D_WU */
                     59:                    /* | SR_D_META */
                     60:                    /* | SR_D_DIS */
                     61:                    /* | SR_D_STATE */
                     62:                ;
                     63: #endif
                     64:
                     65: int            sr_match(struct device *, void *, void *);
                     66: void           sr_attach(struct device *, struct device *, void *);
                     67: int            sr_detach(struct device *, int);
                     68: int            sr_activate(struct device *, enum devact);
                     69:
                     70: struct cfattach softraid_ca = {
                     71:        sizeof(struct sr_softc), sr_match, sr_attach, sr_detach,
                     72:        sr_activate
                     73: };
                     74:
                     75: struct cfdriver softraid_cd = {
                     76:        NULL, "softraid", DV_DULL
                     77: };
                     78:
                     79: int                    sr_scsi_cmd(struct scsi_xfer *);
                     80: void                   sr_minphys(struct buf *bp);
                     81: void                   sr_copy_internal_data(struct scsi_xfer *,
                     82:                            void *, size_t);
                     83: int                    sr_scsi_ioctl(struct scsi_link *, u_long,
                     84:                            caddr_t, int, struct proc *);
                     85: int                    sr_ioctl(struct device *, u_long, caddr_t);
                     86: int                    sr_ioctl_inq(struct sr_softc *, struct bioc_inq *);
                     87: int                    sr_ioctl_vol(struct sr_softc *, struct bioc_vol *);
                     88: int                    sr_ioctl_disk(struct sr_softc *, struct bioc_disk *);
                     89: int                    sr_ioctl_setstate(struct sr_softc *,
                     90:                            struct bioc_setstate *);
                     91: int                    sr_ioctl_createraid(struct sr_softc *,
                     92:                            struct bioc_createraid *, int);
                     93: int                    sr_open_chunks(struct sr_softc *,
                     94:                            struct sr_chunk_head *, dev_t *, int);
                     95: int                    sr_read_meta(struct sr_discipline *);
                     96: int                    sr_create_chunk_meta(struct sr_softc *,
                     97:                            struct sr_chunk_head *);
                     98: void                   sr_unwind_chunks(struct sr_softc *,
                     99:                            struct sr_chunk_head *);
                    100: void                   sr_free_discipline(struct sr_discipline *);
                    101: void                   sr_shutdown_discipline(struct sr_discipline *);
                    102:
                    103: /* work units & ccbs */
                    104: int                    sr_alloc_ccb(struct sr_discipline *);
                    105: void                   sr_free_ccb(struct sr_discipline *);
                    106: struct sr_ccb          *sr_get_ccb(struct sr_discipline *);
                    107: void                   sr_put_ccb(struct sr_ccb *);
                    108: int                    sr_alloc_wu(struct sr_discipline *);
                    109: void                   sr_free_wu(struct sr_discipline *);
                    110: struct sr_workunit     *sr_get_wu(struct sr_discipline *);
                    111: void                   sr_put_wu(struct sr_workunit *);
                    112:
                    113: /* discipline functions */
                    114: int                    sr_raid_inquiry(struct sr_workunit *);
                    115: int                    sr_raid_read_cap(struct sr_workunit *);
                    116: int                    sr_raid_tur(struct sr_workunit *);
                    117: int                    sr_raid_request_sense( struct sr_workunit *);
                    118: int                    sr_raid_start_stop(struct sr_workunit *);
                    119: int                    sr_raid_sync(struct sr_workunit *);
                    120: void                   sr_raid_set_chunk_state(struct sr_discipline *,
                    121:                            int, int);
                    122: void                   sr_raid_set_vol_state(struct sr_discipline *);
                    123: void                   sr_raid_startwu(struct sr_workunit *);
                    124:
                    125: int                    sr_raid1_alloc_resources(struct sr_discipline *);
                    126: int                    sr_raid1_free_resources(struct sr_discipline *);
                    127: int                    sr_raid1_rw(struct sr_workunit *);
                    128: void                   sr_raid1_intr(struct buf *);
                    129: void                   sr_raid1_recreate_wu(struct sr_workunit *);
                    130:
                    131: struct cryptop *       sr_raidc_getcryptop(struct sr_workunit *, int);
                    132: void *                 sr_raidc_putcryptop(struct cryptop *);
                    133: int                    sr_raidc_alloc_resources(struct sr_discipline *);
                    134: int                    sr_raidc_free_resources(struct sr_discipline *);
                    135: int                    sr_raidc_rw(struct sr_workunit *);
                    136: int                    sr_raidc_rw2(struct cryptop *);
                    137: void                   sr_raidc_intr(struct buf *);
                    138: int                    sr_raidc_intr2(struct cryptop *);
                    139:
                    140: /* utility functions */
                    141: void                   sr_shutdown(void *);
                    142: void                   sr_get_uuid(struct sr_uuid *);
                    143: void                   sr_print_uuid(struct sr_uuid *, int);
                    144: u_int32_t              sr_checksum(char *, u_int32_t *, u_int32_t);
                    145: int                    sr_clear_metadata(struct sr_discipline *);
                    146: int                    sr_save_metadata(struct sr_discipline *, u_int32_t);
                    147: void                   sr_save_metadata_callback(void *, void *);
                    148: int                    sr_boot_assembly(struct sr_softc *);
                    149: int                    sr_already_assembled(struct sr_discipline *);
                    150: int                    sr_validate_metadata(struct sr_softc *, dev_t,
                    151:                            struct sr_metadata *);
                    152:
                    153: /* don't include these on RAMDISK */
                    154: #ifndef SMALL_KERNEL
                    155: void                   sr_refresh_sensors(void *);
                    156: int                    sr_create_sensors(struct sr_discipline *);
                    157: void                   sr_delete_sensors(struct sr_discipline *);
                    158: #endif
                    159:
                    160: #ifdef SR_DEBUG
                    161: void                   sr_print_metadata(struct sr_metadata *);
                    162: #else
                    163: #define                        sr_print_metadata(m)
                    164: #endif
                    165:
                    166: struct scsi_adapter sr_switch = {
                    167:        sr_scsi_cmd, sr_minphys, NULL, NULL, sr_scsi_ioctl
                    168: };
                    169:
                    170: struct scsi_device sr_dev = {
                    171:        NULL, NULL, NULL, NULL
                    172: };
                    173:
                    174: int
                    175: sr_match(struct device *parent, void *match, void *aux)
                    176: {
                    177:        return (1);
                    178: }
                    179:
                    180: void
                    181: sr_attach(struct device *parent, struct device *self, void *aux)
                    182: {
                    183:        struct sr_softc         *sc = (void *)self;
                    184:
                    185:        DNPRINTF(SR_D_MISC, "\n%s: sr_attach", DEVNAME(sc));
                    186:
                    187:        rw_init(&sc->sc_lock, "sr_lock");
                    188:
                    189:        if (bio_register(&sc->sc_dev, sr_ioctl) != 0)
                    190:                printf("%s: controller registration failed", DEVNAME(sc));
                    191:        else
                    192:                sc->sc_ioctl = sr_ioctl;
                    193:
                    194:        printf("\n");
                    195:
                    196:        sr_boot_assembly(sc);
                    197: }
                    198:
                    199: int
                    200: sr_detach(struct device *self, int flags)
                    201: {
                    202:        return (0);
                    203: }
                    204:
                    205: int
                    206: sr_activate(struct device *self, enum devact act)
                    207: {
                    208:        return (1);
                    209: }
                    210:
                    211: void
                    212: sr_minphys(struct buf *bp)
                    213: {
                    214:        DNPRINTF(SR_D_MISC, "sr_minphys: %d\n", bp->b_bcount);
                    215:
                    216:        /* XXX currently using SR_MAXFER = MAXPHYS */
                    217:        if (bp->b_bcount > SR_MAXFER)
                    218:                bp->b_bcount = SR_MAXFER;
                    219:        minphys(bp);
                    220: }
                    221:
                    222: void
                    223: sr_copy_internal_data(struct scsi_xfer *xs, void *v, size_t size)
                    224: {
                    225:        size_t                  copy_cnt;
                    226:
                    227:        DNPRINTF(SR_D_MISC, "sr_copy_internal_data xs: %p size: %d\n",
                    228:            xs, size);
                    229:
                    230:        if (xs->datalen) {
                    231:                copy_cnt = MIN(size, xs->datalen);
                    232:                bcopy(v, xs->data, copy_cnt);
                    233:        }
                    234: }
                    235:
                    236: int
                    237: sr_alloc_ccb(struct sr_discipline *sd)
                    238: {
                    239:        struct sr_ccb           *ccb;
                    240:        int                     i;
                    241:
                    242:        if (!sd)
                    243:                return (1);
                    244:
                    245:        DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb\n", DEVNAME(sd->sd_sc));
                    246:
                    247:        if (sd->sd_ccb)
                    248:                return (1);
                    249:
                    250:        sd->sd_ccb = malloc(sizeof(struct sr_ccb) *
                    251:            sd->sd_max_wu * sd->sd_max_ccb_per_wu, M_DEVBUF, M_WAITOK);
                    252:        memset(sd->sd_ccb, 0, sizeof(struct sr_ccb) *
                    253:            sd->sd_max_wu * sd->sd_max_ccb_per_wu);
                    254:        TAILQ_INIT(&sd->sd_ccb_freeq);
                    255:        for (i = 0; i < sd->sd_max_wu * sd->sd_max_ccb_per_wu; i++) {
                    256:                ccb = &sd->sd_ccb[i];
                    257:                ccb->ccb_dis = sd;
                    258:                sr_put_ccb(ccb);
                    259:        }
                    260:
                    261:        DNPRINTF(SR_D_CCB, "%s: sr_alloc_ccb ccb: %d\n",
                    262:            DEVNAME(sd->sd_sc), sd->sd_max_wu * sd->sd_max_ccb_per_wu);
                    263:
                    264:        return (0);
                    265: }
                    266:
                    267: void
                    268: sr_free_ccb(struct sr_discipline *sd)
                    269: {
                    270:        struct sr_ccb           *ccb;
                    271:
                    272:        if (!sd)
                    273:                return;
                    274:
                    275:        DNPRINTF(SR_D_CCB, "%s: sr_free_ccb %p\n", DEVNAME(sd->sd_sc), sd);
                    276:
                    277:        while ((ccb = TAILQ_FIRST(&sd->sd_ccb_freeq)) != NULL)
                    278:                TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link);
                    279:
                    280:        if (sd->sd_ccb)
                    281:                free(sd->sd_ccb, M_DEVBUF);
                    282: }
                    283:
                    284: struct sr_ccb *
                    285: sr_get_ccb(struct sr_discipline *sd)
                    286: {
                    287:        struct sr_ccb           *ccb;
                    288:        int                     s;
                    289:
                    290:        s = splbio();
                    291:
                    292:        ccb = TAILQ_FIRST(&sd->sd_ccb_freeq);
                    293:        if (ccb) {
                    294:                TAILQ_REMOVE(&sd->sd_ccb_freeq, ccb, ccb_link);
                    295:                ccb->ccb_state = SR_CCB_INPROGRESS;
                    296:        }
                    297:
                    298:        splx(s);
                    299:
                    300:        DNPRINTF(SR_D_CCB, "%s: sr_get_ccb: %p\n", DEVNAME(sd->sd_sc),
                    301:            ccb);
                    302:
                    303:        return (ccb);
                    304: }
                    305:
                    306: void
                    307: sr_put_ccb(struct sr_ccb *ccb)
                    308: {
                    309:        struct sr_discipline    *sd = ccb->ccb_dis;
                    310:        int                     s;
                    311:
                    312:        DNPRINTF(SR_D_CCB, "%s: sr_put_ccb: %p\n", DEVNAME(sd->sd_sc),
                    313:            ccb);
                    314:
                    315:        s = splbio();
                    316:
                    317:        ccb->ccb_wu = NULL;
                    318:        ccb->ccb_state = SR_CCB_FREE;
                    319:        ccb->ccb_target = -1;
                    320:
                    321:        TAILQ_INSERT_TAIL(&sd->sd_ccb_freeq, ccb, ccb_link);
                    322:
                    323:        splx(s);
                    324: }
                    325:
                    326: int
                    327: sr_alloc_wu(struct sr_discipline *sd)
                    328: {
                    329:        struct sr_workunit      *wu;
                    330:        int                     i, no_wu;
                    331:
                    332:        if (!sd)
                    333:                return (1);
                    334:
                    335:        DNPRINTF(SR_D_WU, "%s: sr_alloc_wu %p %d\n", DEVNAME(sd->sd_sc),
                    336:            sd, sd->sd_max_wu);
                    337:
                    338:        if (sd->sd_wu)
                    339:                return (1);
                    340:
                    341:        no_wu = sd->sd_max_wu;
                    342:        sd->sd_wu_pending = no_wu;
                    343:
                    344:        sd->sd_wu = malloc(sizeof(struct sr_workunit) * no_wu,
                    345:            M_DEVBUF, M_WAITOK);
                    346:        memset(sd->sd_wu, 0, sizeof(struct sr_workunit) * no_wu);
                    347:        TAILQ_INIT(&sd->sd_wu_freeq);
                    348:        TAILQ_INIT(&sd->sd_wu_pendq);
                    349:        TAILQ_INIT(&sd->sd_wu_defq);
                    350:        for (i = 0; i < no_wu; i++) {
                    351:                wu = &sd->sd_wu[i];
                    352:                wu->swu_dis = sd;
                    353:                sr_put_wu(wu);
                    354:        }
                    355:
                    356:        return (0);
                    357: }
                    358:
                    359: void
                    360: sr_free_wu(struct sr_discipline *sd)
                    361: {
                    362:        struct sr_workunit      *wu;
                    363:
                    364:        if (!sd)
                    365:                return;
                    366:
                    367:        DNPRINTF(SR_D_WU, "%s: sr_free_wu %p\n", DEVNAME(sd->sd_sc), sd);
                    368:
                    369:        while ((wu = TAILQ_FIRST(&sd->sd_wu_freeq)) != NULL)
                    370:                TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link);
                    371:        while ((wu = TAILQ_FIRST(&sd->sd_wu_pendq)) != NULL)
                    372:                TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
                    373:        while ((wu = TAILQ_FIRST(&sd->sd_wu_defq)) != NULL)
                    374:                TAILQ_REMOVE(&sd->sd_wu_defq, wu, swu_link);
                    375:
                    376:        if (sd->sd_wu)
                    377:                free(sd->sd_wu, M_DEVBUF);
                    378: }
                    379:
                    380: void
                    381: sr_put_wu(struct sr_workunit *wu)
                    382: {
                    383:        struct sr_discipline    *sd = wu->swu_dis;
                    384:        struct sr_ccb           *ccb;
                    385:
                    386:        int                     s;
                    387:
                    388:        DNPRINTF(SR_D_WU, "%s: sr_put_wu: %p\n", DEVNAME(sd->sd_sc), wu);
                    389:
                    390:        s = splbio();
                    391:
                    392:        wu->swu_xs = NULL;
                    393:        wu->swu_state = SR_WU_FREE;
                    394:        wu->swu_ios_complete = 0;
                    395:        wu->swu_ios_failed = 0;
                    396:        wu->swu_ios_succeeded = 0;
                    397:        wu->swu_io_count = 0;
                    398:        wu->swu_blk_start = 0;
                    399:        wu->swu_blk_end = 0;
                    400:        wu->swu_collider = NULL;
                    401:        wu->swu_fake = 0;
                    402:
                    403:        while ((ccb = TAILQ_FIRST(&wu->swu_ccb)) != NULL) {
                    404:                TAILQ_REMOVE(&wu->swu_ccb, ccb, ccb_link);
                    405:                sr_put_ccb(ccb);
                    406:        }
                    407:        TAILQ_INIT(&wu->swu_ccb);
                    408:
                    409:        TAILQ_INSERT_TAIL(&sd->sd_wu_freeq, wu, swu_link);
                    410:        sd->sd_wu_pending--;
                    411:
                    412:        splx(s);
                    413: }
                    414:
                    415: struct sr_workunit *
                    416: sr_get_wu(struct sr_discipline *sd)
                    417: {
                    418:        struct sr_workunit      *wu;
                    419:        int                     s;
                    420:
                    421:        s = splbio();
                    422:
                    423:        wu = TAILQ_FIRST(&sd->sd_wu_freeq);
                    424:        if (wu) {
                    425:                TAILQ_REMOVE(&sd->sd_wu_freeq, wu, swu_link);
                    426:                wu->swu_state = SR_WU_INPROGRESS;
                    427:        }
                    428:        sd->sd_wu_pending++;
                    429:
                    430:        splx(s);
                    431:
                    432:        DNPRINTF(SR_D_WU, "%s: sr_get_wu: %p\n", DEVNAME(sd->sd_sc), wu);
                    433:
                    434:        return (wu);
                    435: }
                    436:
                    437: int
                    438: sr_scsi_cmd(struct scsi_xfer *xs)
                    439: {
                    440:        int                     s;
                    441:        struct scsi_link        *link = xs->sc_link;
                    442:        struct sr_softc         *sc = link->adapter_softc;
                    443:        struct sr_workunit      *wu;
                    444:        struct sr_discipline    *sd;
                    445:
                    446:        DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: scsibus%d xs: %p "
                    447:            "flags: %#x\n", DEVNAME(sc), link->scsibus, xs, xs->flags);
                    448:
                    449:        sd = sc->sc_dis[link->scsibus];
                    450:        if (sd == NULL) {
                    451:                s = splhigh();
                    452:                sd = sc->sc_attach_dis;
                    453:                splx(s);
                    454:
                    455:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: attaching %p\n",
                    456:                    DEVNAME(sc), sd);
                    457:                if (sd == NULL) {
                    458:                        wu = NULL;
                    459:                        printf("%s: sr_scsi_cmd NULL discipline\n",
                    460:                            DEVNAME(sc));
                    461:                        goto stuffup;
                    462:                }
                    463:        }
                    464:
                    465:        if ((wu = sr_get_wu(sd)) == NULL) {
                    466:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd no wu\n", DEVNAME(sc));
                    467:                return (TRY_AGAIN_LATER);
                    468:        }
                    469:
                    470:        xs->error = XS_NOERROR;
                    471:        wu->swu_xs = xs;
                    472:
                    473:        switch (xs->cmd->opcode) {
                    474:        case READ_COMMAND:
                    475:        case READ_BIG:
                    476:        case WRITE_COMMAND:
                    477:        case WRITE_BIG:
                    478:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: READ/WRITE %02x\n",
                    479:                    DEVNAME(sc), xs->cmd->opcode);
                    480:                if (sd->sd_scsi_rw(wu))
                    481:                        goto stuffup;
                    482:                break;
                    483:
                    484:        case SYNCHRONIZE_CACHE:
                    485:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: SYNCHRONIZE_CACHE\n",
                    486:                    DEVNAME(sc));
                    487:                if (sd->sd_scsi_sync(wu))
                    488:                        goto stuffup;
                    489:                goto complete;
                    490:
                    491:        case TEST_UNIT_READY:
                    492:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: TEST_UNIT_READY\n",
                    493:                    DEVNAME(sc));
                    494:                if (sd->sd_scsi_tur(wu))
                    495:                        goto stuffup;
                    496:                goto complete;
                    497:
                    498:        case START_STOP:
                    499:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: START_STOP\n",
                    500:                    DEVNAME(sc));
                    501:                if (sd->sd_scsi_start_stop(wu))
                    502:                        goto stuffup;
                    503:                goto complete;
                    504:
                    505:        case INQUIRY:
                    506:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd: INQUIRY\n",
                    507:                    DEVNAME(sc));
                    508:                if (sd->sd_scsi_inquiry(wu))
                    509:                        goto stuffup;
                    510:                goto complete;
                    511:
                    512:        case READ_CAPACITY:
                    513:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd READ CAPACITY\n",
                    514:                    DEVNAME(sc));
                    515:                if (sd->sd_scsi_read_cap(wu))
                    516:                        goto stuffup;
                    517:                goto complete;
                    518:
                    519:        case REQUEST_SENSE:
                    520:                DNPRINTF(SR_D_CMD, "%s: sr_scsi_cmd REQUEST SENSE\n",
                    521:                    DEVNAME(sc));
                    522:                if (sd->sd_scsi_req_sense(wu))
                    523:                        goto stuffup;
                    524:                goto complete;
                    525:
                    526:        default:
                    527:                DNPRINTF(SR_D_CMD, "%s: unsupported scsi command %x\n",
                    528:                    DEVNAME(sc), xs->cmd->opcode);
                    529:                /* XXX might need to add generic function to handle others */
                    530:                goto stuffup;
                    531:        }
                    532:
                    533:        return (SUCCESSFULLY_QUEUED);
                    534: stuffup:
                    535:        if (sd->sd_scsi_sense.error_code) {
                    536:                xs->error = XS_SENSE;
                    537:                bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense));
                    538:                bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
                    539:        } else {
                    540:                xs->error = XS_DRIVER_STUFFUP;
                    541:                xs->flags |= ITSDONE;
                    542:        }
                    543: complete:
                    544:        s = splbio();
                    545:        scsi_done(xs);
                    546:        splx(s);
                    547:        if (wu)
                    548:                sr_put_wu(wu);
                    549:        return (COMPLETE);
                    550: }
                    551: int
                    552: sr_scsi_ioctl(struct scsi_link *link, u_long cmd, caddr_t addr, int flag,
                    553:     struct proc *p)
                    554: {
                    555:        DNPRINTF(SR_D_IOCTL, "%s: sr_scsi_ioctl cmd: %#x\n",
                    556:            DEVNAME((struct sr_softc *)link->adapter_softc), cmd);
                    557:
                    558:        return (sr_ioctl(link->adapter_softc, cmd, addr));
                    559: }
                    560:
                    561: int
                    562: sr_ioctl(struct device *dev, u_long cmd, caddr_t addr)
                    563: {
                    564:        struct sr_softc         *sc = (struct sr_softc *)dev;
                    565:        int                     rv = 0;
                    566:
                    567:        DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl ", DEVNAME(sc));
                    568:
                    569:        rw_enter_write(&sc->sc_lock);
                    570:
                    571:        switch (cmd) {
                    572:        case BIOCINQ:
                    573:                DNPRINTF(SR_D_IOCTL, "inq\n");
                    574:                rv = sr_ioctl_inq(sc, (struct bioc_inq *)addr);
                    575:                break;
                    576:
                    577:        case BIOCVOL:
                    578:                DNPRINTF(SR_D_IOCTL, "vol\n");
                    579:                rv = sr_ioctl_vol(sc, (struct bioc_vol *)addr);
                    580:                break;
                    581:
                    582:        case BIOCDISK:
                    583:                DNPRINTF(SR_D_IOCTL, "disk\n");
                    584:                rv = sr_ioctl_disk(sc, (struct bioc_disk *)addr);
                    585:                break;
                    586:
                    587:        case BIOCALARM:
                    588:                DNPRINTF(SR_D_IOCTL, "alarm\n");
                    589:                /*rv = sr_ioctl_alarm(sc, (struct bioc_alarm *)addr); */
                    590:                break;
                    591:
                    592:        case BIOCBLINK:
                    593:                DNPRINTF(SR_D_IOCTL, "blink\n");
                    594:                /*rv = sr_ioctl_blink(sc, (struct bioc_blink *)addr); */
                    595:                break;
                    596:
                    597:        case BIOCSETSTATE:
                    598:                DNPRINTF(SR_D_IOCTL, "setstate\n");
                    599:                rv = sr_ioctl_setstate(sc, (struct bioc_setstate *)addr);
                    600:                break;
                    601:
                    602:        case BIOCCREATERAID:
                    603:                DNPRINTF(SR_D_IOCTL, "createraid\n");
                    604:                rv = sr_ioctl_createraid(sc, (struct bioc_createraid *)addr, 1);
                    605:                break;
                    606:
                    607:        default:
                    608:                DNPRINTF(SR_D_IOCTL, "invalid ioctl\n");
                    609:                rv = EINVAL;
                    610:        }
                    611:
                    612:        rw_exit_write(&sc->sc_lock);
                    613:
                    614:        return (rv);
                    615: }
                    616:
                    617: int
                    618: sr_ioctl_inq(struct sr_softc *sc, struct bioc_inq *bi)
                    619: {
                    620:        int                     i, vol, disk;
                    621:
                    622:        for (i = 0, vol = 0, disk = 0; i < SR_MAXSCSIBUS; i++)
                    623:                /* XXX this will not work when we stagger disciplines */
                    624:                if (sc->sc_dis[i]) {
                    625:                        vol++;
                    626:                        disk += sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk;
                    627:                }
                    628:
                    629:        strlcpy(bi->bi_dev, sc->sc_dev.dv_xname, sizeof(bi->bi_dev));
                    630:        bi->bi_novol = vol;
                    631:        bi->bi_nodisk = disk;
                    632:
                    633:        return (0);
                    634: }
                    635:
                    636: int
                    637: sr_ioctl_vol(struct sr_softc *sc, struct bioc_vol *bv)
                    638: {
                    639:        int                     i, vol, rv = EINVAL;
                    640:        struct sr_volume        *sv;
                    641:
                    642:        for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
                    643:                /* XXX this will not work when we stagger disciplines */
                    644:                if (sc->sc_dis[i])
                    645:                        vol++;
                    646:                if (vol != bv->bv_volid)
                    647:                        continue;
                    648:
                    649:                sv = &sc->sc_dis[i]->sd_vol;
                    650:                bv->bv_status = sv->sv_meta.svm_status;
                    651:                bv->bv_size = sv->sv_meta.svm_size;
                    652:                bv->bv_level = sv->sv_meta.svm_level;
                    653:                bv->bv_nodisk = sv->sv_meta.svm_no_chunk;
                    654:                strlcpy(bv->bv_dev, sv->sv_meta.svm_devname,
                    655:                    sizeof(bv->bv_dev));
                    656:                strlcpy(bv->bv_vendor, sv->sv_meta.svm_vendor,
                    657:                    sizeof(bv->bv_vendor));
                    658:                rv = 0;
                    659:                break;
                    660:        }
                    661:
                    662:        return (rv);
                    663: }
                    664:
                    665: int
                    666: sr_ioctl_disk(struct sr_softc *sc, struct bioc_disk *bd)
                    667: {
                    668:        int                     i, vol, rv = EINVAL, id;
                    669:        struct sr_chunk         *src;
                    670:
                    671:        for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
                    672:                /* XXX this will not work when we stagger disciplines */
                    673:                if (sc->sc_dis[i])
                    674:                        vol++;
                    675:                if (vol != bd->bd_volid)
                    676:                        continue;
                    677:
                    678:                id = bd->bd_diskid;
                    679:                if (id >= sc->sc_dis[i]->sd_vol.sv_meta.svm_no_chunk)
                    680:                        break;
                    681:
                    682:                src = sc->sc_dis[i]->sd_vol.sv_chunks[id];
                    683:                bd->bd_status = src->src_meta.scm_status;
                    684:                bd->bd_size = src->src_meta.scm_size;
                    685:                bd->bd_channel = vol;
                    686:                bd->bd_target = id;
                    687:                strlcpy(bd->bd_vendor, src->src_meta.scm_devname,
                    688:                    sizeof(bd->bd_vendor));
                    689:                rv = 0;
                    690:                break;
                    691:        }
                    692:
                    693:        return (rv);
                    694: }
                    695:
                    696: int
                    697: sr_ioctl_setstate(struct sr_softc *sc, struct bioc_setstate *bs)
                    698: {
                    699:        int                     rv = EINVAL;
                    700:
                    701: #ifdef SR_UNIT_TEST
                    702:        int                     i, vol, state;
                    703:        struct sr_discipline    *sd;
                    704:
                    705:        for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
                    706:                /* XXX this will not work when we stagger disciplines */
                    707:                if (sc->sc_dis[i])
                    708:                        vol++;
                    709:                if (vol != bs->bs_channel)
                    710:                        continue;
                    711:
                    712:                sd = sc->sc_dis[vol];
                    713:                if (bs->bs_target >= sd->sd_vol.sv_meta.svm_no_chunk)
                    714:                        goto done;
                    715:
                    716:                switch (bs->bs_status) {
                    717:                case BIOC_SSONLINE:
                    718:                        state = BIOC_SDONLINE;
                    719:                        break;
                    720:                case BIOC_SSOFFLINE:
                    721:                        state = BIOC_SDOFFLINE;
                    722:                        break;
                    723:                case BIOC_SSHOTSPARE:
                    724:                        state = BIOC_SDHOTSPARE;
                    725:                        break;
                    726:                case BIOC_SSREBUILD:
                    727:                        state = BIOC_SDREBUILD;
                    728:                        break;
                    729:                default:
                    730:                        printf("invalid state %d\n", bs->bs_status);
                    731:                        goto done;
                    732:                }
                    733:
                    734:                printf("status change for %u:%u -> %u %u\n",
                    735:                    bs->bs_channel, bs->bs_target, bs->bs_status, state);
                    736:
                    737:                sd->sd_set_chunk_state(sd, bs->bs_target, bs->bs_status);
                    738:
                    739:                rv = 0;
                    740:
                    741:                break;
                    742:        }
                    743:
                    744: done:
                    745: #endif
                    746:        return (rv);
                    747: }
                    748:
                    749: int
                    750: sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
                    751: {
                    752:        dev_t                   *dt;
                    753:        int                     i, s, no_chunk, rv = EINVAL, vol;
                    754:        int                     no_meta, updatemeta = 0;
                    755:        int64_t                 vol_size;
                    756:        struct sr_chunk_head    *cl;
                    757:        struct sr_discipline    *sd = NULL;
                    758:        struct sr_chunk         *ch_entry;
                    759:        struct device           *dev, *dev2;
                    760:        struct scsibus_attach_args saa;
                    761:
                    762:        DNPRINTF(SR_D_IOCTL, "%s: sr_ioctl_createraid(%d)\n",
                    763:            DEVNAME(sc), user);
                    764:
                    765:        /* user input */
                    766:        if (bc->bc_dev_list_len > BIOC_CRMAXLEN)
                    767:                goto unwind;
                    768:
                    769:        dt = malloc(bc->bc_dev_list_len, M_DEVBUF, M_WAITOK);
                    770:        bzero(dt, bc->bc_dev_list_len);
                    771:        if (user)
                    772:                copyin(bc->bc_dev_list, dt, bc->bc_dev_list_len);
                    773:        else
                    774:                bcopy(bc->bc_dev_list, dt, bc->bc_dev_list_len);
                    775:
                    776:        sd = malloc(sizeof(struct sr_discipline), M_DEVBUF, M_WAITOK);
                    777:        memset(sd, 0, sizeof(struct sr_discipline));
                    778:        sd->sd_sc = sc;
                    779:
                    780:        no_chunk = bc->bc_dev_list_len / sizeof(dev_t);
                    781:        cl = &sd->sd_vol.sv_chunk_list;
                    782:        SLIST_INIT(cl);
                    783:        if (sr_open_chunks(sc, cl, dt, no_chunk))
                    784:                goto unwind;
                    785:
                    786:        /* in memory copy of metadata */
                    787:        sd->sd_meta = malloc(SR_META_SIZE * 512 , M_DEVBUF, M_WAITOK);
                    788:        bzero(sd->sd_meta, SR_META_SIZE  * 512);
                    789:
                    790:        /* we have a valid list now create an array index */
                    791:        sd->sd_vol.sv_chunks = malloc(sizeof(struct sr_chunk *) * no_chunk,
                    792:            M_DEVBUF, M_WAITOK);
                    793:        bzero(sd->sd_vol.sv_chunks, sizeof(struct sr_chunk *) * no_chunk);
                    794:
                    795:        /* force the raid volume by clearing metadata region */
                    796:        if (bc->bc_flags & BIOC_SCFORCE) {
                    797:                /* make sure disk isn't up and running */
                    798:                if (sr_read_meta(sd))
                    799:                        if (sr_already_assembled(sd)) {
                    800:                                printf("%s: disk ", DEVNAME(sc));
                    801:                                sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
                    802:                                printf(" is currently in use; can't force "
                    803:                                    "create\n");
                    804:                                goto unwind;
                    805:                        }
                    806:
                    807:                /* zero out pointers and metadata again to create disk */
                    808:                bzero(sd->sd_vol.sv_chunks,
                    809:                    sizeof(struct sr_chunk *) * no_chunk);
                    810:                bzero(sd->sd_meta, SR_META_SIZE  * 512);
                    811:
                    812:                if (sr_clear_metadata(sd)) {
                    813:                        printf("%s: failed to clear metadata\n");
                    814:                        goto unwind;
                    815:                }
                    816:        }
                    817:
                    818:        if ((no_meta = sr_read_meta(sd)) == 0) {
                    819:                /* no metadata available */
                    820:                switch (bc->bc_level) {
                    821:                case 1:
                    822:                        if (no_chunk < 2)
                    823:                                goto unwind;
                    824:                        strlcpy(sd->sd_name, "RAID 1", sizeof(sd->sd_name));
                    825:                        break;
                    826: #if 0
                    827:                case 'c':
                    828:                        if (no_chunk != 1)
                    829:                                goto unwind;
                    830:                        strlcpy(sd->sd_name, "RAID C", sizeof(sd->sd_name));
                    831:                        break;
                    832: #endif
                    833:                default:
                    834:                        goto unwind;
                    835:                }
                    836:
                    837:                /* fill out chunk array */
                    838:                i = 0;
                    839:                SLIST_FOREACH(ch_entry, cl, src_link)
                    840:                        sd->sd_vol.sv_chunks[i++] = ch_entry;
                    841:
                    842:                /* fill out all chunk metadata */
                    843:                sr_create_chunk_meta(sc, cl);
                    844:
                    845:                /* fill out all volume metadata */
                    846:                ch_entry = SLIST_FIRST(cl);
                    847:                vol_size = ch_entry->src_meta.scm_coerced_size;
                    848:                DNPRINTF(SR_D_IOCTL,
                    849:                    "%s: sr_ioctl_createraid: vol_size: %lld\n",
                    850:                    DEVNAME(sc), vol_size);
                    851:                sd->sd_vol.sv_meta.svm_no_chunk = no_chunk;
                    852:                sd->sd_vol.sv_meta.svm_size = vol_size;
                    853:                sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE;
                    854:                sd->sd_vol.sv_meta.svm_level = bc->bc_level;
                    855:                strlcpy(sd->sd_vol.sv_meta.svm_vendor, "OPENBSD",
                    856:                    sizeof(sd->sd_vol.sv_meta.svm_vendor));
                    857:                snprintf(sd->sd_vol.sv_meta.svm_product,
                    858:                    sizeof(sd->sd_vol.sv_meta.svm_product), "SR %s",
                    859:                    sd->sd_name);
                    860:                snprintf(sd->sd_vol.sv_meta.svm_revision,
                    861:                    sizeof(sd->sd_vol.sv_meta.svm_revision), "%03d",
                    862:                    SR_META_VERSION);
                    863:
                    864:                sd->sd_meta_flags = bc->bc_flags & BIOC_SCNOAUTOASSEMBLE;
                    865:                updatemeta = 1;
                    866:        } else if (no_meta == no_chunk) {
                    867:                if (user == 0 && sd->sd_meta_flags & BIOC_SCNOAUTOASSEMBLE) {
                    868:                        DNPRINTF(SR_D_META, "%s: disk not auto assembled from "
                    869:                            "metadata\n", DEVNAME(sc));
                    870:                        goto unwind;
                    871:                }
                    872:                if (sr_already_assembled(sd)) {
                    873:                        printf("%s: disk ", DEVNAME(sc));
                    874:                        sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
                    875:                        printf(" already assembled\n");
                    876:                        goto unwind;
                    877:                }
                    878:                DNPRINTF(SR_D_META, "%s: disk assembled from metadata\n",
                    879:                    DEVNAME(sc));
                    880:                updatemeta = 0;
                    881:        } else {
                    882:                if (sr_already_assembled(sd)) {
                    883:                        printf("%s: disk ", DEVNAME(sc));
                    884:                        sr_print_uuid(&sd->sd_meta->ssd_uuid, 0);
                    885:                        printf(" already assembled; will not partial "
                    886:                            "assemble it\n");
                    887:                        goto unwind;
                    888:                }
                    889:                printf("%s: not yet partial bringup\n", DEVNAME(sc));
                    890:                goto unwind;
                    891:        }
                    892:
                    893:        /* XXX metadata SHALL be fully filled in at this point */
                    894:
                    895:        switch (bc->bc_level) {
                    896:        case 1:
                    897:                /* fill out discipline members */
                    898:                sd->sd_type = SR_MD_RAID1;
                    899:                sd->sd_max_ccb_per_wu = no_chunk;
                    900:                sd->sd_max_wu = SR_RAID1_NOWU;
                    901:
                    902:                /* setup discipline pointers */
                    903:                sd->sd_alloc_resources = sr_raid1_alloc_resources;
                    904:                sd->sd_free_resources = sr_raid1_free_resources;
                    905:                sd->sd_scsi_inquiry = sr_raid_inquiry;
                    906:                sd->sd_scsi_read_cap = sr_raid_read_cap;
                    907:                sd->sd_scsi_tur = sr_raid_tur;
                    908:                sd->sd_scsi_req_sense = sr_raid_request_sense;
                    909:                sd->sd_scsi_start_stop = sr_raid_start_stop;
                    910:                sd->sd_scsi_sync = sr_raid_sync;
                    911:                sd->sd_scsi_rw = sr_raid1_rw;
                    912:                sd->sd_set_chunk_state = sr_raid_set_chunk_state;
                    913:                sd->sd_set_vol_state = sr_raid_set_vol_state;
                    914:                break;
                    915: #ifdef CRYPTO
                    916:        case 'c':
                    917:                /* fill out discipline members */
                    918:                sd->sd_type = SR_MD_RAIDC;
                    919:                sd->sd_max_ccb_per_wu = no_chunk;
                    920:                sd->sd_max_wu = SR_RAIDC_NOWU;
                    921:
                    922:                /* setup discipline pointers */
                    923:                sd->sd_alloc_resources = sr_raidc_alloc_resources;
                    924:                sd->sd_free_resources = sr_raidc_free_resources;
                    925:                sd->sd_scsi_inquiry = sr_raid_inquiry;
                    926:                sd->sd_scsi_read_cap = sr_raid_read_cap;
                    927:                sd->sd_scsi_tur = sr_raid_tur;
                    928:                sd->sd_scsi_req_sense = sr_raid_request_sense;
                    929:                sd->sd_scsi_start_stop = sr_raid_start_stop;
                    930:                sd->sd_scsi_sync = sr_raid_sync;
                    931:                sd->sd_scsi_rw = sr_raidc_rw;
                    932:                sd->sd_set_chunk_state = sr_raid_set_chunk_state;
                    933:                sd->sd_set_vol_state = sr_raid_set_vol_state;
                    934:                break;
                    935: #endif
                    936:        default:
                    937:                printf("default %d\n", bc->bc_level);
                    938:                goto unwind;
                    939:        }
                    940:
                    941:        /* allocate all resources */
                    942:        if ((rv = sd->sd_alloc_resources(sd)))
                    943:                goto unwind;
                    944:
                    945:        /* setup scsi midlayer */
                    946:        sd->sd_link.openings = sd->sd_max_wu;
                    947:        sd->sd_link.device = &sr_dev;
                    948:        sd->sd_link.device_softc = sc;
                    949:        sd->sd_link.adapter_softc = sc;
                    950:        sd->sd_link.adapter = &sr_switch;
                    951:        sd->sd_link.adapter_target = SR_MAX_LD;
                    952:        sd->sd_link.adapter_buswidth = 1;
                    953:        bzero(&saa, sizeof(saa));
                    954:        saa.saa_sc_link = &sd->sd_link;
                    955:
                    956:        /* we passed all checks return ENXIO if volume can't be created */
                    957:        rv = ENXIO;
                    958:
                    959:        /* clear sense data */
                    960:        bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
                    961:
                    962:        /* use temporary discipline pointer */
                    963:        s = splhigh();
                    964:        sc->sc_attach_dis = sd;
                    965:        splx(s);
                    966:        dev2 = config_found(&sc->sc_dev, &saa, scsiprint);
                    967:        s = splhigh();
                    968:        sc->sc_attach_dis = NULL;
                    969:        splx(s);
                    970:        TAILQ_FOREACH(dev, &alldevs, dv_list)
                    971:                if (dev->dv_parent == dev2)
                    972:                        break;
                    973:        if (dev == NULL)
                    974:                goto unwind;
                    975:
                    976:        DNPRINTF(SR_D_IOCTL, "%s: sr device added: %s on scsibus%d\n",
                    977:            DEVNAME(sc), dev->dv_xname, sd->sd_link.scsibus);
                    978:
                    979:        sc->sc_dis[sd->sd_link.scsibus] = sd;
                    980:        for (i = 0, vol = -1; i <= sd->sd_link.scsibus; i++)
                    981:                if (sc->sc_dis[i])
                    982:                        vol++;
                    983:
                    984:        rv = 0;
                    985:        if (updatemeta) {
                    986:                /* fill out remaining volume metadata */
                    987:                sd->sd_vol.sv_meta.svm_volid = vol;
                    988:                strlcpy(sd->sd_vol.sv_meta.svm_devname, dev->dv_xname,
                    989:                    sizeof(sd->sd_vol.sv_meta.svm_devname));
                    990:
                    991:        }
                    992:
                    993:        /* save metadata to disk */
                    994:        rv = sr_save_metadata(sd, SR_VOL_DIRTY);
                    995:
                    996: #ifndef SMALL_KERNEL
                    997:        if (sr_create_sensors(sd))
                    998:                printf("%s: unable to create sensor for %s\n", DEVNAME(sc),
                    999:                    dev->dv_xname);
                   1000:        else
                   1001:                sd->sd_vol.sv_sensor_valid = 1;
                   1002: #endif /* SMALL_KERNEL */
                   1003:
                   1004:        sd->sd_scsibus_dev = dev2;
                   1005:        sd->sd_shutdownhook = shutdownhook_establish(sr_shutdown, sd);
                   1006:
                   1007:        return (rv);
                   1008:
                   1009: unwind:
                   1010:        sr_shutdown_discipline(sd);
                   1011:
                   1012:        return (rv);
                   1013: }
                   1014:
                   1015: int
                   1016: sr_open_chunks(struct sr_softc *sc, struct sr_chunk_head *cl, dev_t *dt,
                   1017:     int no_chunk)
                   1018: {
                   1019:        struct sr_chunk         *ch_entry, *ch_prev = NULL;
                   1020:        struct disklabel        label;
                   1021:        struct bdevsw           *bdsw;
                   1022:        char                    *name;
                   1023:        int                     maj, unit, part, i, error;
                   1024:        daddr64_t               size;
                   1025:        dev_t                   dev;
                   1026:
                   1027:        DNPRINTF(SR_D_IOCTL, "%s: sr_open_chunks(%d)\n", DEVNAME(sc), no_chunk);
                   1028:
                   1029:        /* fill out chunk list */
                   1030:        for (i = 0; i < no_chunk; i++) {
                   1031:                ch_entry = malloc(sizeof(struct sr_chunk), M_DEVBUF, M_WAITOK);
                   1032:                bzero(ch_entry, sizeof(struct sr_chunk));
                   1033:                /* keep disks in user supplied order */
                   1034:                if (ch_prev)
                   1035:                        SLIST_INSERT_AFTER(ch_prev, ch_entry, src_link);
                   1036:                else
                   1037:                        SLIST_INSERT_HEAD(cl, ch_entry, src_link);
                   1038:                ch_prev = ch_entry;
                   1039:
                   1040:                dev = dt[i];
                   1041:                maj = major(dev);
                   1042:                part = DISKPART(dev);
                   1043:                unit = DISKUNIT(dev);
                   1044:                bdsw = &bdevsw[maj];
                   1045:
                   1046:                name = findblkname(maj);
                   1047:                if (name == NULL)
                   1048:                        goto unwind;
                   1049:
                   1050:                snprintf(ch_entry->src_devname, sizeof(ch_entry->src_devname),
                   1051:                    "%s%d%c", name, unit, part + 'a');
                   1052:                name = ch_entry->src_devname;
                   1053:
                   1054:                /* open device */
                   1055:                error = bdsw->d_open(dev, FREAD | FWRITE , S_IFBLK, curproc);
                   1056:
                   1057:                /* get disklabel */
                   1058:                error = bdsw->d_ioctl(dev, DIOCGDINFO, (void *)&label,
                   1059:                    0, NULL);
                   1060:                if (error) {
                   1061:                        printf("%s: %s can't obtain disklabel\n",
                   1062:                            DEVNAME(sc), name);
                   1063:                        bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
                   1064:                        goto unwind;
                   1065:                }
                   1066:
                   1067:                /* make sure the partition is of the right type */
                   1068:                if (label.d_partitions[part].p_fstype != FS_RAID) {
                   1069:                        printf("%s: %s partition not of type RAID (%d)\n",
                   1070:                            DEVNAME(sc), name,
                   1071:                            label.d_partitions[part].p_fstype);
                   1072:                        bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
                   1073:                        goto unwind;
                   1074:                }
                   1075:
                   1076:                /* get partition size */
                   1077:                ch_entry->src_size = size = DL_GETPSIZE(&label.d_partitions[part]) -
                   1078:                    SR_META_SIZE - SR_META_OFFSET;
                   1079:                if (size <= 0) {
                   1080:                        printf("%s: %s partition too small\n",
                   1081:                            DEVNAME(sc), name);
                   1082:                        bdsw->d_close(dev, FWRITE, S_IFBLK, curproc);
                   1083:                        goto unwind;
                   1084:                }
                   1085:
                   1086:
                   1087:                ch_entry->src_dev_mm = dev; /* major/minor */
                   1088:
                   1089:                DNPRINTF(SR_D_IOCTL, "%s: found %s size %d\n", DEVNAME(sc),
                   1090:                    name, size);
                   1091:        }
                   1092:
                   1093:        return (0);
                   1094: unwind:
                   1095:        printf("%s: invalid device: %s\n", DEVNAME(sc), name ? name : "nodev");
                   1096:        return (1);
                   1097: }
                   1098:
                   1099: int
                   1100: sr_read_meta(struct sr_discipline *sd)
                   1101: {
                   1102:        struct sr_softc         *sc = sd->sd_sc;
                   1103:        struct sr_chunk_head    *cl = &sd->sd_vol.sv_chunk_list;
                   1104:        struct sr_metadata      *sm = sd->sd_meta, *m;
                   1105:        struct sr_chunk         *ch_entry;
                   1106:        struct buf              b;
                   1107:        struct sr_vol_meta      *mv;
                   1108:        struct sr_chunk_meta    *mc;
                   1109:        size_t                  sz = SR_META_SIZE * 512;
                   1110:        int                     no_chunk = 0;
                   1111:        u_int32_t               volid, ondisk = 0, cid;
                   1112:
                   1113:        DNPRINTF(SR_D_META, "%s: sr_read_meta\n", DEVNAME(sc));
                   1114:
                   1115:        m = malloc(sz , M_DEVBUF, M_WAITOK);
                   1116:        bzero(m, sz);
                   1117:
                   1118:        SLIST_FOREACH(ch_entry, cl, src_link) {
                   1119:                bzero(&b, sizeof(b));
                   1120:
                   1121:                b.b_flags = B_READ;
                   1122:                b.b_blkno = SR_META_OFFSET;
                   1123:                b.b_bcount = sz;
                   1124:                b.b_bufsize = sz;
                   1125:                b.b_resid = sz;
                   1126:                b.b_data = (void *)m;
                   1127:                b.b_error = 0;
                   1128:                b.b_proc = curproc;
                   1129:                b.b_dev = ch_entry->src_dev_mm;
                   1130:                b.b_vp = NULL;
                   1131:                b.b_iodone = NULL;
                   1132:                LIST_INIT(&b.b_dep);
                   1133:                bdevsw_lookup(b.b_dev)->d_strategy(&b);
                   1134:                biowait(&b);
                   1135:
                   1136:                /* XXX mark chunk offline and restart metadata write */
                   1137:                if (b.b_flags & B_ERROR) {
                   1138:                        printf("%s: %s i/o error on block %d while reading "
                   1139:                            "metadata %d\n", DEVNAME(sc),
                   1140:                            ch_entry->src_devname, b.b_blkno, b.b_error);
                   1141:                        continue;
                   1142:                }
                   1143:
                   1144:                if (m->ssd_magic != SR_MAGIC)
                   1145:                        continue;
                   1146:
                   1147:                /* validate metadata */
                   1148:                if (sr_validate_metadata(sc, ch_entry->src_dev_mm, m)) {
                   1149:                        printf("%s: invalid metadata\n", DEVNAME(sc));
                   1150:                        no_chunk = -1;
                   1151:                        goto bad;
                   1152:                }
                   1153:
                   1154:                mv = (struct sr_vol_meta *)(m + 1);
                   1155:                mc = (struct sr_chunk_meta *)(mv + 1);
                   1156:
                   1157:                /* we asssume that the first chunk has the initial metadata */
                   1158:                if (no_chunk++ == 0) {
                   1159:                        bcopy(m, sm, sz);
                   1160:                        bcopy(m, sd->sd_meta, sizeof(*sd->sd_meta));
                   1161:                        bcopy(mv, &sd->sd_vol.sv_meta,
                   1162:                            sizeof(sd->sd_vol.sv_meta));
                   1163:
                   1164:                        volid = m->ssd_vd_volid;
                   1165:                        sd->sd_meta_flags = sm->ssd_flags;
                   1166:                }
                   1167:
                   1168:                if (bcmp(&sm->ssd_uuid, &sd->sd_vol.sv_meta.svm_uuid,
                   1169:                    sizeof(struct sr_uuid))) {
                   1170:                        printf("%s: %s invalid chunk uuid ",
                   1171:                            DEVNAME(sc), ch_entry->src_devname);
                   1172:                        sr_print_uuid(&sm->ssd_uuid, 0);
                   1173:                        printf(", expected ");
                   1174:                        sr_print_uuid(&sd->sd_vol.sv_meta.svm_uuid, 1);
                   1175:                        no_chunk = -1;
                   1176:                        goto bad;
                   1177:                }
                   1178:
                   1179:                /* we have meta data on disk */
                   1180:                ch_entry->src_meta_ondisk = 1;
                   1181:
                   1182:                /* make sure we are part of this vd */
                   1183:                if (volid != m->ssd_vd_volid) {
                   1184:                        printf("%s: %s invalid volume id %d, expected %d\n",
                   1185:                            DEVNAME(sc), ch_entry->src_devname,
                   1186:                            volid, m->ssd_vd_volid);
                   1187:                        no_chunk = -1;
                   1188:                        goto bad;
                   1189:                }
                   1190:
                   1191:                if (m->ssd_chunk_id > m->ssd_chunk_no) {
                   1192:                        printf("%s: %s chunk id out of range %d, expected "
                   1193:                            "lower than %d\n", DEVNAME(sc),
                   1194:                            ch_entry->src_devname,
                   1195:                            m->ssd_chunk_id, m->ssd_chunk_no);
                   1196:                        no_chunk = -1;
                   1197:                        goto bad;
                   1198:                }
                   1199:
                   1200:                if (sd->sd_vol.sv_chunks[m->ssd_chunk_id]) {
                   1201:                        printf("%s: %s chunk id %d already in use\n",
                   1202:                            DEVNAME(sc), ch_entry->src_devname,
                   1203:                            m->ssd_chunk_id);
                   1204:                        no_chunk = -1;
                   1205:                        goto bad;
                   1206:                }
                   1207:
                   1208:                sd->sd_vol.sv_chunks[m->ssd_chunk_id] = ch_entry;
                   1209:                bcopy(mc + m->ssd_chunk_id, &ch_entry->src_meta,
                   1210:                    sizeof(ch_entry->src_meta));
                   1211:
                   1212:                if (ondisk == 0) {
                   1213:                        ondisk = m->ssd_ondisk;
                   1214:                        cid = m->ssd_chunk_id;
                   1215:                }
                   1216:
                   1217:                if (m->ssd_ondisk != ondisk) {
                   1218:                        printf("%s: %s chunk id %d contains stale metadata\n",
                   1219:                            DEVNAME(sc), ch_entry->src_devname,
                   1220:                            m->ssd_ondisk < ondisk ? m->ssd_chunk_id : cid);
                   1221:                        no_chunk = -1;
                   1222:                        goto bad;
                   1223:                }
                   1224:        }
                   1225:
                   1226:        if (no_chunk != m->ssd_chunk_no) {
                   1227:                DNPRINTF(SR_D_META, "%s: not enough chunks supplied\n",
                   1228:                    DEVNAME(sc));
                   1229:                no_chunk = -1;
                   1230:                goto bad;
                   1231:        }
                   1232:
                   1233:        DNPRINTF(SR_D_META, "%s: sr_read_meta: found %d elements\n",
                   1234:            DEVNAME(sc), no_chunk);
                   1235:
                   1236:        sr_print_metadata(m);
                   1237:
                   1238: bad:
                   1239:        /* return nr of chunks that contain metadata */
                   1240:        free(m, M_DEVBUF);
                   1241:        return (no_chunk);
                   1242: }
                   1243:
                   1244: int
                   1245: sr_create_chunk_meta(struct sr_softc *sc, struct sr_chunk_head *cl)
                   1246: {
                   1247:        struct sr_chunk         *ch_entry;
                   1248:        struct sr_uuid          uuid;
                   1249:        int                     rv = 1, cid = 0;
                   1250:        char                    *name;
                   1251:        u_int64_t               max_chunk_sz = 0, min_chunk_sz;
                   1252:
                   1253:        DNPRINTF(SR_D_IOCTL, "%s: sr_create_chunk_meta\n", DEVNAME(sc));
                   1254:
                   1255:        sr_get_uuid(&uuid);
                   1256:
                   1257:        /* fill out stuff and get largest chunk size while looping */
                   1258:        SLIST_FOREACH(ch_entry, cl, src_link) {
                   1259:                name = ch_entry->src_devname;
                   1260:                ch_entry->src_meta.scm_size = ch_entry->src_size;
                   1261:                ch_entry->src_meta.scm_chunk_id = cid++;
                   1262:                ch_entry->src_meta.scm_status = BIOC_SDONLINE;
                   1263:                strlcpy(ch_entry->src_meta.scm_devname, name,
                   1264:                    sizeof(ch_entry->src_meta.scm_devname));
                   1265:                bcopy(&uuid,  &ch_entry->src_meta.scm_uuid,
                   1266:                    sizeof(ch_entry->src_meta.scm_uuid));
                   1267:
                   1268:                if (ch_entry->src_meta.scm_size > max_chunk_sz)
                   1269:                        max_chunk_sz = ch_entry->src_meta.scm_size;
                   1270:        }
                   1271:
                   1272:        /* get smallest chunk size */
                   1273:        min_chunk_sz = max_chunk_sz;
                   1274:        SLIST_FOREACH(ch_entry, cl, src_link)
                   1275:                if (ch_entry->src_meta.scm_size < min_chunk_sz)
                   1276:                        min_chunk_sz = ch_entry->src_meta.scm_size;
                   1277:
                   1278:        /* equalize all sizes */
                   1279:        SLIST_FOREACH(ch_entry, cl, src_link)
                   1280:                ch_entry->src_meta.scm_coerced_size = min_chunk_sz;
                   1281:
                   1282:        /* whine if chunks are not the same size */
                   1283:        if (min_chunk_sz != max_chunk_sz)
                   1284:                printf("%s: chunk sizes are not equal; up to %llu blocks "
                   1285:                    "wasted per chunk\n",
                   1286:                    DEVNAME(sc), max_chunk_sz - min_chunk_sz);
                   1287:
                   1288:        rv = 0;
                   1289:
                   1290:        return (rv);
                   1291: }
                   1292:
                   1293: void
                   1294: sr_unwind_chunks(struct sr_softc *sc, struct sr_chunk_head *cl)
                   1295: {
                   1296:        struct sr_chunk         *ch_entry, *ch_next;
                   1297:        dev_t                   dev;
                   1298:
                   1299:        DNPRINTF(SR_D_IOCTL, "%s: sr_unwind_chunks\n", DEVNAME(sc));
                   1300:
                   1301:        if (!cl)
                   1302:                return;
                   1303:
                   1304:        for (ch_entry = SLIST_FIRST(cl);
                   1305:            ch_entry != SLIST_END(cl); ch_entry = ch_next) {
                   1306:                ch_next = SLIST_NEXT(ch_entry, src_link);
                   1307:
                   1308:                dev = ch_entry->src_dev_mm;
                   1309:
                   1310:                if (dev != NODEV)
                   1311:                        bdevsw_lookup(dev)->d_close(dev, FWRITE, S_IFBLK,
                   1312:                            curproc);
                   1313:
                   1314:                free(ch_entry, M_DEVBUF);
                   1315:        }
                   1316:        SLIST_INIT(cl);
                   1317: }
                   1318:
                   1319: void
                   1320: sr_free_discipline(struct sr_discipline *sd)
                   1321: {
                   1322: #ifdef SR_DEBUG
                   1323:        struct sr_softc         *sc = sd->sd_sc;
                   1324: #endif
                   1325:        if (!sd)
                   1326:                return;
                   1327:
                   1328:        DNPRINTF(SR_D_DIS, "%s: sr_free_discipline %s\n",
                   1329:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   1330:
                   1331:        if (sd->sd_free_resources)
                   1332:                sd->sd_free_resources(sd);
                   1333:        if (sd->sd_vol.sv_chunks)
                   1334:                free(sd->sd_vol.sv_chunks, M_DEVBUF);
                   1335:        free(sd, M_DEVBUF);
                   1336: }
                   1337:
                   1338: void
                   1339: sr_shutdown_discipline(struct sr_discipline *sd)
                   1340: {
                   1341:        struct sr_softc         *sc = sd->sd_sc;
                   1342:        int                     s;
                   1343:
                   1344:        if (!sd || !sc)
                   1345:                return;
                   1346:
                   1347:        DNPRINTF(SR_D_DIS, "%s: sr_shutdown_discipline %s\n",
                   1348:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   1349:
                   1350:        s = splbio();
                   1351:
                   1352:        /* make sure there isn't a sync pending and yield */
                   1353:        wakeup(sd);
                   1354:        while (sd->sd_sync || sd->sd_must_flush)
                   1355:                if (tsleep(&sd->sd_sync, MAXPRI, "sr_down", 60 * hz) ==
                   1356:                    EWOULDBLOCK)
                   1357:                        break;
                   1358:
                   1359: #ifndef SMALL_KERNEL
                   1360:        sr_delete_sensors(sd);
                   1361: #endif /* SMALL_KERNEL */
                   1362:
                   1363:        if (sd->sd_scsibus_dev)
                   1364:                config_detach(sd->sd_scsibus_dev, DETACH_FORCE);
                   1365:
                   1366:        sr_unwind_chunks(sc, &sd->sd_vol.sv_chunk_list);
                   1367:
                   1368:        if (sd)
                   1369:                sr_free_discipline(sd);
                   1370:
                   1371:        splx(s);
                   1372: }
                   1373:
                   1374: int
                   1375: sr_raid_inquiry(struct sr_workunit *wu)
                   1376: {
                   1377:        struct sr_discipline    *sd = wu->swu_dis;
                   1378:        struct scsi_xfer        *xs = wu->swu_xs;
                   1379:        struct scsi_inquiry_data inq;
                   1380:
                   1381:        DNPRINTF(SR_D_DIS, "%s: sr_raid_inquiry\n", DEVNAME(sd->sd_sc));
                   1382:
                   1383:        bzero(&inq, sizeof(inq));
                   1384:        inq.device = T_DIRECT;
                   1385:        inq.dev_qual2 = 0;
                   1386:        inq.version = 2;
                   1387:        inq.response_format = 2;
                   1388:        inq.additional_length = 32;
                   1389:        strlcpy(inq.vendor, sd->sd_vol.sv_meta.svm_vendor,
                   1390:            sizeof(inq.vendor));
                   1391:        strlcpy(inq.product, sd->sd_vol.sv_meta.svm_product,
                   1392:            sizeof(inq.product));
                   1393:        strlcpy(inq.revision, sd->sd_vol.sv_meta.svm_revision,
                   1394:            sizeof(inq.revision));
                   1395:        sr_copy_internal_data(xs, &inq, sizeof(inq));
                   1396:
                   1397:        return (0);
                   1398: }
                   1399:
                   1400: int
                   1401: sr_raid_read_cap(struct sr_workunit *wu)
                   1402: {
                   1403:        struct sr_discipline    *sd = wu->swu_dis;
                   1404:        struct scsi_xfer        *xs = wu->swu_xs;
                   1405:        struct scsi_read_cap_data rcd;
                   1406:
                   1407:        DNPRINTF(SR_D_DIS, "%s: sr_raid_read_cap\n", DEVNAME(sd->sd_sc));
                   1408:
                   1409:        bzero(&rcd, sizeof(rcd));
                   1410:        _lto4b(sd->sd_vol.sv_meta.svm_size, rcd.addr);
                   1411:        _lto4b(512, rcd.length);
                   1412:        sr_copy_internal_data(xs, &rcd, sizeof(rcd));
                   1413:
                   1414:        return (0);
                   1415: }
                   1416:
                   1417: int
                   1418: sr_raid_tur(struct sr_workunit *wu)
                   1419: {
                   1420:        struct sr_discipline    *sd = wu->swu_dis;
                   1421:
                   1422:        DNPRINTF(SR_D_DIS, "%s: sr_raid_tur\n", DEVNAME(sd->sd_sc));
                   1423:
                   1424:        if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
                   1425:                sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT;
                   1426:                sd->sd_scsi_sense.flags = SKEY_NOT_READY;
                   1427:                sd->sd_scsi_sense.add_sense_code = 0x04;
                   1428:                sd->sd_scsi_sense.add_sense_code_qual = 0x11;
                   1429:                sd->sd_scsi_sense.extra_len = 4;
                   1430:                return (1);
                   1431:        } else if (sd->sd_vol.sv_meta.svm_status == BIOC_SVINVALID) {
                   1432:                sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT;
                   1433:                sd->sd_scsi_sense.flags = SKEY_HARDWARE_ERROR;
                   1434:                sd->sd_scsi_sense.add_sense_code = 0x05;
                   1435:                sd->sd_scsi_sense.add_sense_code_qual = 0x00;
                   1436:                sd->sd_scsi_sense.extra_len = 4;
                   1437:                return (1);
                   1438:        }
                   1439:
                   1440:        return (0);
                   1441: }
                   1442:
                   1443: int
                   1444: sr_raid_request_sense(struct sr_workunit *wu)
                   1445: {
                   1446:        struct sr_discipline    *sd = wu->swu_dis;
                   1447:        struct scsi_xfer        *xs = wu->swu_xs;
                   1448:
                   1449:        DNPRINTF(SR_D_DIS, "%s: sr_raid_request_sense\n",
                   1450:            DEVNAME(sd->sd_sc));
                   1451:
                   1452:        /* use latest sense data */
                   1453:        bcopy(&sd->sd_scsi_sense, &xs->sense, sizeof(xs->sense));
                   1454:
                   1455:        /* clear sense data */
                   1456:        bzero(&sd->sd_scsi_sense, sizeof(sd->sd_scsi_sense));
                   1457:
                   1458:        return (0);
                   1459: }
                   1460:
                   1461: int
                   1462: sr_raid_start_stop(struct sr_workunit *wu)
                   1463: {
                   1464:        struct sr_discipline    *sd = wu->swu_dis;
                   1465:        struct scsi_xfer        *xs = wu->swu_xs;
                   1466:        struct scsi_start_stop  *ss = (struct scsi_start_stop *)xs->cmd;
                   1467:        int                     rv = 1;
                   1468:
                   1469:        DNPRINTF(SR_D_DIS, "%s: sr_raid_start_stop\n",
                   1470:            DEVNAME(sd->sd_sc));
                   1471:
                   1472:        if (!ss)
                   1473:                return (rv);
                   1474:
                   1475:        if (ss->byte2 == 0x00) {
                   1476:                /* START */
                   1477:                if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
                   1478:                        /* bring volume online */
                   1479:                        /* XXX check to see if volume can be brought online */
                   1480:                        sd->sd_vol.sv_meta.svm_status = BIOC_SVONLINE;
                   1481:                }
                   1482:                rv = 0;
                   1483:        } else /* XXX is this the check? if (byte == 0x01) */ {
                   1484:                /* STOP */
                   1485:                if (sd->sd_vol.sv_meta.svm_status == BIOC_SVONLINE) {
                   1486:                        /* bring volume offline */
                   1487:                        sd->sd_vol.sv_meta.svm_status = BIOC_SVOFFLINE;
                   1488:                }
                   1489:                rv = 0;
                   1490:        }
                   1491:
                   1492:        return (rv);
                   1493: }
                   1494:
                   1495: int
                   1496: sr_raid_sync(struct sr_workunit *wu)
                   1497: {
                   1498:        struct sr_discipline    *sd = wu->swu_dis;
                   1499:        int                     s, rv = 0, ios;
                   1500:
                   1501:        DNPRINTF(SR_D_DIS, "%s: sr_raid_sync\n", DEVNAME(sd->sd_sc));
                   1502:
                   1503:        /* when doing a fake sync don't coun't the wu */
                   1504:        ios = wu->swu_fake ? 0 : 1;
                   1505:
                   1506:        s = splbio();
                   1507:        sd->sd_sync = 1;
                   1508:
                   1509:        while (sd->sd_wu_pending > ios)
                   1510:                if (tsleep(sd, PRIBIO, "sr_sync", 15 * hz) == EWOULDBLOCK) {
                   1511:                        DNPRINTF(SR_D_DIS, "%s: sr_raid_sync timeout\n",
                   1512:                            DEVNAME(sd->sd_sc));
                   1513:                        rv = 1;
                   1514:                        break;
                   1515:                }
                   1516:
                   1517:        sd->sd_sync = 0;
                   1518:        splx(s);
                   1519:
                   1520:        wakeup(&sd->sd_sync);
                   1521:
                   1522:        return (rv);
                   1523: }
                   1524:
                   1525: void
                   1526: sr_raid_startwu(struct sr_workunit *wu)
                   1527: {
                   1528:        struct sr_discipline    *sd = wu->swu_dis;
                   1529:        struct sr_ccb           *ccb;
                   1530:
                   1531:        splassert(IPL_BIO);
                   1532:
                   1533:        if (wu->swu_state == SR_WU_RESTART)
                   1534:                /*
                   1535:                 * no need to put the wu on the pending queue since we
                   1536:                 * are restarting the io
                   1537:                 */
                   1538:                 ;
                   1539:        else
                   1540:                /* move wu to pending queue */
                   1541:                TAILQ_INSERT_TAIL(&sd->sd_wu_pendq, wu, swu_link);
                   1542:
                   1543:        /* start all individual ios */
                   1544:        TAILQ_FOREACH(ccb, &wu->swu_ccb, ccb_link) {
                   1545:                bdevsw_lookup(ccb->ccb_buf.b_dev)->d_strategy(&ccb->ccb_buf);
                   1546:        }
                   1547: }
                   1548:
                   1549: void
                   1550: sr_raid_set_chunk_state(struct sr_discipline *sd, int c, int new_state)
                   1551: {
                   1552:        int                     old_state, s;
                   1553:
                   1554:        DNPRINTF(SR_D_STATE, "%s: %s: %s: sr_raid_set_chunk_state %d -> %d\n",
                   1555:            DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
                   1556:            sd->sd_vol.sv_chunks[c]->src_meta.scm_devname, c, new_state);
                   1557:
                   1558:        /* ok to go to splbio since this only happens in error path */
                   1559:        s = splbio();
                   1560:        old_state = sd->sd_vol.sv_chunks[c]->src_meta.scm_status;
                   1561:
                   1562:        /* multiple IOs to the same chunk that fail will come through here */
                   1563:        if (old_state == new_state)
                   1564:                goto done;
                   1565:
                   1566:        switch (old_state) {
                   1567:        case BIOC_SDONLINE:
                   1568:                switch (new_state) {
                   1569:                case BIOC_SDOFFLINE:
                   1570:                        break;
                   1571:                case BIOC_SDSCRUB:
                   1572:                        break;
                   1573:                default:
                   1574:                        goto die;
                   1575:                }
                   1576:                break;
                   1577:
                   1578:        case BIOC_SDOFFLINE:
                   1579:                if (new_state == BIOC_SDREBUILD) {
                   1580:                        ;
                   1581:                } else
                   1582:                        goto die;
                   1583:                break;
                   1584:
                   1585:        case BIOC_SDSCRUB:
                   1586:                if (new_state == BIOC_SDONLINE) {
                   1587:                        ;
                   1588:                } else
                   1589:                        goto die;
                   1590:                break;
                   1591:
                   1592:        case BIOC_SDREBUILD:
                   1593:                if (new_state == BIOC_SDONLINE) {
                   1594:                        ;
                   1595:                } else
                   1596:                        goto die;
                   1597:                break;
                   1598:
                   1599:        case BIOC_SDHOTSPARE:
                   1600:                if (new_state == BIOC_SDREBUILD) {
                   1601:                        ;
                   1602:                } else
                   1603:                        goto die;
                   1604:                break;
                   1605:
                   1606:        default:
                   1607: die:
                   1608:                splx(s); /* XXX */
                   1609:                panic("%s: %s: %s: invalid chunk state transition "
                   1610:                    "%d -> %d\n", DEVNAME(sd->sd_sc),
                   1611:                    sd->sd_vol.sv_meta.svm_devname,
                   1612:                    sd->sd_vol.sv_chunks[c]->src_meta.scm_devname,
                   1613:                    old_state, new_state);
                   1614:                /* NOTREACHED */
                   1615:        }
                   1616:
                   1617:        sd->sd_vol.sv_chunks[c]->src_meta.scm_status = new_state;
                   1618:        sd->sd_set_vol_state(sd);
                   1619:
                   1620:        sd->sd_must_flush = 1;
                   1621:        workq_add_task(NULL, 0, sr_save_metadata_callback, sd, NULL);
                   1622: done:
                   1623:        splx(s);
                   1624: }
                   1625:
                   1626: void
                   1627: sr_raid_set_vol_state(struct sr_discipline *sd)
                   1628: {
                   1629:        int                     states[SR_MAX_STATES];
                   1630:        int                     new_state, i, s, nd;
                   1631:        int                     old_state = sd->sd_vol.sv_meta.svm_status;
                   1632:
                   1633:        DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state\n",
                   1634:            DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
                   1635:
                   1636:        nd = sd->sd_vol.sv_meta.svm_no_chunk;
                   1637:
                   1638:        for (i = 0; i < SR_MAX_STATES; i++)
                   1639:                states[i] = 0;
                   1640:
                   1641:        for (i = 0; i < nd; i++) {
                   1642:                s = sd->sd_vol.sv_chunks[i]->src_meta.scm_status;
                   1643:                if (s > SR_MAX_STATES)
                   1644:                        panic("%s: %s: %s: invalid chunk state",
                   1645:                            DEVNAME(sd->sd_sc),
                   1646:                            sd->sd_vol.sv_meta.svm_devname,
                   1647:                            sd->sd_vol.sv_chunks[i]->src_meta.scm_devname);
                   1648:                states[s]++;
                   1649:        }
                   1650:
                   1651:        if (states[BIOC_SDONLINE] == nd)
                   1652:                new_state = BIOC_SVONLINE;
                   1653:        else if (states[BIOC_SDONLINE] == 0)
                   1654:                new_state = BIOC_SVOFFLINE;
                   1655:        else if (states[BIOC_SDSCRUB] != 0)
                   1656:                new_state = BIOC_SVSCRUB;
                   1657:        else if (states[BIOC_SDREBUILD] != 0)
                   1658:                new_state = BIOC_SVREBUILD;
                   1659:        else if (states[BIOC_SDOFFLINE] != 0)
                   1660:                new_state = BIOC_SVDEGRADED;
                   1661:        else {
                   1662:                printf("old_state = %d, ", old_state);
                   1663:                for (i = 0; i < nd; i++)
                   1664:                        printf("%d = %d, ", i,
                   1665:                            sd->sd_vol.sv_chunks[i]->src_meta.scm_status);
                   1666:                panic("invalid new_state");
                   1667:        }
                   1668:
                   1669:        DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state %d -> %d\n",
                   1670:            DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
                   1671:            old_state, new_state);
                   1672:
                   1673:        switch (old_state) {
                   1674:        case BIOC_SVONLINE:
                   1675:                switch (new_state) {
                   1676:                case BIOC_SVOFFLINE:
                   1677:                case BIOC_SVDEGRADED:
                   1678:                        break;
                   1679:                default:
                   1680:                        goto die;
                   1681:                }
                   1682:                break;
                   1683:
                   1684:        case BIOC_SVOFFLINE:
                   1685:                /* XXX this might be a little too much */
                   1686:                goto die;
                   1687:
                   1688:        case BIOC_SVSCRUB:
                   1689:                switch (new_state) {
                   1690:                case BIOC_SVONLINE:
                   1691:                case BIOC_SVOFFLINE:
                   1692:                case BIOC_SVDEGRADED:
                   1693:                case BIOC_SVSCRUB: /* can go to same state */
                   1694:                        break;
                   1695:                default:
                   1696:                        goto die;
                   1697:                }
                   1698:                break;
                   1699:
                   1700:        case BIOC_SVBUILDING:
                   1701:                switch (new_state) {
                   1702:                case BIOC_SVONLINE:
                   1703:                case BIOC_SVOFFLINE:
                   1704:                case BIOC_SVBUILDING: /* can go to the same state */
                   1705:                        break;
                   1706:                default:
                   1707:                        goto die;
                   1708:                }
                   1709:                break;
                   1710:
                   1711:        case BIOC_SVREBUILD:
                   1712:                switch (new_state) {
                   1713:                case BIOC_SVONLINE:
                   1714:                case BIOC_SVOFFLINE:
                   1715:                case BIOC_SVREBUILD: /* can go to the same state */
                   1716:                        break;
                   1717:                default:
                   1718:                        goto die;
                   1719:                }
                   1720:                break;
                   1721:
                   1722:        case BIOC_SVDEGRADED:
                   1723:                switch (new_state) {
                   1724:                case BIOC_SVOFFLINE:
                   1725:                case BIOC_SVREBUILD:
                   1726:                case BIOC_SVDEGRADED: /* can go to the same state */
                   1727:                        break;
                   1728:                default:
                   1729:                        goto die;
                   1730:                }
                   1731:                break;
                   1732:
                   1733:        default:
                   1734: die:
                   1735:                panic("%s: %s: invalid volume state transition "
                   1736:                    "%d -> %d\n", DEVNAME(sd->sd_sc),
                   1737:                    sd->sd_vol.sv_meta.svm_devname,
                   1738:                    old_state, new_state);
                   1739:                /* NOTREACHED */
                   1740:        }
                   1741:
                   1742:        sd->sd_vol.sv_meta.svm_status = new_state;
                   1743: }
                   1744:
                   1745: u_int32_t
                   1746: sr_checksum(char *s, u_int32_t *p, u_int32_t size)
                   1747: {
                   1748:        u_int32_t               chk = 0;
                   1749:        int                     i;
                   1750:
                   1751:        DNPRINTF(SR_D_MISC, "%s: sr_checksum %p %d\n", s, p, size);
                   1752:
                   1753:        if (size % sizeof(u_int32_t))
                   1754:                return (0); /* 0 is failure */
                   1755:
                   1756:        for (i = 0; i < size / sizeof(u_int32_t); i++)
                   1757:                chk ^= p[i];
                   1758:
                   1759:        return (chk);
                   1760: }
                   1761:
                   1762: void
                   1763: sr_get_uuid(struct sr_uuid *uuid)
                   1764: {
                   1765:        int                     i;
                   1766:
                   1767:        for (i = 0; i < SR_UUID_MAX; i++)
                   1768:                uuid->sui_id[i] = arc4random();
                   1769: }
                   1770:
                   1771: void
                   1772: sr_print_uuid(struct sr_uuid *uuid, int cr)
                   1773: {
                   1774:        int                     i;
                   1775:
                   1776:        for (i = 0; i < SR_UUID_MAX; i++)
                   1777:                printf("%x%s", uuid->sui_id[i],
                   1778:                    i < SR_UUID_MAX - 1 ? ":" : "");
                   1779:
                   1780:        if (cr)
                   1781:                printf("\n");
                   1782: }
                   1783:
                   1784: int
                   1785: sr_clear_metadata(struct sr_discipline *sd)
                   1786: {
                   1787:        struct sr_softc         *sc = sd->sd_sc;
                   1788:        struct sr_chunk_head    *cl = &sd->sd_vol.sv_chunk_list;
                   1789:        struct sr_chunk         *ch_entry;
                   1790:        struct buf              b;
                   1791:        size_t                  sz = SR_META_SIZE * 512;
                   1792:        void                    *m;
                   1793:        int                     rv = 0;
                   1794:
                   1795:        DNPRINTF(SR_D_META, "%s: sr_clear_metadata\n", DEVNAME(sc));
                   1796:
                   1797:        m = malloc(sz , M_DEVBUF, M_WAITOK);
                   1798:        bzero(m, sz);
                   1799:
                   1800:        SLIST_FOREACH(ch_entry, cl, src_link) {
                   1801:                bzero(&b, sizeof(b));
                   1802:
                   1803:                b.b_flags = B_WRITE;
                   1804:                b.b_blkno = SR_META_OFFSET;
                   1805:                b.b_bcount = sz;
                   1806:                b.b_bufsize = sz;
                   1807:                b.b_resid = sz;
                   1808:                b.b_data = (void *)m;
                   1809:                b.b_error = 0;
                   1810:                b.b_proc = curproc;
                   1811:                b.b_dev = ch_entry->src_dev_mm;
                   1812:                b.b_vp = NULL;
                   1813:                b.b_iodone = NULL;
                   1814:                LIST_INIT(&b.b_dep);
                   1815:                bdevsw_lookup(b.b_dev)->d_strategy(&b);
                   1816:                biowait(&b);
                   1817:
                   1818:                if (b.b_flags & B_ERROR) {
                   1819:                        printf("%s: %s i/o error on block %d while clearing "
                   1820:                            "metadata %d\n", DEVNAME(sc),
                   1821:                            ch_entry->src_devname, b.b_blkno, b.b_error);
                   1822:                        rv++;
                   1823:                        continue;
                   1824:                }
                   1825:        }
                   1826:
                   1827:        free(m, M_DEVBUF);
                   1828:        return (rv);
                   1829: }
                   1830:
                   1831: int
                   1832: sr_already_assembled(struct sr_discipline *sd)
                   1833: {
                   1834:        struct sr_softc         *sc = sd->sd_sc;
                   1835:        int                     i;
                   1836:
                   1837:        for (i = 0; i < SR_MAXSCSIBUS; i++)
                   1838:                if (sc->sc_dis[i])
                   1839:                        if (!bcmp(&sd->sd_meta->ssd_uuid,
                   1840:                            &sc->sc_dis[i]->sd_meta->ssd_uuid,
                   1841:                            sizeof(sd->sd_meta->ssd_uuid)))
                   1842:                                return (1);
                   1843:
                   1844:        return (0);
                   1845: }
                   1846:
                   1847: void
                   1848: sr_save_metadata_callback(void *arg1, void *arg2)
                   1849: {
                   1850:        struct sr_discipline    *sd = arg1;
                   1851:        int                     s;
                   1852:
                   1853:        s = splbio();
                   1854:
                   1855:        if (sr_save_metadata(arg1, SR_VOL_DIRTY))
                   1856:                printf("%s: save metadata failed\n",
                   1857:                    DEVNAME(sd->sd_sc));
                   1858:
                   1859:        sd->sd_must_flush = 0;
                   1860:        splx(s);
                   1861: }
                   1862:
                   1863: int
                   1864: sr_save_metadata(struct sr_discipline *sd, u_int32_t flags)
                   1865: {
                   1866:        struct sr_softc         *sc = sd->sd_sc;
                   1867:        struct sr_metadata      *sm = sd->sd_meta;
                   1868:        struct sr_vol_meta      *sv = &sd->sd_vol.sv_meta, *im_sv;
                   1869:        struct sr_chunk_meta    *im_sc;
                   1870:        struct sr_chunk         *src;
                   1871:        struct buf              b;
                   1872:        struct sr_workunit      wu;
                   1873:        int                     i, rv = 1, ch = 0;
                   1874:        size_t                  sz = SR_META_SIZE * 512;
                   1875:
                   1876:        DNPRINTF(SR_D_META, "%s: sr_save_metadata %s\n",
                   1877:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   1878:
                   1879:        if (!sm) {
                   1880:                printf("%s: no in memory copy of metadata\n", DEVNAME(sc));
                   1881:                goto bad;
                   1882:        }
                   1883:
                   1884:        im_sv = (struct sr_vol_meta *)(sm + 1);
                   1885:        im_sc = (struct sr_chunk_meta *)(im_sv + 1);
                   1886:
                   1887:        if (sizeof(struct sr_metadata) + sizeof(struct sr_vol_meta) +
                   1888:            (sizeof(struct sr_chunk_meta) * sd->sd_vol.sv_meta.svm_no_chunk) >
                   1889:            sz) {
                   1890:                printf("%s: too much metadata; metadata NOT written\n",
                   1891:                    DEVNAME(sc));
                   1892:                goto bad;
                   1893:        }
                   1894:
                   1895:        if (sm->ssd_magic == 0) {
                   1896:                /* initial metadata */
                   1897:                sm->ssd_magic = SR_MAGIC;
                   1898:                sm->ssd_version = SR_META_VERSION;
                   1899:                sm->ssd_size = sizeof(struct sr_metadata);
                   1900:                sm->ssd_ondisk = 0;
                   1901:                sm->ssd_flags = sd->sd_meta_flags;
                   1902:                /* get uuid from chunk 0 */
                   1903:                bcopy(&sd->sd_vol.sv_chunks[0]->src_meta.scm_uuid,
                   1904:                    &sm->ssd_uuid,
                   1905:                    sizeof(struct sr_uuid));
                   1906:
                   1907:                /* volume */
                   1908:                bcopy(sv, im_sv, sizeof(struct sr_vol_meta));
                   1909:                bcopy(&sm->ssd_uuid, &im_sv->svm_uuid,
                   1910:                    sizeof(im_sv->svm_uuid));
                   1911:                sm->ssd_vd_ver = SR_VOL_VERSION;
                   1912:                sm->ssd_vd_size = sizeof(struct sr_vol_meta);
                   1913:
                   1914:                /* chunk */
                   1915:                for (i = 0; i < sd->sd_vol.sv_meta.svm_no_chunk; i++)
                   1916:                        bcopy(sd->sd_vol.sv_chunks[i], &im_sc[i],
                   1917:                            sizeof(struct sr_chunk_meta));
                   1918:
                   1919:                sm->ssd_chunk_ver = SR_CHUNK_VERSION;
                   1920:                sm->ssd_chunk_size = sizeof(struct sr_chunk_meta);
                   1921:                sm->ssd_chunk_no = sd->sd_vol.sv_meta.svm_no_chunk;
                   1922:
                   1923:                /* optional */
                   1924:                sm->ssd_opt_ver = SR_OPT_VERSION;
                   1925:                sm->ssd_opt_size = 0; /* unused */
                   1926:                sm->ssd_opt_no = 0; /* unused */
                   1927:        }
                   1928:
                   1929:        /* from here on out metadata is updated */
                   1930:        sm->ssd_ondisk++;
                   1931:        im_sv->svm_flags |= flags;
                   1932:        sm->ssd_vd_chk = sr_checksum(DEVNAME(sc),
                   1933:            (u_int32_t *)im_sv, sm->ssd_vd_size);
                   1934:
                   1935:        sm->ssd_chunk_chk = 0;
                   1936:        for (ch = 0; ch < sm->ssd_chunk_no; ch++)
                   1937:                sm->ssd_chunk_chk ^= sr_checksum(DEVNAME(sc),
                   1938:                    (u_int32_t *)&im_sc[ch], sm->ssd_chunk_size);
                   1939:
                   1940:        sr_print_metadata(sm);
                   1941:
                   1942:        for (i = 0; i < sm->ssd_chunk_no; i++) {
                   1943:                memset(&b, 0, sizeof(b));
                   1944:
                   1945:                src = sd->sd_vol.sv_chunks[i];
                   1946:
                   1947:                /* skip disks that are offline */
                   1948:                if (src->src_meta.scm_status == BIOC_SDOFFLINE)
                   1949:                        continue;
                   1950:
                   1951:                /* calculate metdata checksum and ids */
                   1952:                sm->ssd_vd_volid = im_sv->svm_volid;
                   1953:                sm->ssd_chunk_id = i;
                   1954:                sm->ssd_checksum = sr_checksum(DEVNAME(sc),
                   1955:                    (u_int32_t *)sm, sm->ssd_size);
                   1956:                DNPRINTF(SR_D_META, "%s: sr_save_metadata %s: volid: %d "
                   1957:                    "chunkid: %d checksum: 0x%x\n",
                   1958:                    DEVNAME(sc), src->src_meta.scm_devname,
                   1959:                    sm->ssd_vd_volid, sm->ssd_chunk_id,
                   1960:                    sm->ssd_checksum);
                   1961:
                   1962:                b.b_flags = B_WRITE;
                   1963:                b.b_blkno = SR_META_OFFSET;
                   1964:                b.b_bcount = sz;
                   1965:                b.b_bufsize = sz;
                   1966:                b.b_resid = sz;
                   1967:                b.b_data = (void *)sm;
                   1968:                b.b_error = 0;
                   1969:                b.b_proc = curproc;
                   1970:                b.b_dev = src->src_dev_mm;
                   1971:                b.b_vp = NULL;
                   1972:                b.b_iodone = NULL;
                   1973:                LIST_INIT(&b.b_dep);
                   1974:                bdevsw_lookup(b.b_dev)->d_strategy(&b);
                   1975:                biowait(&b);
                   1976:
                   1977:                /* make sure in memory copy is clean */
                   1978:                sm->ssd_vd_volid = 0;
                   1979:                sm->ssd_chunk_id = 0;
                   1980:                sm->ssd_checksum = 0;
                   1981:
                   1982:                /* XXX do something smart here */
                   1983:                /* mark chunk offline and restart metadata write */
                   1984:                if (b.b_flags & B_ERROR) {
                   1985:                        printf("%s: %s i/o error on block %d while writing "
                   1986:                            "metadata %d\n", DEVNAME(sc),
                   1987:                            src->src_meta.scm_devname, b.b_blkno, b.b_error);
                   1988:                        goto bad;
                   1989:                }
                   1990:
                   1991:                DNPRINTF(SR_D_META, "%s: sr_save_metadata written to %s\n",
                   1992:                    DEVNAME(sc), src->src_meta.scm_devname);
                   1993:        }
                   1994:
                   1995:        bzero(&wu, sizeof(wu));
                   1996:        wu.swu_fake = 1;
                   1997:        wu.swu_dis = sd;
                   1998:        sd->sd_scsi_sync(&wu);
                   1999:
                   2000:        rv = 0;
                   2001: bad:
                   2002:        return (rv);
                   2003: }
                   2004:
                   2005: int
                   2006: sr_boot_assembly(struct sr_softc *sc)
                   2007: {
                   2008:        struct device           *dv;
                   2009:        struct buf              *bp;
                   2010:        struct bdevsw           *bdsw;
                   2011:        struct disklabel        label;
                   2012:        struct sr_metadata      *sm;
                   2013:        struct sr_metadata_list_head mlh;
                   2014:        struct sr_metadata_list *mle, *mle2;
                   2015:        struct sr_vol_meta      *vm;
                   2016:        struct bioc_createraid  bc;
                   2017:        dev_t                   dev, devr, *dt = NULL;
                   2018:        int                     error, majdev, i, no_dev, rv = 0;
                   2019:        size_t                  sz = SR_META_SIZE * 512;
                   2020:
                   2021:        DNPRINTF(SR_D_META, "%s: sr_boot_assembly\n", DEVNAME(sc));
                   2022:
                   2023:        SLIST_INIT(&mlh);
                   2024:        bp = geteblk(sz);
                   2025:        if (!bp)
                   2026:                return (ENOMEM);
                   2027:
                   2028:        TAILQ_FOREACH(dv, &alldevs, dv_list) {
                   2029:                if (dv->dv_class != DV_DISK)
                   2030:                        continue;
                   2031:
                   2032:                majdev = findblkmajor(dv);
                   2033:                if (majdev == -1)
                   2034:                        continue;
                   2035:
                   2036:                bp->b_dev = dev = MAKEDISKDEV(majdev, dv->dv_unit, RAW_PART);
                   2037:                bdsw = &bdevsw[majdev];
                   2038:
                   2039:                /* XXX is there  a better way of excluding some devices? */
                   2040:                if (!strncmp(dv->dv_xname, "fd", 2) ||
                   2041:                    !strncmp(dv->dv_xname, "cd", 2) ||
                   2042:                    !strncmp(dv->dv_xname, "rx", 2))
                   2043:                        continue;
                   2044:                /*
                   2045:                 * The devices are being opened with S_IFCHR instead of
                   2046:                 * S_IFBLK so that the SCSI mid-layer does not whine when
                   2047:                 * media is not inserted in certain devices like zip drives
                   2048:                 * and such.
                   2049:                 */
                   2050:
                   2051:                /* open device */
                   2052:                error = (*bdsw->d_open)(dev, FREAD, S_IFCHR, curproc);
                   2053:                if (error) {
                   2054:                        DNPRINTF(SR_D_META, "%s: sr_boot_assembly open failed"
                   2055:                            "\n", DEVNAME(sc));
                   2056:                        continue;
                   2057:                }
                   2058:
                   2059:                /* get disklabel */
                   2060:                error = (*bdsw->d_ioctl)(dev, DIOCGDINFO, (void *)&label,
                   2061:                    FREAD, curproc);
                   2062:                if (error) {
                   2063:                        DNPRINTF(SR_D_META, "%s: sr_boot_assembly ioctl "
                   2064:                            "failed\n", DEVNAME(sc));
                   2065:                        error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
                   2066:                        continue;
                   2067:                }
                   2068:
                   2069:                /* we are done, close device */
                   2070:                error = (*bdsw->d_close)(dev, FREAD, S_IFCHR, curproc);
                   2071:                if (error) {
                   2072:                        DNPRINTF(SR_D_META, "%s: sr_boot_assembly close "
                   2073:                            "failed\n", DEVNAME(sc));
                   2074:                        continue;
                   2075:                }
                   2076:
                   2077:                /* are we a softraid partition? */
                   2078:                for (i = 0; i < MAXPARTITIONS; i++) {
                   2079:                        if (label.d_partitions[i].p_fstype != FS_RAID)
                   2080:                                continue;
                   2081:
                   2082:                        /* open device */
                   2083:                        bp->b_dev = devr = MAKEDISKDEV(majdev, dv->dv_unit, i);
                   2084:                        error = (*bdsw->d_open)(devr, FREAD, S_IFCHR, curproc);
                   2085:                        if (error) {
                   2086:                                DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
                   2087:                                    "open failed, partition %d\n",
                   2088:                                    DEVNAME(sc), i);
                   2089:                                continue;
                   2090:                        }
                   2091:                        /* read metadat */
                   2092:                        bp->b_flags = B_BUSY | B_READ;
                   2093:                        bp->b_blkno = SR_META_OFFSET;
                   2094:                        bp->b_cylinder = 0;
                   2095:                        bp->b_bcount = sz;
                   2096:                        bp->b_bufsize = sz;
                   2097:                        bp->b_resid = sz;
                   2098:                        (*bdsw->d_strategy)(bp);
                   2099:                        if ((error = biowait(bp))) {
                   2100:                                DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
                   2101:                                    "strategy failed, partition %d\n",
                   2102:                                    DEVNAME(sc));
                   2103:                                error = (*bdsw->d_close)(devr, FREAD, S_IFCHR,
                   2104:                                    curproc);
                   2105:                                continue;
                   2106:                        }
                   2107:
                   2108:                        sm = (struct sr_metadata *)bp->b_data;
                   2109:                        if (!sr_validate_metadata(sc, devr, sm)) {
                   2110:                                /* we got one; save it off */
                   2111:                                mle = malloc(sizeof(*mle), M_DEVBUF, M_WAITOK);
                   2112:                                bzero(mle, sizeof(*mle));
                   2113:                                mle->sml_metadata = malloc(sz, M_DEVBUF,
                   2114:                                    M_WAITOK);
                   2115:                                bzero(mle->sml_metadata, sz);
                   2116:                                bcopy(sm, mle->sml_metadata, sz);
                   2117:                                mle->sml_mm = devr;
                   2118:                                SLIST_INSERT_HEAD(&mlh, mle, sml_link);
                   2119:                        }
                   2120:
                   2121:                        /* we are done, close device */
                   2122:                        error = (*bdsw->d_close)(devr, FREAD, S_IFCHR,
                   2123:                            curproc);
                   2124:                        if (error) {
                   2125:                                DNPRINTF(SR_D_META, "%s: sr_boot_assembly "
                   2126:                                    "close failed\n", DEVNAME(sc));
                   2127:                                continue;
                   2128:                        }
                   2129:                }
                   2130:        }
                   2131:
                   2132:        /*
                   2133:         * XXX poor mans hack that doesn't keep disks in order and does not
                   2134:         * roam disks correctly.  replace this with something smarter that
                   2135:         * orders disks by volid, chunkid and uuid.
                   2136:         */
                   2137:        dt = malloc(BIOC_CRMAXLEN, M_DEVBUF, M_WAITOK);
                   2138:        SLIST_FOREACH(mle, &mlh, sml_link) {
                   2139:                /* chunk used already? */
                   2140:                if (mle->sml_used)
                   2141:                        continue;
                   2142:
                   2143:                no_dev = 0;
                   2144:                bzero(dt, BIOC_CRMAXLEN);
                   2145:                SLIST_FOREACH(mle2, &mlh, sml_link) {
                   2146:                        /* chunk used already? */
                   2147:                        if (mle2->sml_used)
                   2148:                                continue;
                   2149:
                   2150:                        /* are we the same volume? */
                   2151:                        if (mle->sml_metadata->ssd_vd_volid !=
                   2152:                            mle2->sml_metadata->ssd_vd_volid)
                   2153:                                continue;
                   2154:
                   2155:                        /* same uuid? */
                   2156:                        if (bcmp(&mle->sml_metadata->ssd_uuid,
                   2157:                            &mle2->sml_metadata->ssd_uuid,
                   2158:                            sizeof(mle->sml_metadata->ssd_uuid)))
                   2159:                                continue;
                   2160:
                   2161:                        /* sanity */
                   2162:                        if (dt[mle2->sml_metadata->ssd_chunk_id]) {
                   2163:                                printf("%s: chunk id already in use; can not "
                   2164:                                    "assemble volume\n", DEVNAME(sc));
                   2165:                                goto unwind;
                   2166:                        }
                   2167:                        dt[mle2->sml_metadata->ssd_chunk_id] = mle2->sml_mm;
                   2168:                        no_dev++;
                   2169:                        mle2->sml_used = 1;
                   2170:                }
                   2171:                if (mle->sml_metadata->ssd_chunk_no != no_dev) {
                   2172:                        printf("%s: not assembling partial disk that used to "
                   2173:                            "be volume %d\n", DEVNAME(sc),
                   2174:                            mle->sml_metadata->ssd_vd_volid);
                   2175:                        continue;
                   2176:                }
                   2177:
                   2178:                bzero(&bc, sizeof(bc));
                   2179:                vm = (struct sr_vol_meta *)(mle->sml_metadata + 1);
                   2180:                bc.bc_level = vm->svm_level;
                   2181:                bc.bc_dev_list_len = no_dev * sizeof(dev_t);
                   2182:                bc.bc_dev_list = dt;
                   2183:                bc.bc_flags = BIOC_SCDEVT;
                   2184:                sr_ioctl_createraid(sc, &bc, 0);
                   2185:                rv++;
                   2186:        }
                   2187:
                   2188: unwind:
                   2189:        if (dt)
                   2190:                free(dt, M_DEVBUF);
                   2191:
                   2192:        for (mle = SLIST_FIRST(&mlh); mle != SLIST_END(&mlh); mle = mle2) {
                   2193:                mle2 = SLIST_NEXT(mle, sml_link);
                   2194:
                   2195:                free(mle->sml_metadata, M_DEVBUF);
                   2196:                free(mle, M_DEVBUF);
                   2197:        }
                   2198:        SLIST_INIT(&mlh);
                   2199:
                   2200:        return (rv);
                   2201: }
                   2202:
                   2203: int
                   2204: sr_validate_metadata(struct sr_softc *sc, dev_t dev, struct sr_metadata *sm)
                   2205: {
                   2206:        struct sr_vol_meta      *mv;
                   2207:        struct sr_chunk_meta    *mc;
                   2208:        char                    *name, devname[32];
                   2209:        int                     maj, part, unit;
                   2210:        u_int32_t               chk;
                   2211:
                   2212:        DNPRINTF(SR_D_META, "%s: sr_validate_metadata(0x%x)\n",
                   2213:            DEVNAME(sc), dev);
                   2214:
                   2215:        bzero(devname, sizeof(devname));
                   2216:
                   2217:        if (sm->ssd_magic != SR_MAGIC)
                   2218:                goto bad;
                   2219:
                   2220:        maj = major(dev);
                   2221:        part = DISKPART(dev);
                   2222:        unit = DISKUNIT(dev);
                   2223:
                   2224:        name = findblkname(maj);
                   2225:        if (name == NULL)
                   2226:                goto bad;
                   2227:
                   2228:        snprintf(devname, sizeof(devname),
                   2229:            "%s%d%c", name, unit, part + 'a');
                   2230:        name = devname;
                   2231:
                   2232:        /* validate metadata */
                   2233:        if (sm->ssd_version != SR_META_VERSION) {
                   2234:                printf("%s: %s can not read metadata version %d, "
                   2235:                    "expected %d\n", DEVNAME(sc),
                   2236:                    devname, sm->ssd_version,
                   2237:                    SR_META_VERSION);
                   2238:                goto bad;
                   2239:        }
                   2240:        if (sm->ssd_size != sizeof(struct sr_metadata)) {
                   2241:                printf("%s: %s invalid metadata size %d, "
                   2242:                    "expected %d\n", DEVNAME(sc),
                   2243:                    devname, sm->ssd_size,
                   2244:                    sizeof(struct sr_metadata));
                   2245:                goto bad;
                   2246:        }
                   2247:        chk = sr_checksum(DEVNAME(sc), (u_int32_t *)sm, sm->ssd_size);
                   2248:        /*
                   2249:         * since the checksum value is part of the checksum a good
                   2250:         * result equals 0
                   2251:         */
                   2252:        if (chk != 0) {
                   2253:                printf("%s: %s invalid metadata checksum 0x%x, "
                   2254:                    "expected 0x%x\n", DEVNAME(sc),
                   2255:                    devname, sm->ssd_checksum, chk);
                   2256:                goto bad;
                   2257:        }
                   2258:
                   2259:        /* validate volume metadata */
                   2260:        if (sm->ssd_vd_ver != SR_VOL_VERSION) {
                   2261:                printf("%s: %s can not read volume metadata version "
                   2262:                    "%d, expected %d\n", DEVNAME(sc),
                   2263:                    devname, sm->ssd_vd_ver,
                   2264:                    SR_VOL_VERSION);
                   2265:                goto bad;
                   2266:        }
                   2267:        if (sm->ssd_vd_size != sizeof(struct sr_vol_meta)) {
                   2268:                printf("%s: %s invalid volume metadata size %d, "
                   2269:                    "expected %d\n", DEVNAME(sc),
                   2270:                    devname, sm->ssd_vd_size,
                   2271:                    sizeof(struct sr_vol_meta));
                   2272:                goto bad;
                   2273:        }
                   2274:        mv = (struct sr_vol_meta *)(sm + 1);
                   2275:        chk = sr_checksum(DEVNAME(sc), (u_int32_t *)mv, sm->ssd_vd_size);
                   2276:        if (chk != sm->ssd_vd_chk) {
                   2277:                printf("%s: %s invalid volume metadata checksum 0x%x, "
                   2278:                    "expected 0x%x\n", DEVNAME(sc),
                   2279:                    devname, sm->ssd_vd_chk, chk);
                   2280:                goto bad;
                   2281:        }
                   2282:
                   2283:        /* validate chunk metadata */
                   2284:        if (sm->ssd_chunk_ver != SR_CHUNK_VERSION) {
                   2285:                printf("%s: %s can not read chunk metadata version "
                   2286:                    "%d, expected %d\n", DEVNAME(sc),
                   2287:                    devname, sm->ssd_chunk_ver,
                   2288:                    SR_CHUNK_VERSION);
                   2289:                goto bad;
                   2290:        }
                   2291:        if (sm->ssd_chunk_size != sizeof(struct sr_chunk_meta)) {
                   2292:                printf("%s: %s invalid chunk metadata size %d, "
                   2293:                    "expected %d\n", DEVNAME(sc),
                   2294:                    devname, sm->ssd_chunk_size,
                   2295:                    sizeof(struct sr_chunk_meta));
                   2296:                goto bad;
                   2297:        }
                   2298:
                   2299:        mc = (struct sr_chunk_meta *)(mv + 1);
                   2300:        /* checksum is calculated over ALL chunks */
                   2301:        chk = sr_checksum(DEVNAME(sc), (u_int32_t *)(mc),
                   2302:            sm->ssd_chunk_size * sm->ssd_chunk_no);
                   2303:
                   2304:        if (chk != sm->ssd_chunk_chk) {
                   2305:                printf("%s: %s invalid chunk metadata checksum 0x%x, "
                   2306:                    "expected 0x%x\n", DEVNAME(sc),
                   2307:                    devname, sm->ssd_chunk_chk, chk);
                   2308:                goto bad;
                   2309:        }
                   2310:
                   2311:        /* warn if disk changed order */
                   2312:        if (strncmp(mc[sm->ssd_chunk_id].scm_devname, name,
                   2313:            sizeof(mc[sm->ssd_chunk_id].scm_devname)))
                   2314:                printf("%s: roaming device %s -> %s\n", DEVNAME(sc),
                   2315:                    mc[sm->ssd_chunk_id].scm_devname, name);
                   2316:
                   2317:        /* we have meta data on disk */
                   2318:        DNPRINTF(SR_D_META, "%s: sr_validate_metadata valid metadata %s\n",
                   2319:            DEVNAME(sc), devname);
                   2320:
                   2321:        return (0);
                   2322: bad:
                   2323:        DNPRINTF(SR_D_META, "%s: sr_validate_metadata invalid metadata %s\n",
                   2324:            DEVNAME(sc), devname);
                   2325:
                   2326:        return (1);
                   2327: }
                   2328:
                   2329: void
                   2330: sr_shutdown(void *arg)
                   2331: {
                   2332:        struct sr_discipline    *sd = arg;
                   2333: #ifdef SR_DEBUG
                   2334:        struct sr_softc         *sc = sd->sd_sc;
                   2335: #endif
                   2336:        DNPRINTF(SR_D_DIS, "%s: sr_shutdown %s\n",
                   2337:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   2338:
                   2339:        sr_save_metadata(sd, 0);
                   2340:
                   2341:        sr_shutdown_discipline(sd);
                   2342: }
                   2343:
                   2344: #ifndef SMALL_KERNEL
                   2345: int
                   2346: sr_create_sensors(struct sr_discipline *sd)
                   2347: {
                   2348:        struct sr_softc         *sc = sd->sd_sc;
                   2349:        int                     rv = 1;
                   2350:
                   2351:        DNPRINTF(SR_D_STATE, "%s: %s: sr_create_sensors\n",
                   2352:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   2353:
                   2354:        strlcpy(sd->sd_vol.sv_sensordev.xname, DEVNAME(sc),
                   2355:            sizeof(sd->sd_vol.sv_sensordev.xname));
                   2356:
                   2357:        sd->sd_vol.sv_sensor.type = SENSOR_DRIVE;
                   2358:        sd->sd_vol.sv_sensor.status = SENSOR_S_UNKNOWN;
                   2359:        strlcpy(sd->sd_vol.sv_sensor.desc, sd->sd_vol.sv_meta.svm_devname,
                   2360:            sizeof(sd->sd_vol.sv_sensor.desc));
                   2361:
                   2362:        sensor_attach(&sd->sd_vol.sv_sensordev, &sd->sd_vol.sv_sensor);
                   2363:
                   2364:        if (sc->sc_sensors_running == 0) {
                   2365:                if (sensor_task_register(sc, sr_refresh_sensors, 10) == NULL)
                   2366:                        goto bad;
                   2367:                sc->sc_sensors_running = 1;
                   2368:        }
                   2369:        sensordev_install(&sd->sd_vol.sv_sensordev);
                   2370:
                   2371:        rv = 0;
                   2372: bad:
                   2373:        return (rv);
                   2374: }
                   2375:
                   2376: void
                   2377: sr_delete_sensors(struct sr_discipline *sd)
                   2378: {
                   2379: #ifdef SR_DEBUG
                   2380:        struct sr_softc         *sc = sd->sd_sc;
                   2381: #endif
                   2382:        DNPRINTF(SR_D_STATE, "%s: %s: sr_delete_sensors\n",
                   2383:            DEVNAME(sc), sd->sd_vol.sv_meta.svm_devname);
                   2384:
                   2385:        if (sd->sd_vol.sv_sensor_valid)
                   2386:                sensordev_deinstall(&sd->sd_vol.sv_sensordev);
                   2387: }
                   2388:
                   2389: void
                   2390: sr_refresh_sensors(void *arg)
                   2391: {
                   2392:        struct sr_softc         *sc = arg;
                   2393:        int                     i, vol;
                   2394:        struct sr_volume        *sv;
                   2395:
                   2396:        DNPRINTF(SR_D_STATE, "%s: sr_refresh_sensors\n", DEVNAME(sc));
                   2397:
                   2398:        for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
                   2399:                /* XXX this will not work when we stagger disciplines */
                   2400:                if (!sc->sc_dis[i])
                   2401:                        continue;
                   2402:
                   2403:                sv = &sc->sc_dis[i]->sd_vol;
                   2404:
                   2405:                switch(sv->sv_meta.svm_status) {
                   2406:                case BIOC_SVOFFLINE:
                   2407:                        sv->sv_sensor.value = SENSOR_DRIVE_FAIL;
                   2408:                        sv->sv_sensor.status = SENSOR_S_CRIT;
                   2409:                        break;
                   2410:
                   2411:                case BIOC_SVDEGRADED:
                   2412:                        sv->sv_sensor.value = SENSOR_DRIVE_PFAIL;
                   2413:                        sv->sv_sensor.status = SENSOR_S_WARN;
                   2414:                        break;
                   2415:
                   2416:                case BIOC_SVSCRUB:
                   2417:                case BIOC_SVONLINE:
                   2418:                        sv->sv_sensor.value = SENSOR_DRIVE_ONLINE;
                   2419:                        sv->sv_sensor.status = SENSOR_S_OK;
                   2420:                        break;
                   2421:
                   2422:                default:
                   2423:                        sv->sv_sensor.value = 0; /* unknown */
                   2424:                        sv->sv_sensor.status = SENSOR_S_UNKNOWN;
                   2425:                }
                   2426:        }
                   2427: }
                   2428: #endif /* SMALL_KERNEL */
                   2429:
                   2430: #ifdef SR_FANCY_STATS
                   2431: void                           sr_print_stats(void);
                   2432:
                   2433: void
                   2434: sr_print_stats(void)
                   2435: {
                   2436:        struct sr_softc         *sc;
                   2437:        struct sr_discipline    *sd;
                   2438:        int                     i, vol;
                   2439:
                   2440:        for (i = 0; i < softraid_cd.cd_ndevs; i++)
                   2441:                if (softraid_cd.cd_devs[i]) {
                   2442:                        sc = softraid_cd.cd_devs[i];
                   2443:                        /* we'll only have one softc */
                   2444:                        break;
                   2445:                }
                   2446:
                   2447:        if (!sc) {
                   2448:                printf("no softraid softc found\n");
                   2449:                return;
                   2450:        }
                   2451:
                   2452:        for (i = 0, vol = -1; i < SR_MAXSCSIBUS; i++) {
                   2453:                /* XXX this will not work when we stagger disciplines */
                   2454:                if (!sc->sc_dis[i])
                   2455:                        continue;
                   2456:
                   2457:                sd = sc->sc_dis[i];
                   2458:                printf("%s: ios pending: %d  collisions %llu\n",
                   2459:                    sd->sd_vol.sv_meta.svm_devname,
                   2460:                    sd->sd_wu_pending,
                   2461:                    sd->sd_wu_collisions);
                   2462:        }
                   2463: }
                   2464: #endif /* SR_FANCY_STATS */
                   2465:
                   2466: #ifdef SR_DEBUG
                   2467: void
                   2468: sr_print_metadata(struct sr_metadata *sm)
                   2469: {
                   2470:        struct sr_vol_meta      *im_sv;
                   2471:        struct sr_chunk_meta    *im_sc;
                   2472:        int                     ch;
                   2473:
                   2474:        im_sv = (struct sr_vol_meta *)(sm + 1);
                   2475:        im_sc = (struct sr_chunk_meta *)(im_sv + 1);
                   2476:
                   2477:        DNPRINTF(SR_D_META, "\tmeta magic 0x%llx\n", sm->ssd_magic);
                   2478:        DNPRINTF(SR_D_META, "\tmeta version %d\n", sm->ssd_version);
                   2479:        DNPRINTF(SR_D_META, "\tmeta checksum 0x%x\n", sm->ssd_checksum);
                   2480:        DNPRINTF(SR_D_META, "\tmeta size %d\n", sm->ssd_size);
                   2481:        DNPRINTF(SR_D_META, "\tmeta on disk version %u\n", sm->ssd_ondisk);
                   2482:        DNPRINTF(SR_D_META, "\tmeta uuid ");
                   2483:        sr_print_uuid(&sm->ssd_uuid, 1);
                   2484:        DNPRINTF(SR_D_META, "\tvd version %d\n", sm->ssd_vd_ver);
                   2485:        DNPRINTF(SR_D_META, "\tvd size %lu\n", sm->ssd_vd_size);
                   2486:        DNPRINTF(SR_D_META, "\tvd id %u\n", sm->ssd_vd_volid);
                   2487:        DNPRINTF(SR_D_META, "\tvd checksum 0x%x\n", sm->ssd_vd_chk);
                   2488:        DNPRINTF(SR_D_META, "\tchunk version %d\n", sm->ssd_chunk_ver);
                   2489:        DNPRINTF(SR_D_META, "\tchunks %d\n", sm->ssd_chunk_no);
                   2490:        DNPRINTF(SR_D_META, "\tchunk size %u\n", sm->ssd_chunk_size);
                   2491:        DNPRINTF(SR_D_META, "\tchunk id %u\n", sm->ssd_chunk_id);
                   2492:        DNPRINTF(SR_D_META, "\tchunk checksum 0x%x\n", sm->ssd_chunk_chk);
                   2493:
                   2494:        DNPRINTF(SR_D_META, "\t\tvol id %d\n", im_sv->svm_volid);
                   2495:        DNPRINTF(SR_D_META, "\t\tvol status %d\n", im_sv->svm_status);
                   2496:        DNPRINTF(SR_D_META, "\t\tvol flags 0x%x\n", im_sv->svm_flags);
                   2497:        DNPRINTF(SR_D_META, "\t\tvol level %d\n", im_sv->svm_level);
                   2498:        DNPRINTF(SR_D_META, "\t\tvol size %lld\n", im_sv->svm_size);
                   2499:        DNPRINTF(SR_D_META, "\t\tvol name %s\n", im_sv->svm_devname);
                   2500:        DNPRINTF(SR_D_META, "\t\tvol vendor %s\n", im_sv->svm_vendor);
                   2501:        DNPRINTF(SR_D_META, "\t\tvol prod %s\n", im_sv->svm_product);
                   2502:        DNPRINTF(SR_D_META, "\t\tvol rev %s\n", im_sv->svm_revision);
                   2503:        DNPRINTF(SR_D_META, "\t\tvol no chunks %d\n", im_sv->svm_no_chunk);
                   2504:        DNPRINTF(SR_D_META, "\t\tvol uuid ");
                   2505:        sr_print_uuid(& im_sv->svm_uuid, 1);
                   2506:
                   2507:        for (ch = 0; ch < im_sv->svm_no_chunk; ch++) {
                   2508:                DNPRINTF(SR_D_META, "\t\t\tchunk vol id %d\n",
                   2509:                    im_sc[ch].scm_volid);
                   2510:                DNPRINTF(SR_D_META, "\t\t\tchunk id %d\n",
                   2511:                    im_sc[ch].scm_chunk_id);
                   2512:                DNPRINTF(SR_D_META, "\t\t\tchunk status %d\n",
                   2513:                    im_sc[ch].scm_status);
                   2514:                DNPRINTF(SR_D_META, "\t\t\tchunk name %s\n",
                   2515:                    im_sc[ch].scm_devname);
                   2516:                DNPRINTF(SR_D_META, "\t\t\tchunk size %lld\n",
                   2517:                    im_sc[ch].scm_size);
                   2518:                DNPRINTF(SR_D_META, "\t\t\tchunk coerced size %lld\n",
                   2519:                    im_sc[ch].scm_coerced_size);
                   2520:                DNPRINTF(SR_D_META, "\t\t\tchunk uuid ");
                   2521:                sr_print_uuid(&im_sc[ch].scm_uuid, 1);
                   2522:        }
                   2523: }
                   2524: #endif /* SR_DEBUG */
                   2525:
                   2526: /* RAID 1 functions */
                   2527: int
                   2528: sr_raid1_alloc_resources(struct sr_discipline *sd)
                   2529: {
                   2530:        int                     rv = EINVAL;
                   2531:
                   2532:        if (!sd)
                   2533:                return (rv);
                   2534:
                   2535:        DNPRINTF(SR_D_DIS, "%s: sr_raid1_alloc_resources\n",
                   2536:            DEVNAME(sd->sd_sc));
                   2537:
                   2538:        if (sr_alloc_wu(sd))
                   2539:                goto bad;
                   2540:        if (sr_alloc_ccb(sd))
                   2541:                goto bad;
                   2542:
                   2543:        rv = 0;
                   2544: bad:
                   2545:        return (rv);
                   2546: }
                   2547:
                   2548: int
                   2549: sr_raid1_free_resources(struct sr_discipline *sd)
                   2550: {
                   2551:        int                     rv = EINVAL;
                   2552:
                   2553:        if (!sd)
                   2554:                return (rv);
                   2555:
                   2556:        DNPRINTF(SR_D_DIS, "%s: sr_raid1_free_resources\n",
                   2557:            DEVNAME(sd->sd_sc));
                   2558:
                   2559:        sr_free_wu(sd);
                   2560:        sr_free_ccb(sd);
                   2561:
                   2562:        if (sd->sd_meta)
                   2563:                free(sd->sd_meta, M_DEVBUF);
                   2564:
                   2565:        rv = 0;
                   2566:        return (rv);
                   2567: }
                   2568:
                   2569: int
                   2570: sr_raid1_rw(struct sr_workunit *wu)
                   2571: {
                   2572:        struct sr_discipline    *sd = wu->swu_dis;
                   2573:        struct scsi_xfer        *xs = wu->swu_xs;
                   2574:        struct sr_workunit      *wup;
                   2575:        struct sr_ccb           *ccb;
                   2576:        struct sr_chunk         *scp;
                   2577:        int                     ios, x, i, s, rt;
                   2578:        daddr64_t               blk;
                   2579:
                   2580:        DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw 0x%02x\n", DEVNAME(sd->sd_sc),
                   2581:            xs->cmd->opcode);
                   2582:
                   2583:        if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
                   2584:                DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw device offline\n",
                   2585:                    DEVNAME(sd->sd_sc));
                   2586:                goto bad;
                   2587:        }
                   2588:
                   2589:        if (xs->datalen == 0) {
                   2590:                printf("%s: %s: illegal block count\n",
                   2591:                    DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
                   2592:                goto bad;
                   2593:        }
                   2594:
                   2595:        if (xs->cmdlen == 10)
                   2596:                blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
                   2597:        else if (xs->cmdlen == 6)
                   2598:                blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
                   2599:        else {
                   2600:                printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc),
                   2601:                    sd->sd_vol.sv_meta.svm_devname);
                   2602:                goto bad;
                   2603:        }
                   2604:
                   2605:        wu->swu_blk_start = blk;
                   2606:        wu->swu_blk_end = blk + (xs->datalen >> 9) - 1;
                   2607:
                   2608:        if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) {
                   2609:                DNPRINTF(SR_D_DIS, "%s: sr_raid1_rw out of bounds start: %lld "
                   2610:                    "end: %lld length: %d\n", wu->swu_blk_start,
                   2611:                    wu->swu_blk_end, xs->datalen);
                   2612:
                   2613:                sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT |
                   2614:                    SSD_ERRCODE_VALID;
                   2615:                sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
                   2616:                sd->sd_scsi_sense.add_sense_code = 0x21;
                   2617:                sd->sd_scsi_sense.add_sense_code_qual = 0x00;
                   2618:                sd->sd_scsi_sense.extra_len = 4;
                   2619:                goto bad;
                   2620:        }
                   2621:
                   2622:        /* calculate physical block */
                   2623:        blk += SR_META_SIZE + SR_META_OFFSET;
                   2624:
                   2625:        if (xs->flags & SCSI_DATA_IN)
                   2626:                ios = 1;
                   2627:        else
                   2628:                ios = sd->sd_vol.sv_meta.svm_no_chunk;
                   2629:        wu->swu_io_count = ios;
                   2630:
                   2631:        for (i = 0; i < ios; i++) {
                   2632:                ccb = sr_get_ccb(sd);
                   2633:                if (!ccb) {
                   2634:                        /* should never happen but handle more gracefully */
                   2635:                        printf("%s: %s: too many ccbs queued\n",
                   2636:                            DEVNAME(sd->sd_sc),
                   2637:                            sd->sd_vol.sv_meta.svm_devname);
                   2638:                        goto bad;
                   2639:                }
                   2640:
                   2641:                if (xs->flags & SCSI_POLL) {
                   2642:                        ccb->ccb_buf.b_flags = 0;
                   2643:                        ccb->ccb_buf.b_iodone = NULL;
                   2644:                } else {
                   2645:                        ccb->ccb_buf.b_flags = B_CALL;
                   2646:                        ccb->ccb_buf.b_iodone = sr_raid1_intr;
                   2647:                }
                   2648:
                   2649:                ccb->ccb_buf.b_blkno = blk;
                   2650:                ccb->ccb_buf.b_bcount = xs->datalen;
                   2651:                ccb->ccb_buf.b_bufsize = xs->datalen;
                   2652:                ccb->ccb_buf.b_resid = xs->datalen;
                   2653:                ccb->ccb_buf.b_data = xs->data;
                   2654:                ccb->ccb_buf.b_error = 0;
                   2655:                ccb->ccb_buf.b_proc = curproc;
                   2656:                ccb->ccb_wu = wu;
                   2657:
                   2658:                if (xs->flags & SCSI_DATA_IN) {
                   2659:                        rt = 0;
                   2660: ragain:
                   2661:                        /* interleave reads */
                   2662:                        x = sd->mds.mdd_raid1.sr1_counter++ %
                   2663:                            sd->sd_vol.sv_meta.svm_no_chunk;
                   2664:                        scp = sd->sd_vol.sv_chunks[x];
                   2665:                        switch (scp->src_meta.scm_status) {
                   2666:                        case BIOC_SDONLINE:
                   2667:                        case BIOC_SDSCRUB:
                   2668:                                ccb->ccb_buf.b_flags |= B_READ;
                   2669:                                break;
                   2670:
                   2671:                        case BIOC_SDOFFLINE:
                   2672:                        case BIOC_SDREBUILD:
                   2673:                        case BIOC_SDHOTSPARE:
                   2674:                                if (rt++ < sd->sd_vol.sv_meta.svm_no_chunk)
                   2675:                                        goto ragain;
                   2676:
                   2677:                                /* FALLTHROUGH */
                   2678:                        default:
                   2679:                                /* volume offline */
                   2680:                                printf("%s: is offline, can't read\n",
                   2681:                                    DEVNAME(sd->sd_sc));
                   2682:                                sr_put_ccb(ccb);
                   2683:                                goto bad;
                   2684:                        }
                   2685:                } else {
                   2686:                        /* writes go on all working disks */
                   2687:                        x = i;
                   2688:                        scp = sd->sd_vol.sv_chunks[x];
                   2689:                        switch (scp->src_meta.scm_status) {
                   2690:                        case BIOC_SDONLINE:
                   2691:                        case BIOC_SDSCRUB:
                   2692:                        case BIOC_SDREBUILD:
                   2693:                                ccb->ccb_buf.b_flags |= B_WRITE;
                   2694:                                break;
                   2695:
                   2696:                        case BIOC_SDHOTSPARE: /* should never happen */
                   2697:                        case BIOC_SDOFFLINE:
                   2698:                                wu->swu_io_count--;
                   2699:                                sr_put_ccb(ccb);
                   2700:                                continue;
                   2701:
                   2702:                        default:
                   2703:                                goto bad;
                   2704:                        }
                   2705:
                   2706:                }
                   2707:                ccb->ccb_target = x;
                   2708:                ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[x]->src_dev_mm;
                   2709:                ccb->ccb_buf.b_vp = NULL;
                   2710:
                   2711:                LIST_INIT(&ccb->ccb_buf.b_dep);
                   2712:
                   2713:                TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link);
                   2714:
                   2715:                DNPRINTF(SR_D_DIS, "%s: %s: sr_raid1: b_bcount: %d "
                   2716:                    "b_blkno: %x b_flags 0x%0x b_data %p\n",
                   2717:                    DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
                   2718:                    ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno,
                   2719:                    ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data);
                   2720:        }
                   2721:
                   2722:        s = splbio();
                   2723:
                   2724:        /* current io failed, restart */
                   2725:        if (wu->swu_state == SR_WU_RESTART)
                   2726:                goto start;
                   2727:
                   2728:        /* deferred io failed, don't restart */
                   2729:        if (wu->swu_state == SR_WU_REQUEUE)
                   2730:                goto queued;
                   2731:
                   2732:        /* walk queue backwards and fill in collider if we have one */
                   2733:        TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) {
                   2734:                if (wu->swu_blk_end < wup->swu_blk_start ||
                   2735:                    wup->swu_blk_end < wu->swu_blk_start)
                   2736:                        continue;
                   2737:
                   2738:                /* we have an LBA collision, defer wu */
                   2739:                wu->swu_state = SR_WU_DEFERRED;
                   2740:                if (wup->swu_collider)
                   2741:                        /* wu is on deferred queue, append to last wu */
                   2742:                        while (wup->swu_collider)
                   2743:                                wup = wup->swu_collider;
                   2744:
                   2745:                wup->swu_collider = wu;
                   2746:                TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link);
                   2747:                sd->sd_wu_collisions++;
                   2748:                goto queued;
                   2749:        }
                   2750:
                   2751:        /* XXX deal with polling */
                   2752: start:
                   2753:        sr_raid_startwu(wu);
                   2754: queued:
                   2755:        splx(s);
                   2756:        return (0);
                   2757: bad:
                   2758:        /* wu is unwound by sr_put_wu */
                   2759:        return (1);
                   2760: }
                   2761:
                   2762: void
                   2763: sr_raid1_intr(struct buf *bp)
                   2764: {
                   2765:        struct sr_ccb           *ccb = (struct sr_ccb *)bp;
                   2766:        struct sr_workunit      *wu = ccb->ccb_wu, *wup;
                   2767:        struct sr_discipline    *sd = wu->swu_dis;
                   2768:        struct scsi_xfer        *xs = wu->swu_xs;
                   2769:        struct sr_softc         *sc = sd->sd_sc;
                   2770:        int                     s, pend;
                   2771:
                   2772:        DNPRINTF(SR_D_INTR, "%s: sr_intr bp %x xs %x\n",
                   2773:            DEVNAME(sc), bp, xs);
                   2774:
                   2775:        DNPRINTF(SR_D_INTR, "%s: sr_intr: b_bcount: %d b_resid: %d"
                   2776:            " b_flags: 0x%0x block: %lld target: %d\n", DEVNAME(sc),
                   2777:            ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags,
                   2778:            ccb->ccb_buf.b_blkno, ccb->ccb_target);
                   2779:
                   2780:        s = splbio();
                   2781:
                   2782:        if (ccb->ccb_buf.b_flags & B_ERROR) {
                   2783:                DNPRINTF(SR_D_INTR, "%s: i/o error on block %lld target: %d\n",
                   2784:                    DEVNAME(sc), ccb->ccb_buf.b_blkno, ccb->ccb_target);
                   2785:                wu->swu_ios_failed++;
                   2786:                ccb->ccb_state = SR_CCB_FAILED;
                   2787:                if (ccb->ccb_target != -1)
                   2788:                        sd->sd_set_chunk_state(sd, ccb->ccb_target,
                   2789:                            BIOC_SDOFFLINE);
                   2790:                else
                   2791:                        panic("%s: invalid target on wu: %p", DEVNAME(sc), wu);
                   2792:        } else {
                   2793:                ccb->ccb_state = SR_CCB_OK;
                   2794:                wu->swu_ios_succeeded++;
                   2795:        }
                   2796:        wu->swu_ios_complete++;
                   2797:
                   2798:        DNPRINTF(SR_D_INTR, "%s: sr_intr: comp: %d count: %d failed: %d\n",
                   2799:            DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
                   2800:            wu->swu_ios_failed);
                   2801:
                   2802:        if (wu->swu_ios_complete >= wu->swu_io_count) {
                   2803:                /* if all ios failed, retry reads and give up on writes */
                   2804:                if (wu->swu_ios_failed == wu->swu_ios_complete) {
                   2805:                        if (xs->flags & SCSI_DATA_IN) {
                   2806:                                printf("%s: retrying read on block %lld\n",
                   2807:                                    DEVNAME(sc), ccb->ccb_buf.b_blkno);
                   2808:                                sr_put_ccb(ccb);
                   2809:                                TAILQ_INIT(&wu->swu_ccb);
                   2810:                                wu->swu_state = SR_WU_RESTART;
                   2811:                                if (sd->sd_scsi_rw(wu))
                   2812:                                        goto bad;
                   2813:                                else
                   2814:                                        goto retry;
                   2815:                        } else {
                   2816:                                printf("%s: permanently fail write on block "
                   2817:                                    "%lld\n", DEVNAME(sc),
                   2818:                                    ccb->ccb_buf.b_blkno);
                   2819:                                xs->error = XS_DRIVER_STUFFUP;
                   2820:                                goto bad;
                   2821:                        }
                   2822:                }
                   2823:
                   2824:                xs->error = XS_NOERROR;
                   2825:                xs->resid = 0;
                   2826:                xs->flags |= ITSDONE;
                   2827:
                   2828:                pend = 0;
                   2829:                TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
                   2830:                        if (wu == wup) {
                   2831:                                /* wu on pendq, remove */
                   2832:                                TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
                   2833:                                pend = 1;
                   2834:
                   2835:                                if (wu->swu_collider) {
                   2836:                                        if (wu->swu_ios_failed)
                   2837:                                                /* toss all ccbs and recreate */
                   2838:                                                sr_raid1_recreate_wu(wu->swu_collider);
                   2839:
                   2840:                                        /* restart deferred wu */
                   2841:                                        wu->swu_collider->swu_state =
                   2842:                                            SR_WU_INPROGRESS;
                   2843:                                        TAILQ_REMOVE(&sd->sd_wu_defq,
                   2844:                                            wu->swu_collider, swu_link);
                   2845:                                        sr_raid_startwu(wu->swu_collider);
                   2846:                                }
                   2847:                                break;
                   2848:                        }
                   2849:                }
                   2850:
                   2851:                if (!pend)
                   2852:                        printf("%s: wu: %p not on pending queue\n",
                   2853:                            DEVNAME(sc), wu);
                   2854:
                   2855:                /* do not change the order of these 2 functions */
                   2856:                sr_put_wu(wu);
                   2857:                scsi_done(xs);
                   2858:
                   2859:                if (sd->sd_sync && sd->sd_wu_pending == 0)
                   2860:                        wakeup(sd);
                   2861:        }
                   2862:
                   2863: retry:
                   2864:        splx(s);
                   2865:        return;
                   2866: bad:
                   2867:        xs->error = XS_DRIVER_STUFFUP;
                   2868:        xs->flags |= ITSDONE;
                   2869:        sr_put_wu(wu);
                   2870:        scsi_done(xs);
                   2871:        splx(s);
                   2872: }
                   2873:
                   2874: void
                   2875: sr_raid1_recreate_wu(struct sr_workunit *wu)
                   2876: {
                   2877:        struct sr_discipline    *sd = wu->swu_dis;
                   2878:        struct sr_workunit      *wup = wu;
                   2879:        struct sr_ccb           *ccb;
                   2880:
                   2881:        do {
                   2882:                DNPRINTF(SR_D_INTR, "%s: sr_raid1_recreate_wu: %p\n", wup);
                   2883:
                   2884:                /* toss all ccbs */
                   2885:                while ((ccb = TAILQ_FIRST(&wup->swu_ccb)) != NULL) {
                   2886:                        TAILQ_REMOVE(&wup->swu_ccb, ccb, ccb_link);
                   2887:                        sr_put_ccb(ccb);
                   2888:                }
                   2889:                TAILQ_INIT(&wup->swu_ccb);
                   2890:
                   2891:                /* recreate ccbs */
                   2892:                wup->swu_state = SR_WU_REQUEUE;
                   2893:                if (sd->sd_scsi_rw(wup))
                   2894:                        panic("could not requeue io");
                   2895:
                   2896:                wup = wup->swu_collider;
                   2897:        } while (wup);
                   2898: }
                   2899:
                   2900: #ifdef CRYPTO
                   2901: /* RAID crypto functions */
                   2902: struct cryptop *
                   2903: sr_raidc_getcryptop(struct sr_workunit *wu, int encrypt)
                   2904: {
                   2905:        struct scsi_xfer        *xs = wu->swu_xs;
                   2906:        struct sr_discipline    *sd = wu->swu_dis;
                   2907:        struct cryptop          *crp;
                   2908:        struct cryptodesc       *crd;
                   2909:        struct uio              *uio;
                   2910:        int                     flags, i, n;
                   2911:        int                     blk = 0;
                   2912:
                   2913:        DNPRINTF(SR_D_DIS, "%s: sr_raidc_getcryptop wu: %p encrypt: %d\n",
                   2914:            DEVNAME(sd->sd_sc), wu, encrypt);
                   2915:
                   2916:        uio = malloc(sizeof(*uio), M_DEVBUF, M_WAITOK);
                   2917:        memset(uio, 0, sizeof(*uio));
                   2918:        uio->uio_iov = malloc(sizeof(*uio->uio_iov), M_DEVBUF, M_WAITOK);
                   2919:        uio->uio_iovcnt = 1;
                   2920:        uio->uio_iov->iov_base = xs->data;
                   2921:        uio->uio_iov->iov_len = xs->datalen;
                   2922:
                   2923:        if (xs->cmdlen == 10)
                   2924:                blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
                   2925:        else if (xs->cmdlen == 6)
                   2926:                blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
                   2927:
                   2928:        n = xs->datalen >> 9;
                   2929:        flags = (encrypt ? CRD_F_ENCRYPT : 0) |
                   2930:            CRD_F_IV_PRESENT | CRD_F_IV_EXPLICIT;
                   2931:
                   2932:        crp = crypto_getreq(n);
                   2933:
                   2934:        crp->crp_sid = sd->mds.mdd_raidc.src_sid;
                   2935:        crp->crp_ilen = xs->datalen;
                   2936:        crp->crp_alloctype = M_DEVBUF;
                   2937:        crp->crp_buf = uio;
                   2938:        for (i = 0, crd = crp->crp_desc; crd; i++, crd = crd->crd_next) {
                   2939:                crd->crd_skip = 512 * i;
                   2940:                crd->crd_len = 512;
                   2941:                crd->crd_inject = 0;
                   2942:                crd->crd_flags = flags;
                   2943:                crd->crd_alg = CRYPTO_AES_CBC;
                   2944:                crd->crd_klen = 256;
                   2945:                crd->crd_rnd = 14;
                   2946:                crd->crd_key = sd->mds.mdd_raidc.src_key;
                   2947:                memset(crd->crd_iv, blk + i, sizeof(crd->crd_iv));
                   2948:        }
                   2949:
                   2950:        return (crp);
                   2951: }
                   2952:
                   2953: void *
                   2954: sr_raidc_putcryptop(struct cryptop *crp)
                   2955: {
                   2956:        struct uio              *uio = crp->crp_buf;
                   2957:        void                    *opaque = crp->crp_opaque;
                   2958:
                   2959:        DNPRINTF(SR_D_DIS, "sr_raidc_putcryptop crp: %p\n", crp);
                   2960:
                   2961:        free(uio->uio_iov, M_DEVBUF);
                   2962:        free(uio, M_DEVBUF);
                   2963:        crypto_freereq(crp);
                   2964:
                   2965:        return (opaque);
                   2966: }
                   2967:
                   2968: int
                   2969: sr_raidc_alloc_resources(struct sr_discipline *sd)
                   2970: {
                   2971:        struct cryptoini        cri;
                   2972:
                   2973:        if (!sd)
                   2974:                return (EINVAL);
                   2975:
                   2976:        DNPRINTF(SR_D_DIS, "%s: sr_raidc_alloc_resources\n",
                   2977:            DEVNAME(sd->sd_sc));
                   2978:
                   2979:        if (sr_alloc_wu(sd))
                   2980:                return (ENOMEM);
                   2981:        if (sr_alloc_ccb(sd))
                   2982:                return (ENOMEM);
                   2983:
                   2984:        /* XXX we need a real key later */
                   2985:        memset(sd->mds.mdd_raidc.src_key, 'k',
                   2986:            sizeof sd->mds.mdd_raidc.src_key);
                   2987:
                   2988:        bzero(&cri, sizeof(cri));
                   2989:        cri.cri_alg = CRYPTO_AES_CBC;
                   2990:        cri.cri_klen = 256;
                   2991:        cri.cri_rnd = 14;
                   2992:        cri.cri_key = sd->mds.mdd_raidc.src_key;
                   2993:
                   2994:        return (crypto_newsession(&sd->mds.mdd_raidc.src_sid, &cri, 0));
                   2995: }
                   2996:
                   2997: int
                   2998: sr_raidc_free_resources(struct sr_discipline *sd)
                   2999: {
                   3000:        int                     rv = EINVAL;
                   3001:
                   3002:        if (!sd)
                   3003:                return (rv);
                   3004:
                   3005:        DNPRINTF(SR_D_DIS, "%s: sr_raidc_free_resources\n",
                   3006:            DEVNAME(sd->sd_sc));
                   3007:
                   3008:        sr_free_wu(sd);
                   3009:        sr_free_ccb(sd);
                   3010:
                   3011:        if (sd->sd_meta)
                   3012:                free(sd->sd_meta, M_DEVBUF);
                   3013:
                   3014:        rv = 0;
                   3015:        return (rv);
                   3016: }
                   3017:
                   3018: int
                   3019: sr_raidc_rw(struct sr_workunit *wu)
                   3020: {
                   3021:        struct cryptop          *crp;
                   3022:
                   3023:        DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw wu: %p\n",
                   3024:            DEVNAME(wu->swu_dis->sd_sc), wu);
                   3025:
                   3026:        crp = sr_raidc_getcryptop(wu, 1);
                   3027:        crp->crp_callback = sr_raidc_rw2;
                   3028:        crp->crp_opaque = wu;
                   3029:        crypto_dispatch(crp);
                   3030:
                   3031:        return (0);
                   3032: }
                   3033:
                   3034: int
                   3035: sr_raidc_rw2(struct cryptop *crp)
                   3036: {
                   3037:        struct sr_workunit      *wu = sr_raidc_putcryptop(crp);
                   3038:        struct sr_discipline    *sd = wu->swu_dis;
                   3039:        struct scsi_xfer        *xs = wu->swu_xs;
                   3040:        struct sr_workunit      *wup;
                   3041:        struct sr_ccb           *ccb;
                   3042:        struct sr_chunk         *scp;
                   3043:        int                     s, rt;
                   3044:        daddr64_t               blk;
                   3045:
                   3046:        DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw2 0x%02x\n", DEVNAME(sd->sd_sc),
                   3047:            xs->cmd->opcode);
                   3048:
                   3049:        if (sd->sd_vol.sv_meta.svm_status == BIOC_SVOFFLINE) {
                   3050:                DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw device offline\n",
                   3051:                    DEVNAME(sd->sd_sc));
                   3052:                goto bad;
                   3053:        }
                   3054:
                   3055:        if (xs->datalen == 0) {
                   3056:                printf("%s: %s: illegal block count\n",
                   3057:                    DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname);
                   3058:                goto bad;
                   3059:        }
                   3060:
                   3061:        if (xs->cmdlen == 10)
                   3062:                blk = _4btol(((struct scsi_rw_big *)xs->cmd)->addr);
                   3063:        else if (xs->cmdlen == 6)
                   3064:                blk = _3btol(((struct scsi_rw *)xs->cmd)->addr);
                   3065:        else {
                   3066:                printf("%s: %s: illegal cmdlen\n", DEVNAME(sd->sd_sc),
                   3067:                    sd->sd_vol.sv_meta.svm_devname);
                   3068:                goto bad;
                   3069:        }
                   3070:
                   3071:        wu->swu_blk_start = blk;
                   3072:        wu->swu_blk_end = blk + (xs->datalen >> 9) - 1;
                   3073:
                   3074:        if (wu->swu_blk_end > sd->sd_vol.sv_meta.svm_size) {
                   3075:                DNPRINTF(SR_D_DIS, "%s: sr_raidc_rw2 out of bounds start: %lld "
                   3076:                    "end: %lld length: %d\n", wu->swu_blk_start,
                   3077:                    wu->swu_blk_end, xs->datalen);
                   3078:
                   3079:                sd->sd_scsi_sense.error_code = SSD_ERRCODE_CURRENT |
                   3080:                    SSD_ERRCODE_VALID;
                   3081:                sd->sd_scsi_sense.flags = SKEY_ILLEGAL_REQUEST;
                   3082:                sd->sd_scsi_sense.add_sense_code = 0x21;
                   3083:                sd->sd_scsi_sense.add_sense_code_qual = 0x00;
                   3084:                sd->sd_scsi_sense.extra_len = 4;
                   3085:                goto bad;
                   3086:        }
                   3087:
                   3088:        /* calculate physical block */
                   3089:        blk += SR_META_SIZE + SR_META_OFFSET;
                   3090:
                   3091:        wu->swu_io_count = 1;
                   3092:
                   3093:        ccb = sr_get_ccb(sd);
                   3094:        if (!ccb) {
                   3095:                /* should never happen but handle more gracefully */
                   3096:                printf("%s: %s: too many ccbs queued\n",
                   3097:                    DEVNAME(sd->sd_sc),
                   3098:                    sd->sd_vol.sv_meta.svm_devname);
                   3099:                goto bad;
                   3100:        }
                   3101:
                   3102:        if (xs->flags & SCSI_POLL) {
                   3103:                panic("not yet, crypto poll");
                   3104:                ccb->ccb_buf.b_flags = 0;
                   3105:                ccb->ccb_buf.b_iodone = NULL;
                   3106:        } else {
                   3107:                ccb->ccb_buf.b_flags = B_CALL;
                   3108:                ccb->ccb_buf.b_iodone = sr_raidc_intr;
                   3109:        }
                   3110:
                   3111:        ccb->ccb_buf.b_blkno = blk;
                   3112:        ccb->ccb_buf.b_bcount = xs->datalen;
                   3113:        ccb->ccb_buf.b_bufsize = xs->datalen;
                   3114:        ccb->ccb_buf.b_resid = xs->datalen;
                   3115:        ccb->ccb_buf.b_data = xs->data;
                   3116:        ccb->ccb_buf.b_error = 0;
                   3117:        ccb->ccb_buf.b_proc = curproc;
                   3118:        ccb->ccb_wu = wu;
                   3119:
                   3120:        if (xs->flags & SCSI_DATA_IN) {
                   3121:                rt = 0;
                   3122: ragain:
                   3123:                scp = sd->sd_vol.sv_chunks[0];
                   3124:                switch (scp->src_meta.scm_status) {
                   3125:                case BIOC_SDONLINE:
                   3126:                case BIOC_SDSCRUB:
                   3127:                        ccb->ccb_buf.b_flags |= B_READ;
                   3128:                        break;
                   3129:
                   3130:                case BIOC_SDOFFLINE:
                   3131:                case BIOC_SDREBUILD:
                   3132:                case BIOC_SDHOTSPARE:
                   3133:                        if (rt++ < sd->sd_vol.sv_meta.svm_no_chunk)
                   3134:                                goto ragain;
                   3135:
                   3136:                        /* FALLTHROUGH */
                   3137:                default:
                   3138:                        /* volume offline */
                   3139:                        printf("%s: is offline, can't read\n",
                   3140:                            DEVNAME(sd->sd_sc));
                   3141:                        sr_put_ccb(ccb);
                   3142:                        goto bad;
                   3143:                }
                   3144:        } else {
                   3145:                scp = sd->sd_vol.sv_chunks[0];
                   3146:                switch (scp->src_meta.scm_status) {
                   3147:                case BIOC_SDONLINE:
                   3148:                case BIOC_SDSCRUB:
                   3149:                case BIOC_SDREBUILD:
                   3150:                        ccb->ccb_buf.b_flags |= B_WRITE;
                   3151:                        break;
                   3152:
                   3153:                case BIOC_SDHOTSPARE: /* should never happen */
                   3154:                case BIOC_SDOFFLINE:
                   3155:                        wu->swu_io_count--;
                   3156:                        sr_put_ccb(ccb);
                   3157:                        goto bad;
                   3158:
                   3159:                default:
                   3160:                        goto bad;
                   3161:                }
                   3162:
                   3163:        }
                   3164:        ccb->ccb_target = 0;
                   3165:        ccb->ccb_buf.b_dev = sd->sd_vol.sv_chunks[0]->src_dev_mm;
                   3166:        ccb->ccb_buf.b_vp = NULL;
                   3167:
                   3168:        LIST_INIT(&ccb->ccb_buf.b_dep);
                   3169:
                   3170:        TAILQ_INSERT_TAIL(&wu->swu_ccb, ccb, ccb_link);
                   3171:
                   3172:        DNPRINTF(SR_D_DIS, "%s: %s: sr_raidc: b_bcount: %d "
                   3173:            "b_blkno: %x b_flags 0x%0x b_data %p\n",
                   3174:            DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname,
                   3175:            ccb->ccb_buf.b_bcount, ccb->ccb_buf.b_blkno,
                   3176:            ccb->ccb_buf.b_flags, ccb->ccb_buf.b_data);
                   3177:
                   3178:
                   3179:        /* walk queue backwards and fill in collider if we have one */
                   3180:        s = splbio();
                   3181:        TAILQ_FOREACH_REVERSE(wup, &sd->sd_wu_pendq, sr_wu_list, swu_link) {
                   3182:                if (wu->swu_blk_end < wup->swu_blk_start ||
                   3183:                    wup->swu_blk_end < wu->swu_blk_start)
                   3184:                        continue;
                   3185:
                   3186:                /* we have an LBA collision, defer wu */
                   3187:                wu->swu_state = SR_WU_DEFERRED;
                   3188:                if (wup->swu_collider)
                   3189:                        /* wu is on deferred queue, append to last wu */
                   3190:                        while (wup->swu_collider)
                   3191:                                wup = wup->swu_collider;
                   3192:
                   3193:                wup->swu_collider = wu;
                   3194:                TAILQ_INSERT_TAIL(&sd->sd_wu_defq, wu, swu_link);
                   3195:                sd->sd_wu_collisions++;
                   3196:                goto queued;
                   3197:        }
                   3198:
                   3199:        /* XXX deal with polling */
                   3200:
                   3201:        sr_raid_startwu(wu);
                   3202:
                   3203: queued:
                   3204:        splx(s);
                   3205:        return (0);
                   3206: bad:
                   3207:        /* wu is unwound by sr_put_wu */
                   3208:        return (1);
                   3209: }
                   3210:
                   3211: void
                   3212: sr_raidc_intr(struct buf *bp)
                   3213: {
                   3214:        struct sr_ccb           *ccb = (struct sr_ccb *)bp;
                   3215:        struct sr_workunit      *wu = ccb->ccb_wu;
                   3216:        struct cryptop          *crp;
                   3217: #ifdef SR_DEBUG
                   3218:        struct sr_softc         *sc = wu->swu_dis->sd_sc;
                   3219: #endif
                   3220:
                   3221:        DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr bp: %x xs: %x\n",
                   3222:            DEVNAME(sc), bp, wu->swu_xs);
                   3223:
                   3224:        DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr: b_bcount: %d b_resid: %d"
                   3225:            " b_flags: 0x%0x\n", DEVNAME(sc), ccb->ccb_buf.b_bcount,
                   3226:            ccb->ccb_buf.b_resid, ccb->ccb_buf.b_flags);
                   3227:
                   3228:        crp = sr_raidc_getcryptop(wu, 0);
                   3229:        crp->crp_callback = sr_raidc_intr2;
                   3230:        crp->crp_opaque = bp;
                   3231:        crypto_dispatch(crp);
                   3232: }
                   3233:
                   3234: int
                   3235: sr_raidc_intr2(struct cryptop *crp)
                   3236: {
                   3237:        struct buf              *bp = sr_raidc_putcryptop(crp);
                   3238:        struct sr_ccb           *ccb = (struct sr_ccb *)bp;
                   3239:        struct sr_workunit      *wu = ccb->ccb_wu, *wup;
                   3240:        struct sr_discipline    *sd = wu->swu_dis;
                   3241:        struct scsi_xfer        *xs = wu->swu_xs;
                   3242:        struct sr_softc         *sc = sd->sd_sc;
                   3243:        int                     s, pend;
                   3244:
                   3245:        DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr2 crp: %x xs: %x\n",
                   3246:            DEVNAME(sc), crp, xs);
                   3247:
                   3248:        s = splbio();
                   3249:
                   3250:        if (ccb->ccb_buf.b_flags & B_ERROR) {
                   3251:                printf("%s: i/o error on block %lld\n", DEVNAME(sc),
                   3252:                    ccb->ccb_buf.b_blkno);
                   3253:                wu->swu_ios_failed++;
                   3254:                ccb->ccb_state = SR_CCB_FAILED;
                   3255:                if (ccb->ccb_target != -1)
                   3256:                        sd->sd_set_chunk_state(sd, ccb->ccb_target,
                   3257:                            BIOC_SDOFFLINE);
                   3258:                else
                   3259:                        panic("%s: invalid target on wu: %p", DEVNAME(sc), wu);
                   3260:        } else {
                   3261:                ccb->ccb_state = SR_CCB_OK;
                   3262:                wu->swu_ios_succeeded++;
                   3263:        }
                   3264:        wu->swu_ios_complete++;
                   3265:
                   3266:        DNPRINTF(SR_D_INTR, "%s: sr_raidc_intr2: comp: %d count: %d\n",
                   3267:            DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count);
                   3268:
                   3269:        if (wu->swu_ios_complete == wu->swu_io_count) {
                   3270:                if (wu->swu_ios_failed == wu->swu_ios_complete)
                   3271:                        xs->error = XS_DRIVER_STUFFUP;
                   3272:                else
                   3273:                        xs->error = XS_NOERROR;
                   3274:
                   3275:                xs->resid = 0;
                   3276:                xs->flags |= ITSDONE;
                   3277:
                   3278:                pend = 0;
                   3279:                TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) {
                   3280:                        if (wu == wup) {
                   3281:                                /* wu on pendq, remove */
                   3282:                                TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
                   3283:                                pend = 1;
                   3284:
                   3285:                                if (wu->swu_collider) {
                   3286:                                        /* restart deferred wu */
                   3287:                                        wu->swu_collider->swu_state =
                   3288:                                            SR_WU_INPROGRESS;
                   3289:                                        TAILQ_REMOVE(&sd->sd_wu_defq,
                   3290:                                            wu->swu_collider, swu_link);
                   3291:                                        sr_raid_startwu(wu->swu_collider);
                   3292:                                }
                   3293:                                break;
                   3294:                        }
                   3295:                }
                   3296:
                   3297:                if (!pend)
                   3298:                        printf("%s: wu: %p not on pending queue\n",
                   3299:                            DEVNAME(sc), wu);
                   3300:
                   3301:                /* do not change the order of these 2 functions */
                   3302:                sr_put_wu(wu);
                   3303:                scsi_done(xs);
                   3304:
                   3305:                if (sd->sd_sync && sd->sd_wu_pending == 0)
                   3306:                        wakeup(sd);
                   3307:        }
                   3308:
                   3309:        splx(s);
                   3310:
                   3311:        return (0);
                   3312: }
                   3313: #endif

CVSweb