1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _VDSK_COMMON_H 28 #define _VDSK_COMMON_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 /* 37 * This header file contains the private LDoms Virtual Disk (vDisk) definitions 38 * common to both the server (vds) and the client (vdc) 39 */ 40 41 #include <sys/machparam.h> 42 #include <sys/vtoc.h> 43 44 #include <sys/ldc.h> 45 #include <sys/vio_common.h> 46 #include <sys/vio_mailbox.h> 47 48 /* 49 * vDisk definitions 50 */ 51 52 /* 53 * The number of Descriptor Ring entries 54 * 55 * Constraints: 56 * - overall DRing size must be greater than 8K (MMU_PAGESIZE) 57 * - overall DRing size should be 8K aligned (desirable but not enforced) 58 * - DRing entry must be 8 byte aligned 59 */ 60 #define VD_DRING_LEN 512 61 62 /* 63 * 64 */ 65 #define VD_DRING_ENTRY_SZ (sizeof (vd_dring_entry_t) + \ 66 (sizeof (ldc_mem_cookie_t) * (VD_MAX_COOKIES - 1))) 67 68 /* 69 * The maximum block size we can transmit using one Descriptor Ring entry 70 * 71 * Currently no FS uses more than 128K and it doesn't look like they 72 * will either as there is no perf gain to be had by larger values. 73 * ( see ZFS comment at definition of SPA_MAXBLOCKSIZE ). 74 * 75 * We choose 256K to give us some headroom. 76 */ 77 #define VD_MAX_BLOCK_SIZE (256 * 1024) 78 79 #define VD_MAX_COOKIES ((VD_MAX_BLOCK_SIZE / PAGESIZE) + 1) 80 #define VD_USEC_TIMEOUT 20000 81 #define VD_LDC_IDS_PROP "ldc-ids" 82 #define VD_LDC_QLEN 32 83 84 /* 85 * Flags used by ioctl routines to indicate if a copyin/copyout is needed 86 */ 87 #define VD_COPYOUT 0x1 88 #define VD_COPYIN 0x2 89 90 /* 91 * vDisk operations on physical devices 92 */ 93 #define VD_OP_BREAD 0x01 /* Block Read */ 94 #define VD_OP_BWRITE 0x02 /* Block Write */ 95 #define VD_OP_FLUSH 0x03 /* Flush disk write cache contents */ 96 #define VD_OP_GET_WCE 0x04 /* Get disk W$ status */ 97 #define VD_OP_SET_WCE 0x05 /* Enable/Disable disk W$ */ 98 #define VD_OP_GET_VTOC 0x06 /* Get VTOC */ 99 #define VD_OP_SET_VTOC 0x07 /* Set VTOC */ 100 #define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */ 101 #define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */ 102 #define VD_OP_SCSICMD 0x0a /* SCSI control command */ 103 #define VD_OP_MASK 0xFF /* mask of all possible operations */ 104 #define VD_OP_COUNT 10 /* Number of operations */ 105 106 /* 107 * Definitions of the various ways vds can export disk support to vdc. 108 */ 109 typedef enum vd_disk_type { 110 VD_DISK_TYPE_UNK = 0, /* Unknown device type */ 111 VD_DISK_TYPE_SLICE, /* slice in block device */ 112 VD_DISK_TYPE_DISK /* entire disk (slice 2) */ 113 } vd_disk_type_t; 114 115 /* 116 * vDisk Descriptor payload 117 */ 118 typedef struct vd_dring_payload { 119 uint64_t req_id; /* The request ID being processed */ 120 uint8_t operation; /* operation for server to perform */ 121 uint8_t slice; /* The disk slice being accessed */ 122 uint16_t resv1; /* padding */ 123 uint32_t status; /* "errno" of server operation */ 124 uint64_t addr; /* LP64 diskaddr_t (block I/O) */ 125 uint64_t nbytes; /* LP64 size_t */ 126 uint32_t ncookies; /* Number of cookies used */ 127 uint32_t resv2; /* padding */ 128 129 ldc_mem_cookie_t cookie[1]; /* variable sized array */ 130 } vd_dring_payload_t; 131 132 133 /* 134 * vDisk Descriptor entry 135 */ 136 typedef struct vd_dring_entry { 137 vio_dring_entry_hdr_t hdr; /* common header */ 138 vd_dring_payload_t payload; /* disk specific data */ 139 } vd_dring_entry_t; 140 141 142 /* 143 * vDisk control operation structures 144 * 145 * XXX FIXME - future support - add structures for VD_OP_XXXX 146 */ 147 148 /* 149 * vDisk geometry definition (VD_OP_GET_DISKGEOM and VD_OP_SET_DISKGEOM) 150 */ 151 typedef struct vd_geom { 152 uint16_t ncyl; /* number of data cylinders */ 153 uint16_t acyl; /* number of alternate cylinders */ 154 uint16_t bcyl; /* cyl offset for fixed head area */ 155 uint16_t nhead; /* number of heads */ 156 uint16_t nsect; /* number of data sectors per track */ 157 uint16_t intrlv; /* interleave factor */ 158 uint16_t apc; /* alternates per cyl (SCSI only) */ 159 uint16_t rpm; /* revolutions per minute */ 160 uint16_t pcyl; /* number of physical cylinders */ 161 uint16_t write_reinstruct; /* # sectors to skip, writes */ 162 uint16_t read_reinstruct; /* # sectors to skip, reads */ 163 } vd_geom_t; 164 165 166 /* 167 * vDisk partition definition 168 */ 169 typedef struct vd_partition { 170 uint16_t id_tag; /* ID tag of partition */ 171 uint16_t perm; /* permission flags for partition */ 172 uint32_t reserved; /* padding */ 173 uint64_t start; /* block number of partition start */ 174 uint64_t nblocks; /* number of blocks in partition */ 175 } vd_partition_t; 176 177 /* 178 * vDisk VTOC definition (VD_OP_GET_VTOC and VD_OP_SET_VTOC) 179 */ 180 #define VD_VOLNAME_LEN 8 /* length of volume_name field */ 181 #define VD_ASCIILABEL_LEN 128 /* length of ascii_label field */ 182 typedef struct vd_vtoc { 183 char volume_name[VD_VOLNAME_LEN]; /* volume name */ 184 uint16_t sector_size; /* sector size in bytes */ 185 uint16_t num_partitions; /* number of partitions */ 186 char ascii_label[VD_ASCIILABEL_LEN]; /* ASCII label */ 187 vd_partition_t partition[V_NUMPAR]; /* partition headers */ 188 } vd_vtoc_t; 189 190 191 /* 192 * Copy the contents of a vd_geom_t to the contents of a dk_geom struct 193 */ 194 #define VD_GEOM2DK_GEOM(vd_geom, dk_geom) \ 195 { \ 196 bzero((dk_geom), sizeof (*(dk_geom))); \ 197 (dk_geom)->dkg_ncyl = (vd_geom)->ncyl; \ 198 (dk_geom)->dkg_acyl = (vd_geom)->acyl; \ 199 (dk_geom)->dkg_bcyl = (vd_geom)->bcyl; \ 200 (dk_geom)->dkg_nhead = (vd_geom)->nhead; \ 201 (dk_geom)->dkg_nsect = (vd_geom)->nsect; \ 202 (dk_geom)->dkg_intrlv = (vd_geom)->intrlv; \ 203 (dk_geom)->dkg_apc = (vd_geom)->apc; \ 204 (dk_geom)->dkg_rpm = (vd_geom)->rpm; \ 205 (dk_geom)->dkg_pcyl = (vd_geom)->pcyl; \ 206 (dk_geom)->dkg_write_reinstruct = (vd_geom)->write_reinstruct; \ 207 (dk_geom)->dkg_read_reinstruct = (vd_geom)->read_reinstruct; \ 208 } 209 210 /* 211 * Copy the contents of a vd_vtoc_t to the contents of a vtoc struct 212 */ 213 #define VD_VTOC2VTOC(vd_vtoc, vtoc) \ 214 { \ 215 bzero((vtoc), sizeof (*(vtoc))); \ 216 bcopy((vd_vtoc)->volume_name, (vtoc)->v_volume, \ 217 MIN(sizeof ((vd_vtoc)->volume_name), \ 218 sizeof ((vtoc)->v_volume))); \ 219 bcopy((vd_vtoc)->ascii_label, (vtoc)->v_asciilabel, \ 220 MIN(sizeof ((vd_vtoc)->ascii_label), \ 221 sizeof ((vtoc)->v_asciilabel))); \ 222 (vtoc)->v_sanity = VTOC_SANE; \ 223 (vtoc)->v_version = V_VERSION; \ 224 (vtoc)->v_sectorsz = (vd_vtoc)->sector_size; \ 225 (vtoc)->v_nparts = (vd_vtoc)->num_partitions; \ 226 for (int i = 0; i < (vd_vtoc)->num_partitions; i++) { \ 227 (vtoc)->v_part[i].p_tag = (vd_vtoc)->partition[i].id_tag; \ 228 (vtoc)->v_part[i].p_flag = (vd_vtoc)->partition[i].perm; \ 229 (vtoc)->v_part[i].p_start = (vd_vtoc)->partition[i].start; \ 230 (vtoc)->v_part[i].p_size = (vd_vtoc)->partition[i].nblocks; \ 231 } \ 232 } 233 234 /* 235 * Copy the contents of a dk_geom struct to the contents of a vd_geom_t 236 */ 237 #define DK_GEOM2VD_GEOM(dk_geom, vd_geom) \ 238 { \ 239 bzero((vd_geom), sizeof (*(vd_geom))); \ 240 (vd_geom)->ncyl = (dk_geom)->dkg_ncyl; \ 241 (vd_geom)->acyl = (dk_geom)->dkg_acyl; \ 242 (vd_geom)->bcyl = (dk_geom)->dkg_bcyl; \ 243 (vd_geom)->nhead = (dk_geom)->dkg_nhead; \ 244 (vd_geom)->nsect = (dk_geom)->dkg_nsect; \ 245 (vd_geom)->intrlv = (dk_geom)->dkg_intrlv; \ 246 (vd_geom)->apc = (dk_geom)->dkg_apc; \ 247 (vd_geom)->rpm = (dk_geom)->dkg_rpm; \ 248 (vd_geom)->pcyl = (dk_geom)->dkg_pcyl; \ 249 (vd_geom)->write_reinstruct = (dk_geom)->dkg_write_reinstruct; \ 250 (vd_geom)->read_reinstruct = (dk_geom)->dkg_read_reinstruct; \ 251 } 252 253 /* 254 * Copy the contents of a vtoc struct to the contents of a vd_vtoc_t 255 */ 256 #define VTOC2VD_VTOC(vtoc, vd_vtoc) \ 257 { \ 258 bzero((vd_vtoc), sizeof (*(vd_vtoc))); \ 259 bcopy((vtoc)->v_volume, (vd_vtoc)->volume_name, \ 260 MIN(sizeof ((vtoc)->v_volume), \ 261 sizeof ((vd_vtoc)->volume_name))); \ 262 bcopy((vtoc)->v_asciilabel, (vd_vtoc)->ascii_label, \ 263 MIN(sizeof ((vtoc)->v_asciilabel), \ 264 sizeof ((vd_vtoc)->ascii_label))); \ 265 (vd_vtoc)->sector_size = (vtoc)->v_sectorsz; \ 266 (vd_vtoc)->num_partitions = (vtoc)->v_nparts; \ 267 for (int i = 0; i < (vtoc)->v_nparts; i++) { \ 268 (vd_vtoc)->partition[i].id_tag = (vtoc)->v_part[i].p_tag; \ 269 (vd_vtoc)->partition[i].perm = (vtoc)->v_part[i].p_flag; \ 270 (vd_vtoc)->partition[i].start = (vtoc)->v_part[i].p_start; \ 271 (vd_vtoc)->partition[i].nblocks = (vtoc)->v_part[i].p_size; \ 272 } \ 273 } 274 275 276 #ifdef __cplusplus 277 } 278 #endif 279 280 #endif /* _VDSK_COMMON_H */ 281