root/dev/softraid.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sr_match
  2. sr_attach
  3. sr_detach
  4. sr_activate
  5. sr_minphys
  6. sr_copy_internal_data
  7. sr_alloc_ccb
  8. sr_free_ccb
  9. sr_get_ccb
  10. sr_put_ccb
  11. sr_alloc_wu
  12. sr_free_wu
  13. sr_put_wu
  14. sr_get_wu
  15. sr_scsi_cmd
  16. sr_scsi_ioctl
  17. sr_ioctl
  18. sr_ioctl_inq
  19. sr_ioctl_vol
  20. sr_ioctl_disk
  21. sr_ioctl_setstate
  22. sr_ioctl_createraid
  23. sr_open_chunks
  24. sr_read_meta
  25. sr_create_chunk_meta
  26. sr_unwind_chunks
  27. sr_free_discipline
  28. sr_shutdown_discipline
  29. sr_raid_inquiry
  30. sr_raid_read_cap
  31. sr_raid_tur
  32. sr_raid_request_sense
  33. sr_raid_start_stop
  34. sr_raid_sync
  35. sr_raid_startwu
  36. sr_raid_set_chunk_state
  37. sr_raid_set_vol_state
  38. sr_checksum
  39. sr_get_uuid
  40. sr_print_uuid
  41. sr_clear_metadata
  42. sr_already_assembled
  43. sr_save_metadata_callback
  44. sr_save_metadata
  45. sr_boot_assembly
  46. sr_validate_metadata
  47. sr_shutdown
  48. sr_create_sensors
  49. sr_delete_sensors
  50. sr_refresh_sensors
  51. sr_print_stats
  52. sr_print_metadata
  53. sr_raid1_alloc_resources
  54. sr_raid1_free_resources
  55. sr_raid1_rw
  56. sr_raid1_intr
  57. sr_raid1_recreate_wu
  58. sr_raidc_getcryptop
  59. sr_raidc_putcryptop
  60. sr_raidc_alloc_resources
  61. sr_raidc_free_resources
  62. sr_raidc_rw
  63. sr_raidc_rw2
  64. sr_raidc_intr
  65. sr_raidc_intr2

    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

/* [<][>][^][v][top][bottom][index][help] */