1 1991 heppo /* 2 1991 heppo * CDDL HEADER START 3 1991 heppo * 4 1991 heppo * The contents of this file are subject to the terms of the 5 1991 heppo * Common Development and Distribution License (the "License"). 6 1991 heppo * You may not use this file except in compliance with the License. 7 1991 heppo * 8 1991 heppo * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 1991 heppo * or http://www.opensolaris.org/os/licensing. 10 1991 heppo * See the License for the specific language governing permissions 11 1991 heppo * and limitations under the License. 12 1991 heppo * 13 1991 heppo * When distributing Covered Code, include this CDDL HEADER in each 14 1991 heppo * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 1991 heppo * If applicable, add the following below this CDDL HEADER, with the 16 1991 heppo * fields enclosed by brackets "[]" replaced with your own identifying 17 1991 heppo * information: Portions Copyright [yyyy] [name of copyright owner] 18 1991 heppo * 19 1991 heppo * CDDL HEADER END 20 1991 heppo */ 21 1991 heppo 22 1991 heppo /* 23 9889 Larry * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 1991 heppo * Use is subject to license terms. 25 1991 heppo */ 26 1991 heppo 27 1991 heppo #ifndef _VDSK_COMMON_H 28 1991 heppo #define _VDSK_COMMON_H 29 1991 heppo 30 1991 heppo #ifdef __cplusplus 31 1991 heppo extern "C" { 32 1991 heppo #endif 33 1991 heppo 34 1991 heppo /* 35 1991 heppo * This header file contains the private LDoms Virtual Disk (vDisk) definitions 36 1991 heppo * common to both the server (vds) and the client (vdc) 37 1991 heppo */ 38 1991 heppo 39 2531 narayan #include <sys/efi_partition.h> 40 1991 heppo #include <sys/machparam.h> 41 1991 heppo #include <sys/vtoc.h> 42 1991 heppo 43 1991 heppo #include <sys/ldc.h> 44 1991 heppo #include <sys/vio_common.h> 45 1991 heppo #include <sys/vio_mailbox.h> 46 1991 heppo 47 1991 heppo /* 48 1991 heppo * vDisk definitions 49 1991 heppo */ 50 1991 heppo 51 1991 heppo /* 52 1991 heppo * The number of Descriptor Ring entries 53 1991 heppo * 54 1991 heppo * Constraints: 55 1991 heppo * - overall DRing size must be greater than 8K (MMU_PAGESIZE) 56 1991 heppo * - overall DRing size should be 8K aligned (desirable but not enforced) 57 1991 heppo * - DRing entry must be 8 byte aligned 58 1991 heppo */ 59 1991 heppo #define VD_DRING_LEN 512 60 1991 heppo 61 1991 heppo /* 62 1991 heppo * 63 1991 heppo */ 64 1991 heppo #define VD_DRING_ENTRY_SZ (sizeof (vd_dring_entry_t) + \ 65 1991 heppo (sizeof (ldc_mem_cookie_t) * (VD_MAX_COOKIES - 1))) 66 1991 heppo 67 1991 heppo /* 68 1991 heppo * The maximum block size we can transmit using one Descriptor Ring entry 69 1991 heppo * 70 1991 heppo * Currently no FS uses more than 128K and it doesn't look like they 71 1991 heppo * will either as there is no perf gain to be had by larger values. 72 1991 heppo * ( see ZFS comment at definition of SPA_MAXBLOCKSIZE ). 73 1991 heppo * 74 1991 heppo * We choose 256K to give us some headroom. 75 1991 heppo */ 76 1991 heppo #define VD_MAX_BLOCK_SIZE (256 * 1024) 77 1991 heppo 78 1991 heppo #define VD_MAX_COOKIES ((VD_MAX_BLOCK_SIZE / PAGESIZE) + 1) 79 1991 heppo #define VD_USEC_TIMEOUT 20000 80 1991 heppo #define VD_LDC_IDS_PROP "ldc-ids" 81 2410 lm66018 #define VD_LDC_MTU 256 82 1991 heppo 83 1991 heppo /* 84 1991 heppo * Flags used by ioctl routines to indicate if a copyin/copyout is needed 85 1991 heppo */ 86 1991 heppo #define VD_COPYOUT 0x1 87 1991 heppo #define VD_COPYIN 0x2 88 1991 heppo 89 1991 heppo /* 90 1991 heppo * vDisk operations on physical devices 91 1991 heppo */ 92 1991 heppo #define VD_OP_BREAD 0x01 /* Block Read */ 93 1991 heppo #define VD_OP_BWRITE 0x02 /* Block Write */ 94 1991 heppo #define VD_OP_FLUSH 0x03 /* Flush disk write cache contents */ 95 1991 heppo #define VD_OP_GET_WCE 0x04 /* Get disk W$ status */ 96 1991 heppo #define VD_OP_SET_WCE 0x05 /* Enable/Disable disk W$ */ 97 1991 heppo #define VD_OP_GET_VTOC 0x06 /* Get VTOC */ 98 1991 heppo #define VD_OP_SET_VTOC 0x07 /* Set VTOC */ 99 1991 heppo #define VD_OP_GET_DISKGEOM 0x08 /* Get disk geometry */ 100 1991 heppo #define VD_OP_SET_DISKGEOM 0x09 /* Set disk geometry */ 101 1991 heppo #define VD_OP_SCSICMD 0x0a /* SCSI control command */ 102 2531 narayan #define VD_OP_GET_DEVID 0x0b /* Get device id */ 103 2531 narayan #define VD_OP_GET_EFI 0x0c /* Get EFI */ 104 2531 narayan #define VD_OP_SET_EFI 0x0d /* Set EFI */ 105 5658 achartre #define VD_OP_RESET 0x0e /* Reset disk */ 106 5658 achartre #define VD_OP_GET_ACCESS 0x0f /* Get disk access */ 107 5658 achartre #define VD_OP_SET_ACCESS 0x10 /* Set disk access */ 108 5658 achartre #define VD_OP_GET_CAPACITY 0x11 /* Get disk capacity */ 109 1991 heppo #define VD_OP_MASK 0xFF /* mask of all possible operations */ 110 5658 achartre #define VD_OP_COUNT 0x11 /* Number of operations */ 111 5658 achartre 112 5658 achartre /* 113 5658 achartre * Status for the VD_OP_GET_ACCESS operation 114 5658 achartre */ 115 5658 achartre #define VD_ACCESS_DENIED 0x00 /* access is not allowed */ 116 5658 achartre #define VD_ACCESS_ALLOWED 0x01 /* access is allowed */ 117 5658 achartre 118 5658 achartre /* 119 5658 achartre * Flags for the VD_OP_SET_ACCESS operation 120 5658 achartre */ 121 5658 achartre #define VD_ACCESS_SET_CLEAR 0x00 /* clear exclusive access rights */ 122 5658 achartre #define VD_ACCESS_SET_EXCLUSIVE 0x01 /* set exclusive access rights */ 123 5658 achartre #define VD_ACCESS_SET_PREEMPT 0x02 /* forcefully set access rights */ 124 5658 achartre #define VD_ACCESS_SET_PRESERVE 0x04 /* preserve access rights */ 125 5365 lm66018 126 5365 lm66018 /* 127 5365 lm66018 * This is a mask of all the basic operations supported by all 128 5365 lm66018 * disk types (v1.0). 129 5365 lm66018 */ 130 5365 lm66018 #define VD_OP_MASK_READ \ 131 5365 lm66018 ((1 << VD_OP_BREAD) | \ 132 5365 lm66018 (1 << VD_OP_GET_WCE) | \ 133 5365 lm66018 (1 << VD_OP_GET_VTOC) | \ 134 5365 lm66018 (1 << VD_OP_GET_DISKGEOM) | \ 135 5365 lm66018 (1 << VD_OP_GET_DEVID) | \ 136 5365 lm66018 (1 << VD_OP_GET_EFI)) 137 5365 lm66018 138 5365 lm66018 #define VD_OP_MASK_WRITE \ 139 5365 lm66018 ((1 << VD_OP_BWRITE) | \ 140 5365 lm66018 (1 << VD_OP_FLUSH) | \ 141 5365 lm66018 (1 << VD_OP_SET_WCE) | \ 142 5365 lm66018 (1 << VD_OP_SET_VTOC) | \ 143 5365 lm66018 (1 << VD_OP_SET_DISKGEOM) | \ 144 5365 lm66018 (1 << VD_OP_SET_EFI)) 145 5365 lm66018 146 5658 achartre /* 147 5658 achartre * Mask for additional operations provided for SCSI disks (v1.1) 148 5658 achartre */ 149 5658 achartre #define VD_OP_MASK_SCSI \ 150 5658 achartre ((1 << VD_OP_SCSICMD) | \ 151 5658 achartre (1 << VD_OP_RESET) | \ 152 5658 achartre (1 << VD_OP_GET_ACCESS) | \ 153 7540 Ramesh (1 << VD_OP_SET_ACCESS)) 154 5365 lm66018 155 5365 lm66018 /* 156 5365 lm66018 * macro to check if the operation 'op' is supported by checking the list 157 5365 lm66018 * of operations supported which is exported by the vDisk server. 158 5365 lm66018 */ 159 5365 lm66018 #define VD_OP_SUPPORTED(ops_bitmask, op) ((ops_bitmask) & (1 << (op))) 160 4696 achartre 161 4696 achartre /* 162 4696 achartre * Slice for absolute disk transaction. 163 4696 achartre */ 164 4696 achartre #define VD_SLICE_NONE 0xFF 165 2531 narayan 166 2531 narayan /* 167 2531 narayan * EFI disks do not have a slice 7. Actually that slice is used to represent 168 2531 narayan * the whole disk. 169 2531 narayan */ 170 2531 narayan #define VD_EFI_WD_SLICE 7 171 1991 heppo 172 1991 heppo /* 173 1991 heppo * Definitions of the various ways vds can export disk support to vdc. 174 1991 heppo */ 175 1991 heppo typedef enum vd_disk_type { 176 1991 heppo VD_DISK_TYPE_UNK = 0, /* Unknown device type */ 177 1991 heppo VD_DISK_TYPE_SLICE, /* slice in block device */ 178 1991 heppo VD_DISK_TYPE_DISK /* entire disk (slice 2) */ 179 1991 heppo } vd_disk_type_t; 180 2531 narayan 181 2531 narayan /* 182 2531 narayan * Definitions of the various disk label that vDisk supports. 183 2531 narayan */ 184 2531 narayan typedef enum vd_disk_label { 185 2531 narayan VD_DISK_LABEL_UNK = 0, /* Unknown disk label */ 186 2531 narayan VD_DISK_LABEL_VTOC, /* VTOC disk label */ 187 2531 narayan VD_DISK_LABEL_EFI /* EFI disk label */ 188 2531 narayan } vd_disk_label_t; 189 1991 heppo 190 1991 heppo /* 191 1991 heppo * vDisk Descriptor payload 192 1991 heppo */ 193 1991 heppo typedef struct vd_dring_payload { 194 1991 heppo uint64_t req_id; /* The request ID being processed */ 195 1991 heppo uint8_t operation; /* operation for server to perform */ 196 1991 heppo uint8_t slice; /* The disk slice being accessed */ 197 1991 heppo uint16_t resv1; /* padding */ 198 1991 heppo uint32_t status; /* "errno" of server operation */ 199 1991 heppo uint64_t addr; /* LP64 diskaddr_t (block I/O) */ 200 1991 heppo uint64_t nbytes; /* LP64 size_t */ 201 1991 heppo uint32_t ncookies; /* Number of cookies used */ 202 1991 heppo uint32_t resv2; /* padding */ 203 1991 heppo 204 1991 heppo ldc_mem_cookie_t cookie[1]; /* variable sized array */ 205 1991 heppo } vd_dring_payload_t; 206 1991 heppo 207 1991 heppo 208 1991 heppo /* 209 1991 heppo * vDisk Descriptor entry 210 1991 heppo */ 211 1991 heppo typedef struct vd_dring_entry { 212 1991 heppo vio_dring_entry_hdr_t hdr; /* common header */ 213 1991 heppo vd_dring_payload_t payload; /* disk specific data */ 214 1991 heppo } vd_dring_entry_t; 215 5874 achartre 216 5874 achartre /* 217 5874 achartre * vDisk logical partition 218 5874 achartre */ 219 5874 achartre typedef struct vd_slice { 220 5874 achartre daddr_t start; /* block number of slice start */ 221 5874 achartre daddr_t nblocks; /* number of blocks in the slice */ 222 5874 achartre } vd_slice_t; 223 1991 heppo 224 1991 heppo 225 1991 heppo /* 226 1991 heppo * vDisk control operation structures 227 1991 heppo */ 228 1991 heppo 229 1991 heppo /* 230 2032 lm66018 * vDisk geometry definition (VD_OP_GET_DISKGEOM and VD_OP_SET_DISKGEOM) 231 2032 lm66018 */ 232 2032 lm66018 typedef struct vd_geom { 233 2032 lm66018 uint16_t ncyl; /* number of data cylinders */ 234 2032 lm66018 uint16_t acyl; /* number of alternate cylinders */ 235 2032 lm66018 uint16_t bcyl; /* cyl offset for fixed head area */ 236 2032 lm66018 uint16_t nhead; /* number of heads */ 237 2032 lm66018 uint16_t nsect; /* number of data sectors per track */ 238 2032 lm66018 uint16_t intrlv; /* interleave factor */ 239 2032 lm66018 uint16_t apc; /* alternates per cyl (SCSI only) */ 240 2032 lm66018 uint16_t rpm; /* revolutions per minute */ 241 2032 lm66018 uint16_t pcyl; /* number of physical cylinders */ 242 2032 lm66018 uint16_t write_reinstruct; /* # sectors to skip, writes */ 243 2032 lm66018 uint16_t read_reinstruct; /* # sectors to skip, reads */ 244 2032 lm66018 } vd_geom_t; 245 2032 lm66018 246 2032 lm66018 247 2032 lm66018 /* 248 2032 lm66018 * vDisk partition definition 249 1991 heppo */ 250 1991 heppo typedef struct vd_partition { 251 2032 lm66018 uint16_t id_tag; /* ID tag of partition */ 252 2032 lm66018 uint16_t perm; /* permission flags for partition */ 253 1991 heppo uint32_t reserved; /* padding */ 254 2032 lm66018 uint64_t start; /* block number of partition start */ 255 2032 lm66018 uint64_t nblocks; /* number of blocks in partition */ 256 1991 heppo } vd_partition_t; 257 1991 heppo 258 2032 lm66018 /* 259 2032 lm66018 * vDisk VTOC definition (VD_OP_GET_VTOC and VD_OP_SET_VTOC) 260 2032 lm66018 */ 261 2032 lm66018 #define VD_VOLNAME_LEN 8 /* length of volume_name field */ 262 2032 lm66018 #define VD_ASCIILABEL_LEN 128 /* length of ascii_label field */ 263 1991 heppo typedef struct vd_vtoc { 264 2032 lm66018 char volume_name[VD_VOLNAME_LEN]; /* volume name */ 265 2032 lm66018 uint16_t sector_size; /* sector size in bytes */ 266 2032 lm66018 uint16_t num_partitions; /* number of partitions */ 267 2032 lm66018 char ascii_label[VD_ASCIILABEL_LEN]; /* ASCII label */ 268 2032 lm66018 vd_partition_t partition[V_NUMPAR]; /* partition headers */ 269 1991 heppo } vd_vtoc_t; 270 1991 heppo 271 2531 narayan 272 2531 narayan /* 273 2531 narayan * vDisk EFI definition (VD_OP_GET_EFI and VD_OP_SET_EFI) 274 2531 narayan */ 275 2531 narayan typedef struct vd_efi { 276 2531 narayan uint64_t lba; /* lba of the request */ 277 2531 narayan uint64_t length; /* length of data */ 278 2531 narayan char data[1]; /* data of the request */ 279 2531 narayan } vd_efi_t; 280 2531 narayan 281 2531 narayan 282 2531 narayan /* 283 2531 narayan * vDisk DEVID definition (VD_OP_GET_DEVID) 284 2531 narayan */ 285 2531 narayan #define VD_DEVID_SIZE(l) (sizeof (vd_devid_t) - 1 + l) 286 2531 narayan #define VD_DEVID_DEFAULT_LEN 128 287 2531 narayan 288 2531 narayan typedef struct vd_devid { 289 2531 narayan uint16_t reserved; /* padding */ 290 2531 narayan uint16_t type; /* type of device id */ 291 2531 narayan uint32_t length; /* length the device id */ 292 2531 narayan char id[1]; /* device id */ 293 2531 narayan } vd_devid_t; 294 5658 achartre 295 5658 achartre /* 296 5658 achartre * vDisk CAPACITY definition (VD_OP_GET_CAPACITY) 297 5658 achartre */ 298 5658 achartre typedef struct vd_capacity { 299 5658 achartre uint32_t vdisk_block_size; /* block size in bytes */ 300 5658 achartre uint32_t reserved; /* reserved */ 301 5658 achartre uint64_t vdisk_size; /* disk size in blocks */ 302 5658 achartre } vd_capacity_t; 303 5658 achartre 304 5658 achartre /* Identifier for unknown disk size */ 305 5658 achartre #define VD_SIZE_UNKNOWN -1 306 5658 achartre 307 5658 achartre /* 308 5658 achartre * vDisk SCSI definition (VD_OP_SCSICMD) 309 5658 achartre */ 310 5658 achartre typedef struct vd_scsi { 311 5658 achartre uint8_t cmd_status; /* command completion status */ 312 5658 achartre uint8_t sense_status; /* sense command completion status */ 313 5658 achartre uint8_t task_attribute; /* task attribute */ 314 5658 achartre uint8_t task_priority; /* task priority */ 315 5658 achartre uint8_t crn; /* command reference number */ 316 5658 achartre uint8_t reserved; /* reserved */ 317 5658 achartre uint16_t timeout; /* command timeout */ 318 5658 achartre uint64_t options; /* options */ 319 5658 achartre uint64_t cdb_len; /* CDB data length */ 320 5658 achartre uint64_t sense_len; /* sense request length */ 321 5658 achartre uint64_t datain_len; /* data in buffer length */ 322 5658 achartre uint64_t dataout_len; /* data out buffer length */ 323 5658 achartre char data[1]; /* data (CDB, sense, data in/out */ 324 5658 achartre } vd_scsi_t; 325 5658 achartre 326 5658 achartre /* Minimum size of the vd_scsi structure */ 327 5658 achartre #define VD_SCSI_SIZE (sizeof (vd_scsi_t) - sizeof (uint64_t)) 328 5658 achartre 329 5658 achartre /* 330 5658 achartre * Macros to access data buffers in a vd_scsi structure. When using these 331 5658 achartre * macros, the vd_scsi structure needs to be populated with the sizes of 332 5658 achartre * data buffers allocated in the structure. 333 5658 achartre */ 334 5658 achartre #define VD_SCSI_DATA_CDB(vscsi) \ 335 5658 achartre ((union scsi_cdb *)(uintptr_t)((vscsi)->data)) 336 5658 achartre 337 5658 achartre #define VD_SCSI_DATA_SENSE(vscsi) \ 338 5658 achartre ((struct scsi_extended_sense *)(uintptr_t)((vscsi)->data + \ 339 5658 achartre P2ROUNDUP((vscsi)->cdb_len, sizeof (uint64_t)))) 340 5658 achartre 341 5658 achartre #define VD_SCSI_DATA_IN(vscsi) \ 342 5658 achartre ((uintptr_t)((vscsi)->data + \ 343 5658 achartre P2ROUNDUP((vscsi)->cdb_len, sizeof (uint64_t)) + \ 344 5658 achartre P2ROUNDUP((vscsi)->sense_len, sizeof (uint64_t)))) 345 5658 achartre 346 5658 achartre #define VD_SCSI_DATA_OUT(vscsi) \ 347 5658 achartre ((uintptr_t)((vscsi)->data + \ 348 5658 achartre P2ROUNDUP((vscsi)->cdb_len, sizeof (uint64_t)) + \ 349 5658 achartre P2ROUNDUP((vscsi)->sense_len, sizeof (uint64_t)) + \ 350 5658 achartre P2ROUNDUP((vscsi)->datain_len, sizeof (uint64_t)))) 351 5658 achartre 352 5658 achartre /* vDisk SCSI task attribute */ 353 5658 achartre #define VD_SCSI_TASK_SIMPLE 0x01 /* simple task */ 354 5658 achartre #define VD_SCSI_TASK_ORDERED 0x02 /* ordered task */ 355 5658 achartre #define VD_SCSI_TASK_HQUEUE 0x03 /* head of queue task */ 356 5658 achartre #define VD_SCSI_TASK_ACA 0x04 /* ACA task */ 357 5658 achartre 358 5658 achartre /* vDisk SCSI options */ 359 5658 achartre #define VD_SCSI_OPT_CRN 0x01 /* request has a CRN */ 360 5658 achartre #define VD_SCSI_OPT_NORETRY 0x02 /* do not attempt any retry */ 361 1991 heppo 362 1991 heppo /* 363 2032 lm66018 * Copy the contents of a vd_geom_t to the contents of a dk_geom struct 364 1991 heppo */ 365 2032 lm66018 #define VD_GEOM2DK_GEOM(vd_geom, dk_geom) \ 366 2032 lm66018 { \ 367 2032 lm66018 bzero((dk_geom), sizeof (*(dk_geom))); \ 368 2032 lm66018 (dk_geom)->dkg_ncyl = (vd_geom)->ncyl; \ 369 2032 lm66018 (dk_geom)->dkg_acyl = (vd_geom)->acyl; \ 370 2032 lm66018 (dk_geom)->dkg_bcyl = (vd_geom)->bcyl; \ 371 2032 lm66018 (dk_geom)->dkg_nhead = (vd_geom)->nhead; \ 372 2032 lm66018 (dk_geom)->dkg_nsect = (vd_geom)->nsect; \ 373 2032 lm66018 (dk_geom)->dkg_intrlv = (vd_geom)->intrlv; \ 374 2032 lm66018 (dk_geom)->dkg_apc = (vd_geom)->apc; \ 375 2032 lm66018 (dk_geom)->dkg_rpm = (vd_geom)->rpm; \ 376 2032 lm66018 (dk_geom)->dkg_pcyl = (vd_geom)->pcyl; \ 377 2032 lm66018 (dk_geom)->dkg_write_reinstruct = (vd_geom)->write_reinstruct; \ 378 2032 lm66018 (dk_geom)->dkg_read_reinstruct = (vd_geom)->read_reinstruct; \ 379 2032 lm66018 } 380 2032 lm66018 381 2032 lm66018 /* 382 2032 lm66018 * Copy the contents of a vd_vtoc_t to the contents of a vtoc struct 383 2032 lm66018 */ 384 2032 lm66018 #define VD_VTOC2VTOC(vd_vtoc, vtoc) \ 385 2032 lm66018 { \ 386 2032 lm66018 bzero((vtoc), sizeof (*(vtoc))); \ 387 2032 lm66018 bcopy((vd_vtoc)->volume_name, (vtoc)->v_volume, \ 388 2032 lm66018 MIN(sizeof ((vd_vtoc)->volume_name), \ 389 2032 lm66018 sizeof ((vtoc)->v_volume))); \ 390 2032 lm66018 bcopy((vd_vtoc)->ascii_label, (vtoc)->v_asciilabel, \ 391 2032 lm66018 MIN(sizeof ((vd_vtoc)->ascii_label), \ 392 2032 lm66018 sizeof ((vtoc)->v_asciilabel))); \ 393 2032 lm66018 (vtoc)->v_sanity = VTOC_SANE; \ 394 2032 lm66018 (vtoc)->v_version = V_VERSION; \ 395 2032 lm66018 (vtoc)->v_sectorsz = (vd_vtoc)->sector_size; \ 396 2032 lm66018 (vtoc)->v_nparts = (vd_vtoc)->num_partitions; \ 397 2032 lm66018 for (int i = 0; i < (vd_vtoc)->num_partitions; i++) { \ 398 2032 lm66018 (vtoc)->v_part[i].p_tag = (vd_vtoc)->partition[i].id_tag; \ 399 2032 lm66018 (vtoc)->v_part[i].p_flag = (vd_vtoc)->partition[i].perm; \ 400 2032 lm66018 (vtoc)->v_part[i].p_start = (vd_vtoc)->partition[i].start; \ 401 2032 lm66018 (vtoc)->v_part[i].p_size = (vd_vtoc)->partition[i].nblocks; \ 402 2032 lm66018 } \ 403 2032 lm66018 } 404 2032 lm66018 405 2032 lm66018 /* 406 2032 lm66018 * Copy the contents of a dk_geom struct to the contents of a vd_geom_t 407 2032 lm66018 */ 408 2032 lm66018 #define DK_GEOM2VD_GEOM(dk_geom, vd_geom) \ 409 2032 lm66018 { \ 410 2032 lm66018 bzero((vd_geom), sizeof (*(vd_geom))); \ 411 2032 lm66018 (vd_geom)->ncyl = (dk_geom)->dkg_ncyl; \ 412 2032 lm66018 (vd_geom)->acyl = (dk_geom)->dkg_acyl; \ 413 2032 lm66018 (vd_geom)->bcyl = (dk_geom)->dkg_bcyl; \ 414 2032 lm66018 (vd_geom)->nhead = (dk_geom)->dkg_nhead; \ 415 2032 lm66018 (vd_geom)->nsect = (dk_geom)->dkg_nsect; \ 416 2032 lm66018 (vd_geom)->intrlv = (dk_geom)->dkg_intrlv; \ 417 2032 lm66018 (vd_geom)->apc = (dk_geom)->dkg_apc; \ 418 2032 lm66018 (vd_geom)->rpm = (dk_geom)->dkg_rpm; \ 419 2032 lm66018 (vd_geom)->pcyl = (dk_geom)->dkg_pcyl; \ 420 2032 lm66018 (vd_geom)->write_reinstruct = (dk_geom)->dkg_write_reinstruct; \ 421 2032 lm66018 (vd_geom)->read_reinstruct = (dk_geom)->dkg_read_reinstruct; \ 422 2032 lm66018 } 423 2032 lm66018 424 2032 lm66018 /* 425 2032 lm66018 * Copy the contents of a vtoc struct to the contents of a vd_vtoc_t 426 2032 lm66018 */ 427 2032 lm66018 #define VTOC2VD_VTOC(vtoc, vd_vtoc) \ 428 2032 lm66018 { \ 429 2032 lm66018 bzero((vd_vtoc), sizeof (*(vd_vtoc))); \ 430 2032 lm66018 bcopy((vtoc)->v_volume, (vd_vtoc)->volume_name, \ 431 2032 lm66018 MIN(sizeof ((vtoc)->v_volume), \ 432 2032 lm66018 sizeof ((vd_vtoc)->volume_name))); \ 433 2032 lm66018 bcopy((vtoc)->v_asciilabel, (vd_vtoc)->ascii_label, \ 434 2032 lm66018 MIN(sizeof ((vtoc)->v_asciilabel), \ 435 2032 lm66018 sizeof ((vd_vtoc)->ascii_label))); \ 436 2032 lm66018 (vd_vtoc)->sector_size = (vtoc)->v_sectorsz; \ 437 2032 lm66018 (vd_vtoc)->num_partitions = (vtoc)->v_nparts; \ 438 2032 lm66018 for (int i = 0; i < (vtoc)->v_nparts; i++) { \ 439 2032 lm66018 (vd_vtoc)->partition[i].id_tag = (vtoc)->v_part[i].p_tag; \ 440 2032 lm66018 (vd_vtoc)->partition[i].perm = (vtoc)->v_part[i].p_flag; \ 441 2032 lm66018 (vd_vtoc)->partition[i].start = (vtoc)->v_part[i].p_start; \ 442 2032 lm66018 (vd_vtoc)->partition[i].nblocks = (vtoc)->v_part[i].p_size; \ 443 2032 lm66018 } \ 444 2032 lm66018 } 445 1991 heppo 446 2531 narayan /* 447 2531 narayan * Copy the contents of a vd_efi_t to the contents of a dk_efi_t. 448 2531 narayan * Note that (dk_efi)->dki_data and (vd_efi)->data should be correctly 449 2531 narayan * initialized prior to using this macro. 450 2531 narayan */ 451 2531 narayan #define VD_EFI2DK_EFI(vd_efi, dk_efi) \ 452 2531 narayan { \ 453 2531 narayan (dk_efi)->dki_lba = (vd_efi)->lba; \ 454 2531 narayan (dk_efi)->dki_length = (vd_efi)->length; \ 455 2531 narayan bcopy((vd_efi)->data, (dk_efi)->dki_data, (dk_efi)->dki_length); \ 456 2531 narayan } 457 2531 narayan 458 2531 narayan /* 459 2531 narayan * Copy the contents of dk_efi_t to the contents of vd_efi_t. 460 2531 narayan * Note that (dk_efi)->dki_data and (vd_efi)->data should be correctly 461 2531 narayan * initialized prior to using this macro. 462 2531 narayan */ 463 2531 narayan #define DK_EFI2VD_EFI(dk_efi, vd_efi) \ 464 2531 narayan { \ 465 2531 narayan (vd_efi)->lba = (dk_efi)->dki_lba; \ 466 2531 narayan (vd_efi)->length = (dk_efi)->dki_length; \ 467 2531 narayan bcopy((dk_efi)->dki_data, (vd_efi)->data, (vd_efi)->length); \ 468 2531 narayan } 469 2531 narayan 470 5365 lm66018 #define VD_MEDIATYPE2DK_MEDIATYPE(mt) \ 471 5365 lm66018 ((mt) == VD_MEDIA_FIXED ? DK_FIXED_DISK : \ 472 5365 lm66018 (mt) == VD_MEDIA_CD ? DK_CDROM : \ 473 5365 lm66018 (mt) == VD_MEDIA_DVD ? DK_DVDROM : \ 474 5365 lm66018 DK_UNKNOWN) 475 5365 lm66018 476 7929 Alexandre /* 477 7929 Alexandre * If the media type returned by the DKIOCGMEDIAINFO ioctl is greater than 478 7929 Alexandre * 0xFFFF then this is not an optical media and we consider that this is 479 7929 Alexandre * a fixed media. 480 7929 Alexandre * 481 7929 Alexandre * Otherwise, we have an optical media. If this is a SCSI media then the media 482 7929 Alexandre * type is actually the profile number returned by the SCSI GET CONFIGURATION 483 7929 Alexandre * command. In that case, the possible values we can have are described in the 484 7929 Alexandre * SCSI Multi-Media Commands (MMC) documentation. 485 7929 Alexandre * 486 7929 Alexandre * Not all SCSI optical media profile numbers are defined in Solaris. However 487 7929 Alexandre * undefined profiles are essentially different variants of DVD (like Blu-Ray 488 7929 Alexandre * or HD-DVD). So we consider that any optical media that we can not explicitly 489 7929 Alexandre * identify is a DVD. 490 7929 Alexandre */ 491 7929 Alexandre #define DK_MEDIA_OPTICAL_MAX 0xFFFF 492 7929 Alexandre 493 5365 lm66018 #define DK_MEDIATYPE2VD_MEDIATYPE(mt) \ 494 7929 Alexandre (((mt) > DK_MEDIA_OPTICAL_MAX)? VD_MEDIA_FIXED : \ 495 7929 Alexandre (mt) == DK_REMOVABLE_DISK ? VD_MEDIA_FIXED : \ 496 5365 lm66018 (mt) == DK_MO_ERASABLE ? VD_MEDIA_FIXED : \ 497 5365 lm66018 (mt) == DK_MO_WRITEONCE ? VD_MEDIA_FIXED : \ 498 5365 lm66018 (mt) == DK_AS_MO ? VD_MEDIA_FIXED : \ 499 5365 lm66018 (mt) == DK_CDROM ? VD_MEDIA_CD : \ 500 5365 lm66018 (mt) == DK_CDR ? VD_MEDIA_CD : \ 501 5365 lm66018 (mt) == DK_CDRW ? VD_MEDIA_CD : \ 502 7929 Alexandre VD_MEDIA_DVD) 503 5365 lm66018 504 2531 narayan /* 505 2531 narayan * Hooks for EFI support 506 2531 narayan */ 507 2531 narayan 508 2531 narayan /* 509 2531 narayan * The EFI alloc_and_read() function will use some ioctls to get EFI data 510 2531 narayan * but the device reference we will use is different depending if the command 511 2531 narayan * is issued from the vDisk server side (vds) or from the vDisk client side 512 5874 achartre * (vdc). The vd_efi_dev structure is filled by vdc/vds to indicate the ioctl 513 5874 achartre * function to call back and to provide information about the virtual disk. 514 2531 narayan */ 515 5874 achartre typedef int (*vd_efi_ioctl_func)(void *, int, uintptr_t); 516 2531 narayan 517 5874 achartre typedef struct vd_efi_dev { 518 5874 achartre void *vdisk; /* opaque pointer to the vdisk */ 519 5874 achartre size_t block_size; /* vdisk block size */ 520 5874 achartre size_t disk_size; /* vdisk size in blocks */ 521 5874 achartre vd_efi_ioctl_func vdisk_ioctl; /* vdisk ioctl function */ 522 5874 achartre } vd_efi_dev_t; 523 5874 achartre 524 9889 Larry #define VDSK_EFI_DEV_SET(efi_dev, vdsk, ioctl, bsize, dsize) \ 525 9889 Larry (efi_dev).vdisk = vdsk; \ 526 9889 Larry (efi_dev).vdisk_ioctl = ioctl; \ 527 9889 Larry (efi_dev).block_size = bsize; \ 528 9889 Larry (efi_dev).disk_size = dsize; 529 5874 achartre 530 5874 achartre 531 5874 achartre int vd_efi_alloc_and_read(vd_efi_dev_t *dev, efi_gpt_t **gpt, efi_gpe_t **gpe); 532 5874 achartre void vd_efi_free(vd_efi_dev_t *dev, efi_gpt_t *gpt, efi_gpe_t *gpe); 533 5874 achartre 534 6099 lm66018 /* 535 6099 lm66018 * Macros to update the I/O statistics kstat consumed by iostat(1m). 536 6099 lm66018 */ 537 6099 lm66018 538 6099 lm66018 /* 539 6099 lm66018 * Given a pointer to the instance private data of a vDisk driver (vd), 540 6099 lm66018 * the type of operation and the number of bytes read/written, this macro 541 6099 lm66018 * updates the I/O statistics in the kstat. 542 6099 lm66018 */ 543 6099 lm66018 #define VD_UPDATE_IO_STATS(vd, op, len) \ 544 6099 lm66018 { \ 545 6099 lm66018 ASSERT((vd) != NULL); \ 546 6099 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 547 6099 lm66018 ASSERT(((op) == VD_OP_BREAD) || ((op) == VD_OP_BWRITE));\ 548 6099 lm66018 if ((vd)->io_stats != NULL) { \ 549 6099 lm66018 kstat_io_t *kip = KSTAT_IO_PTR((vd)->io_stats); \ 550 6099 lm66018 if ((op) == VD_OP_BREAD) { \ 551 6099 lm66018 kip->reads++; \ 552 6099 lm66018 kip->nread += (len); \ 553 6099 lm66018 } else { \ 554 6099 lm66018 kip->writes++; \ 555 6099 lm66018 kip->nwritten += (len); \ 556 6099 lm66018 } \ 557 6099 lm66018 } \ 558 6099 lm66018 } 559 6099 lm66018 560 6099 lm66018 /* 561 6099 lm66018 * These wrapper macros take a pointer to the I/O statistics kstat and 562 6099 lm66018 * update the queue length statistics. These are 'safe' wrappers which 563 6099 lm66018 * check to see if the kstat was created when the vDisk instance was 564 6099 lm66018 * added (i.e. is not NULL). 565 6099 lm66018 */ 566 6468 lm66018 #define VD_KSTAT_WAITQ_ENTER(vd) \ 567 6468 lm66018 if ((vd)->io_stats != NULL) { \ 568 6468 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 569 6468 lm66018 kstat_waitq_enter(KSTAT_IO_PTR((vd)->io_stats)); \ 570 6099 lm66018 } 571 6099 lm66018 572 6468 lm66018 #define VD_KSTAT_WAITQ_EXIT(vd) \ 573 6468 lm66018 if ((vd)->io_stats != NULL) { \ 574 6468 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 575 6468 lm66018 kstat_waitq_exit(KSTAT_IO_PTR((vd)->io_stats)); \ 576 6099 lm66018 } 577 6099 lm66018 578 6468 lm66018 #define VD_KSTAT_WAITQ_TO_RUNQ(vd) \ 579 6468 lm66018 if ((vd)->io_stats != NULL) { \ 580 6468 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 581 6468 lm66018 kstat_waitq_to_runq(KSTAT_IO_PTR((vd)->io_stats)); \ 582 6099 lm66018 } 583 6099 lm66018 584 6468 lm66018 #define VD_KSTAT_RUNQ_ENTER(vd) \ 585 6468 lm66018 if ((vd)->io_stats != NULL) { \ 586 6468 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 587 6468 lm66018 kstat_runq_enter(KSTAT_IO_PTR((vd)->io_stats)); \ 588 6099 lm66018 } 589 6099 lm66018 590 6468 lm66018 #define VD_KSTAT_RUNQ_EXIT(vd) \ 591 6468 lm66018 if ((vd)->io_stats != NULL) { \ 592 6468 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 593 6468 lm66018 kstat_runq_exit(KSTAT_IO_PTR((vd)->io_stats)); \ 594 6099 lm66018 } 595 6099 lm66018 596 6099 lm66018 /* 597 6099 lm66018 * Given a pointer to the instance private data of a vDisk driver (vd) and 598 6099 lm66018 * the name of the error stats entry we wish to update, increment that value 599 6099 lm66018 */ 600 6099 lm66018 #define VD_UPDATE_ERR_STATS(vd, stat_entry) \ 601 6099 lm66018 { \ 602 6099 lm66018 ASSERT((vd) != NULL); \ 603 6099 lm66018 ASSERT(MUTEX_HELD(&(vd)->lock)); \ 604 6099 lm66018 if ((vd)->err_stats != NULL) { \ 605 6099 lm66018 vd_err_stats_t *stp; \ 606 6099 lm66018 stp = (vd_err_stats_t *)(vd)->err_stats->ks_data; \ 607 6099 lm66018 stp->stat_entry.value.ui32++; \ 608 6099 lm66018 } \ 609 6099 lm66018 } 610 6099 lm66018 611 6099 lm66018 /* Structure to record vDisk error statistics */ 612 6099 lm66018 typedef struct vd_err_stats { 613 6099 lm66018 struct kstat_named vd_softerrs; /* Softerrs */ 614 6099 lm66018 struct kstat_named vd_transerrs; /* Transport errs */ 615 6099 lm66018 struct kstat_named vd_protoerrs; /* VIO Protocol errs */ 616 6099 lm66018 struct kstat_named vd_vid; /* Vendor ID */ 617 6099 lm66018 struct kstat_named vd_pid; /* Product ID */ 618 6099 lm66018 struct kstat_named vd_capacity; /* Capacity of the disk */ 619 6099 lm66018 } vd_err_stats_t; 620 6099 lm66018 621 1991 heppo 622 1991 heppo #ifdef __cplusplus 623 1991 heppo } 624 1991 heppo #endif 625 1991 heppo 626 1991 heppo #endif /* _VDSK_COMMON_H */ 627