Annotation of sys/dev/softraidvar.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: softraidvar.h,v 1.32 2007/06/06 23:06:02 deraadt Exp $ */
! 2: /*
! 3: * Copyright (c) 2006 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 <dev/biovar.h>
! 19:
! 20: #include <sys/buf.h>
! 21: #include <sys/queue.h>
! 22: #include <sys/rwlock.h>
! 23:
! 24: #include <scsi/scsi_all.h>
! 25: #include <scsi/scsi_disk.h>
! 26: #include <scsi/scsiconf.h>
! 27:
! 28: #define DEVNAME(_s) ((_s)->sc_dev.dv_xname)
! 29:
! 30: /* #define SR_DEBUG */
! 31: #ifdef SR_DEBUG
! 32: extern u_int32_t sr_debug;
! 33: #define DPRINTF(x...) do { if (sr_debug) printf(x); } while(0)
! 34: #define DNPRINTF(n,x...) do { if (sr_debug & n) printf(x); } while(0)
! 35: #define SR_D_CMD 0x0001
! 36: #define SR_D_INTR 0x0002
! 37: #define SR_D_MISC 0x0004
! 38: #define SR_D_IOCTL 0x0008
! 39: #define SR_D_CCB 0x0010
! 40: #define SR_D_WU 0x0020
! 41: #define SR_D_META 0x0040
! 42: #define SR_D_DIS 0x0080
! 43: #define SR_D_STATE 0x0100
! 44: #else
! 45: #define DPRINTF(x...)
! 46: #define DNPRINTF(n,x...)
! 47: #endif
! 48:
! 49: #define SR_MAXFER MAXPHYS
! 50: #define SR_MAX_LD 1
! 51: #define SR_MAX_CMDS 16
! 52: #define SR_MAX_STATES 7
! 53:
! 54: /* forward define to prevent dependency goo */
! 55: struct sr_softc;
! 56:
! 57: #define SR_UUID_MAX 4
! 58: struct sr_uuid {
! 59: u_int32_t sui_id[SR_UUID_MAX];
! 60: } __packed;
! 61:
! 62: struct sr_ccb {
! 63: struct buf ccb_buf; /* MUST BE FIRST!! */
! 64:
! 65: struct sr_workunit *ccb_wu;
! 66: struct sr_discipline *ccb_dis;
! 67:
! 68: int ccb_target;
! 69: int ccb_state;
! 70: #define SR_CCB_FREE 0
! 71: #define SR_CCB_INPROGRESS 1
! 72: #define SR_CCB_OK 2
! 73: #define SR_CCB_FAILED 3
! 74:
! 75: TAILQ_ENTRY(sr_ccb) ccb_link;
! 76: } __packed;
! 77:
! 78: TAILQ_HEAD(sr_ccb_list, sr_ccb);
! 79:
! 80: struct sr_workunit {
! 81: struct scsi_xfer *swu_xs;
! 82: struct sr_discipline *swu_dis;
! 83:
! 84: int swu_state;
! 85: #define SR_WU_FREE 0
! 86: #define SR_WU_INPROGRESS 1
! 87: #define SR_WU_OK 2
! 88: #define SR_WU_FAILED 3
! 89: #define SR_WU_PARTIALLYFAILED 4
! 90: #define SR_WU_DEFERRED 5
! 91: #define SR_WU_PENDING 6
! 92: #define SR_WU_RESTART 7
! 93: #define SR_WU_REQUEUE 8
! 94:
! 95: int swu_fake; /* faked wu */
! 96: /* workunit io range */
! 97: daddr64_t swu_blk_start;
! 98: daddr64_t swu_blk_end;
! 99:
! 100: /* in flight totals */
! 101: u_int32_t swu_ios_complete;
! 102: u_int32_t swu_ios_failed;
! 103: u_int32_t swu_ios_succeeded;
! 104:
! 105: /* number of ios that makes up the whole work unit */
! 106: u_int32_t swu_io_count;
! 107:
! 108: /* colliding wu */
! 109: struct sr_workunit *swu_collider;
! 110:
! 111: /* all ios that make up this workunit */
! 112: struct sr_ccb_list swu_ccb;
! 113:
! 114: TAILQ_ENTRY(sr_workunit) swu_link;
! 115: };
! 116:
! 117: TAILQ_HEAD(sr_wu_list, sr_workunit);
! 118:
! 119: /* RAID 1 */
! 120: #define SR_RAID1_NOWU 16
! 121: struct sr_raid1 {
! 122: u_int32_t sr1_counter;
! 123: };
! 124:
! 125: /* RAID C */
! 126: #define SR_RAIDC_NOWU 16
! 127: struct sr_raidc {
! 128: u_int64_t src_sid;
! 129: char src_key[64];
! 130: };
! 131:
! 132: #define SR_META_SIZE 32 /* save space at chunk beginning */
! 133: #define SR_META_OFFSET 16 /* skip 8192 bytes at chunk beginning */
! 134: #define SR_META_VERSION 1 /* bump when sr_metadata changes */
! 135: struct sr_metadata {
! 136: /* do not change order of ssd_magic, ssd_version & ssd_checksum */
! 137: u_int64_t ssd_magic; /* magic id */
! 138: #define SR_MAGIC 0x4d4152436372616dLLU
! 139: u_int8_t ssd_version; /* meta data version */
! 140: u_int8_t ssd_pad1[3];
! 141: u_int32_t ssd_flags; /* flags */
! 142:
! 143: /* meta-data */
! 144: u_int32_t ssd_checksum; /* xor of the structure */
! 145: u_int32_t ssd_size; /* sizeof(sr_metadata) */
! 146: u_int32_t ssd_ondisk; /* on disk version counter */
! 147: u_int32_t ssd_pad2;
! 148: struct sr_uuid ssd_uuid; /* unique identifier */
! 149:
! 150: /* virtual disk data */
! 151: u_int32_t ssd_vd_ver; /* vd structure version */
! 152: u_int32_t ssd_vd_size; /* vd structure size */
! 153: u_int32_t ssd_vd_volid; /* volume id */
! 154: u_int32_t ssd_vd_chk; /* vd structure xor */
! 155:
! 156: /* chunk data */
! 157: u_int32_t ssd_chunk_ver; /* chunk structure version */
! 158: u_int32_t ssd_chunk_no; /* number of chunks */
! 159: u_int32_t ssd_chunk_size; /* chunk structure size */
! 160: u_int32_t ssd_chunk_id; /* chunk identifier */
! 161: u_int32_t ssd_chunk_chk; /* chunk structure xor */
! 162: u_int32_t ssd_pad3;
! 163:
! 164: /* optional metadata */
! 165: u_int32_t ssd_opt_ver; /* optinal meta version */
! 166: u_int32_t ssd_opt_no; /* nr of optional md elements */
! 167: u_int32_t ssd_opt_size; /* sizeof optional metadata */
! 168: u_int32_t ssd_opt_chk; /* optional metadata xor */
! 169: } __packed;
! 170:
! 171: struct sr_metadata_list {
! 172: struct sr_metadata *sml_metadata;
! 173: dev_t sml_mm;
! 174: int sml_used;
! 175:
! 176: SLIST_ENTRY(sr_metadata_list) sml_link;
! 177: };
! 178:
! 179: SLIST_HEAD(sr_metadata_list_head, sr_metadata_list);
! 180:
! 181: #define SR_OPT_VERSION 1 /* bump when sr_opt_meta changes */
! 182: struct sr_opt_meta {
! 183: u_int32_t som_type;
! 184: u_int32_t som_pad;
! 185: #define SR_OPT_INVALID 0x00
! 186: #define SR_OPT_CRYPTO 0x01
! 187: union {
! 188: struct sr_raidc smm_crypto;
! 189: } som_meta;
! 190: };
! 191:
! 192: #define SR_CHUNK_VERSION 1 /* bump when sr_chunk_meta changes */
! 193: struct sr_chunk_meta {
! 194: u_int32_t scm_volid; /* vd we belong to */
! 195: u_int32_t scm_chunk_id; /* chunk id */
! 196: u_int32_t scm_status; /* use bio bioc_disk status */
! 197: u_int32_t scm_pad1;
! 198: char scm_devname[32];/* /dev/XXXXX */
! 199: int64_t scm_size; /* size of partition */
! 200: int64_t scm_coerced_size; /* coerced size of part */
! 201: struct sr_uuid scm_uuid; /* unique identifier */
! 202: } __packed;
! 203:
! 204: struct sr_chunk {
! 205: struct sr_chunk_meta src_meta; /* chunk meta data */
! 206:
! 207: /* runtime data */
! 208: dev_t src_dev_mm; /* major/minor */
! 209:
! 210: /* helper members before metadata makes it onto the chunk */
! 211: int src_meta_ondisk;/* set when meta is on disk */
! 212: char src_devname[32];
! 213: int64_t src_size;
! 214:
! 215: SLIST_ENTRY(sr_chunk) src_link;
! 216: };
! 217:
! 218: SLIST_HEAD(sr_chunk_head, sr_chunk);
! 219:
! 220: #define SR_VOL_VERSION 1 /* bump when sr_vol_meta changes */
! 221: struct sr_vol_meta {
! 222: u_int32_t svm_volid; /* volume id */
! 223: u_int32_t svm_status; /* use bioc_vol status */
! 224: u_int32_t svm_flags; /* flags */
! 225: #define SR_VOL_DIRTY 0x01
! 226: u_int32_t svm_level; /* raid level */
! 227: int64_t svm_size; /* virtual disk size */
! 228: char svm_devname[32];/* /dev/XXXXX */
! 229: char svm_vendor[8]; /* scsi vendor */
! 230: char svm_product[16];/* scsi product */
! 231: char svm_revision[4];/* scsi revision */
! 232: u_int32_t svm_no_chunk; /* number of chunks */
! 233: struct sr_uuid svm_uuid; /* volume unique identifier */
! 234: } __packed;
! 235:
! 236: struct sr_volume {
! 237: struct sr_vol_meta sv_meta; /* meta data */
! 238:
! 239: /* runtime data */
! 240: struct sr_chunk_head sv_chunk_list; /* linked list of all chunks */
! 241: struct sr_chunk **sv_chunks; /* array to same chunks */
! 242:
! 243: /* sensors */
! 244: struct ksensor sv_sensor;
! 245: struct ksensordev sv_sensordev;
! 246: int sv_sensor_valid;
! 247: };
! 248:
! 249: struct sr_discipline {
! 250: struct sr_softc *sd_sc; /* link back to sr softc */
! 251: u_int8_t sd_type; /* type of discipline */
! 252: #define SR_MD_RAID0 0
! 253: #define SR_MD_RAID1 1
! 254: #define SR_MD_RAID5 2
! 255: #define SR_MD_CACHE 3
! 256: #define SR_MD_RAIDC 4
! 257: char sd_name[10]; /* human readable dis name */
! 258: u_int8_t sd_scsibus; /* scsibus discipline uses */
! 259: struct scsi_link sd_link; /* link to midlayer */
! 260:
! 261: union {
! 262: struct sr_raid1 mdd_raid1;
! 263: struct sr_raidc mdd_raidc;
! 264: } sd_dis_specific;/* dis specific members */
! 265: #define mds sd_dis_specific
! 266:
! 267: /* discipline metadata */
! 268: struct sr_metadata *sd_meta; /* in memory copy of metadata */
! 269: u_int32_t sd_meta_flags;
! 270:
! 271: int sd_sync;
! 272: int sd_must_flush;
! 273:
! 274: struct device *sd_scsibus_dev;
! 275: void (*sd_shutdownhook)(void *);
! 276:
! 277: /* discipline volume */
! 278: struct sr_volume sd_vol; /* volume associated */
! 279:
! 280: /* discipline resources */
! 281: struct sr_ccb *sd_ccb;
! 282: struct sr_ccb_list sd_ccb_freeq;
! 283: u_int32_t sd_max_ccb_per_wu;
! 284:
! 285: struct sr_workunit *sd_wu; /* all workunits */
! 286: u_int32_t sd_max_wu;
! 287:
! 288: struct sr_wu_list sd_wu_freeq; /* free wu queue */
! 289: struct sr_wu_list sd_wu_pendq; /* pending wu queue */
! 290: struct sr_wu_list sd_wu_defq; /* deferred wu queue */
! 291:
! 292: /* discipline stats */
! 293: int sd_wu_pending;
! 294: u_int64_t sd_wu_collisions;
! 295:
! 296: /* discipline functions */
! 297: int (*sd_alloc_resources)(struct sr_discipline *);
! 298: int (*sd_assemble_volume)(void *);
! 299: int (*sd_bringup_volume)(void *);
! 300: int (*sd_shutdown_volume)(void *);
! 301: int (*sd_free_resources)(struct sr_discipline *);
! 302: int (*sd_quiesce_io)(struct sr_discipline *);
! 303: void (*sd_set_chunk_state)(struct sr_discipline *,
! 304: int, int);
! 305: void (*sd_set_vol_state)(struct sr_discipline *);
! 306:
! 307: /* SCSI emulation */
! 308: struct scsi_sense_data sd_scsi_sense;
! 309: int (*sd_scsi_rw)(struct sr_workunit *);
! 310: int (*sd_scsi_sync)(struct sr_workunit *);
! 311: int (*sd_scsi_tur)(struct sr_workunit *);
! 312: int (*sd_scsi_start_stop)(struct sr_workunit *);
! 313: int (*sd_scsi_inquiry)(struct sr_workunit *);
! 314: int (*sd_scsi_read_cap)(struct sr_workunit *);
! 315: int (*sd_scsi_req_sense)(struct sr_workunit *);
! 316: };
! 317:
! 318: struct sr_softc {
! 319: struct device sc_dev;
! 320:
! 321: int (*sc_ioctl)(struct device *, u_long, caddr_t);
! 322:
! 323: struct rwlock sc_lock;
! 324:
! 325: int sc_sensors_running;
! 326: /*
! 327: * during scsibus attach this is the discipline that is in use
! 328: * this variable is protected by sc_lock and splhigh
! 329: */
! 330: struct sr_discipline *sc_attach_dis;
! 331:
! 332: /*
! 333: * XXX expensive, alternative would be nice but has to be cheap
! 334: * since the scsibus lookup happens on each IO
! 335: */
! 336: #define SR_MAXSCSIBUS 256
! 337: struct sr_discipline *sc_dis[SR_MAXSCSIBUS]; /* scsibus is u_int8_t */
! 338: };
CVSweb