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 * Copyright 2016 Toomas Soome <tsoome@me.com> 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #ifndef _SYS_CMLB_H 28 #define _SYS_CMLB_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <sys/dktp/fdisk.h> 35 36 /* 37 * structure used for getting phygeom and virtgeom from target driver 38 */ 39 typedef struct cmlb_geom { 40 unsigned int g_ncyl; 41 unsigned short g_acyl; 42 unsigned short g_nhead; 43 unsigned short g_nsect; 44 unsigned short g_secsize; 45 diskaddr_t g_capacity; 46 unsigned short g_intrlv; 47 unsigned short g_rpm; 48 } cmlb_geom_t; 49 50 51 typedef struct tg_attribute { 52 int media_is_writable; 53 int media_is_solid_state; 54 } tg_attribute_t; 55 56 57 58 /* bit definitions for alter_behavior passed to cmlb_attach */ 59 60 #define CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT 0x00000001 61 #define CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8 0x00000002 62 #define CMLB_OFF_BY_ONE 0x00000004 63 #define CMLB_FAKE_LABEL_ONE_PARTITION 0x00000008 64 #define CMLB_INTERNAL_MINOR_NODES 0x00000010 65 #define CMLB_CREATE_P0_MINOR_NODE 0x00000020 66 67 /* bit definitions of flag passed to cmlb_validate */ 68 #define CMLB_SILENT 0x00000001 69 70 /* version for tg_ops */ 71 #define TG_DK_OPS_VERSION_0 0 72 #define TG_DK_OPS_VERSION_1 1 73 74 /* definitions for cmd passed to tg_rdwr */ 75 #define TG_READ 0 76 #define TG_WRITE 1 77 78 /* definitions for cmd passed to tg_getinfo */ 79 #define TG_GETPHYGEOM 1 80 #define TG_GETVIRTGEOM 2 81 #define TG_GETCAPACITY 3 82 #define TG_GETBLOCKSIZE 4 83 #define TG_GETATTR 5 84 85 #if defined(_SUNOS_VTOC_8) 86 87 #define CMLBUNIT_DFT_SHIFT 3 88 /* This will support p0 node on sparc */ 89 #define CMLBUNIT_FORCE_P0_SHIFT (CMLBUNIT_DFT_SHIFT + 1) 90 91 #elif defined(_SUNOS_VTOC_16) 92 93 #define CMLBUNIT_DFT_SHIFT 6 94 #define CMLBUNIT_FORCE_P0_SHIFT (CMLBUNIT_DFT_SHIFT) 95 96 #else /* defined(_SUNOS_VTOC_16) */ 97 98 #error "No VTOC format defined." 99 100 #endif /* defined(_SUNOS_VTOC_8) */ 101 102 /* 103 * Ops vector including utility functions into target driver that cmlb uses. 104 */ 105 typedef struct cmlb_tg_ops { 106 int tg_version; 107 108 /* 109 * tg_rdwr: 110 * perform read/write on target device associated with devi. 111 * 112 * Arguments: 113 * 114 * devi: pointer to device's dev_info structure. 115 * 116 * cmd: operation to perform. 117 * Possible values: TG_READ, TG_WRITE 118 * 119 * bufp: pointer to allocated buffer for transfer 120 * 121 * start_block: starting block number to read/write (based on 122 * system blocksize, DEV_BSIZE) 123 * 124 * reqlength: requested transfer length (in bytes) 125 * 126 * tg_cookie cookie from target driver to be passed back to 127 * target driver when we call back to it through 128 * tg_ops. 129 * 130 * Note: It is the responsibility of caller to make sure 131 * length of buffer pointed to by bufp is at least equal to 132 * requested transfer length 133 * 134 * Return values: 135 * 0 success 136 * ENOMEM can not allocate memory 137 * EACCESS reservation conflict 138 * EIO I/O error 139 * EFAULT copyin/copyout error 140 * ENXIO internal error/ invalid devi 141 * EINVAL invalid command value. 142 */ 143 int (*tg_rdwr)(dev_info_t *devi, uchar_t cmd, void *bufp, 144 diskaddr_t start_block, size_t reqlength, void *tg_cookie); 145 146 /* 147 * tg_getinfo: 148 * Report the information requested on device/media and 149 * store the requested info in area pointed to by arg. 150 * 151 * Arguments: 152 * devi: pointer to device's dev_info structure. 153 * 154 * cmd: operation to perform 155 * 156 * arg: arg for the operation for result. 157 * 158 * tg_cookie cookie from target driver to be passed back to 159 * target driver when we call back to it through 160 * tg_ops. 161 * 162 * Possible commands and the interpretation of arg: 163 * 164 * cmd: 165 * TG_GETPHYGEOM 166 * Obtain raw physical geometry from target, 167 * and store in structure pointed to by arg, 168 * a cmlb_geom_t structure. 169 * 170 * TG_GETVIRTGEOM: 171 * Obtain HBA geometry for the target and 172 * store in struct pointed to by arg, 173 * a cmlb_geom_t structure. 174 * 175 * TG_GETCAPACITY: 176 * Report the capacity of the target (in system 177 * blocksize (DEV_BSIZE) and store in the 178 * space pointed to by arg, a diskaddr_t. 179 * 180 * TG_GETBLOCKSIZE: 181 * Report the block size of the target 182 * in the space pointed to by arg, a uint32_t. 183 * 184 * TG_GETATTR: 185 * Report the information requested on 186 * device/media and store in area pointed to by 187 * arg, a tg_attribute_t structure. 188 * Return values: 189 * 190 * Return values: 191 * 0 success 192 * 193 * EACCESS reservation conflict 194 * 195 * ENXIO internal error/invalid devi 196 * 197 * EINVAL When command is TG_GETPHYGEOM or 198 * TG_GETVIRTGEOM, or TG_GETATTR, this return code 199 * indicates the operation is not applicable to 200 * target. 201 * In case of TG_GETCAP, this return code 202 * indicates no media in the drive. 203 * 204 * EIO An error occurred during obtaining info 205 * from device/media. 206 * 207 * ENOTSUP In case of TG_GETCAP, target does not 208 * support getting capacity info. 209 * 210 * ENOTTY Unknown command. 211 * 212 * 213 */ 214 int (*tg_getinfo)(dev_info_t *devi, int cmd, void *arg, 215 void *tg_cookie); 216 217 } cmlb_tg_ops_t; 218 219 220 typedef struct __cmlb_handle *cmlb_handle_t; 221 222 /* 223 * 224 * Functions exported from cmlb 225 * 226 * Note: Most these functions can callback to target driver through the 227 * tg_ops functions. Target driver should consider this for synchronization. 228 * Any functions that may adjust minor nodes should be called when 229 * the target driver ensures it is safe to do so. 230 */ 231 232 /* 233 * cmlb_alloc_handle: 234 * 235 * Allocates a handle. 236 * 237 * Arguments: 238 * cmlbhandlep pointer to handle 239 * 240 * Notes: 241 * Allocates a handle and stores the allocated handle in the area 242 * pointed to by cmlbhandlep 243 * 244 * Context: 245 * Kernel thread only (can sleep). 246 */ 247 void 248 cmlb_alloc_handle(cmlb_handle_t *cmlbhandlep); 249 250 251 /* 252 * cmlb_attach: 253 * 254 * Attach handle to device, create minor nodes for device. 255 * 256 * 257 * Arguments: 258 * devi pointer to device's dev_info structure. 259 * tgopsp pointer to array of functions cmlb can use to callback 260 * to target driver. 261 * 262 * device_type Peripheral device type as defined in 263 * scsi/generic/inquiry.h 264 * 265 * is_removable whether or not device is removable. 266 * 267 * is_hotpluggable whether or not device is hotpluggable. 268 * 269 * node_type minor node type (as used by ddi_create_minor_node) 270 * 271 * alter_behavior 272 * bit flags: 273 * 274 * CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT: create 275 * an alternate slice for the default label, if 276 * device type is DTYPE_DIRECT an architectures default 277 * label type is VTOC16. 278 * Otherwise alternate slice will no be created. 279 * 280 * 281 * CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8: report a default 282 * geometry and label for DKIOCGGEOM and DKIOCGVTOC 283 * on architecture with VTOC 8 label types. 284 * 285 * CMLB_OFF_BY_ONE: do the workaround for legacy off-by- 286 * one bug in obtaining capacity (used for sd). 287 * 288 * 289 * cmlbhandle cmlb handle associated with device 290 * 291 * tg_cookie cookie from target driver to be passed back to target 292 * driver when we call back to it through tg_ops. 293 * 294 * cmlb does not interpret the values. It is currently 295 * used for sd to indicate whether retries are allowed 296 * on commands or not. e.g when cmlb entries are called 297 * from interrupt context on removable media, sd rather 298 * not have retries done. 299 * 300 * 301 * 302 * Notes: 303 * Assumes a default label based on capacity for non-removable devices. 304 * If capacity > 1TB, EFI is assumed otherwise VTOC (default VTOC 305 * for the architecture). 306 * For removable devices, default label type is assumed to be VTOC 307 * type. Create minor nodes based on a default label type. 308 * Label on the media is not validated. 309 * minor number consists of: 310 * if _SUNOS_VTOC_8 is defined 311 * lowest 3 bits is taken as partition number 312 * the rest is instance number 313 * if _SUNOS_VTOC_16 is defined 314 * lowest 6 bits is taken as partition number 315 * the rest is instance number 316 * 317 * 318 * Return values: 319 * 0 Success 320 * ENXIO creating minor nodes failed. 321 * EINVAL invalid arg, unsupported tg_ops version 322 * 323 */ 324 int 325 cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type, 326 boolean_t is_removable, boolean_t is_hotpluggable, char *node_type, 327 int alter_behavior, cmlb_handle_t cmlbhandle, void *tg_cookie); 328 329 330 /* 331 * cmlb_validate: 332 * 333 * Validates label. 334 * 335 * Arguments 336 * cmlbhandle cmlb handle associated with device. 337 * 338 * int flags 339 * currently used for verbosity control. 340 * CMLB_SILENT is the only current definition for it 341 * tg_cookie cookie from target driver to be passed back to target 342 * driver when we call back to it through tg_ops. 343 * Notes: 344 * If new label type is different from the current, adjust minor nodes 345 * accordingly. 346 * 347 * Return values: 348 * 0 success 349 * Note: having fdisk but no solaris partition is assumed 350 * success. 351 * 352 * ENOMEM memory allocation failed 353 * EIO i/o errors during read or get capacity 354 * EACCESS reservation conflicts 355 * EINVAL label was corrupt, or no default label was assumed 356 * ENXIO invalid handle 357 * 358 */ 359 int 360 cmlb_validate(cmlb_handle_t cmlbhandle, int flags, void *tg_cookie); 361 362 /* 363 * cmlb_invalidate: 364 * Invalidate in core label data 365 * 366 * Arguments: 367 * cmlbhandle cmlb handle associated with device. 368 * tg_cookie cookie from target driver to be passed back to target 369 * driver when we call back to it through tg_ops. 370 */ 371 void 372 cmlb_invalidate(cmlb_handle_t cmlbhandle, void *tg_cookie); 373 374 375 376 /* 377 * cmlb_is_valid 378 * Get status on whether the incore label/geom data is valid 379 * 380 * Arguments: 381 * cmlbhandle cmlb handle associated with device. 382 * 383 * Return values: 384 * TRUE if valid 385 * FALSE otherwise. 386 * 387 */ 388 boolean_t 389 cmlb_is_valid(cmlb_handle_t cmlbhandle); 390 391 /* 392 * cmlb_partinfo: 393 * Get partition info for specified partition number. 394 * 395 * Arguments: 396 * cmlbhandle cmlb handle associated with device. 397 * part partition number 398 * driver when we call back to it through tg_ops. 399 * nblocksp pointer to number of blocks 400 * startblockp pointer to starting block 401 * partnamep pointer to name of partition 402 * tagp pointer to tag info 403 * tg_cookie cookie from target driver to be passed back to target 404 * 405 * Notes: 406 * If in-core label is not valid, this functions tries to revalidate 407 * the label. If label is valid, it stores the total number of blocks 408 * in this partition in the area pointed to by nblocksp, starting 409 * block number in area pointed to by startblockp, pointer to partition 410 * name in area pointed to by partnamep, and tag value in area 411 * pointed by tagp. 412 * For EFI labels, tag value will be set to 0. 413 * 414 * For all nblocksp, startblockp and partnamep, tagp, a value of NULL 415 * indicates the corresponding info is not requested. 416 * 417 * 418 * Return values: 419 * 0 success 420 * EINVAL no valid label or requested partition number is invalid. 421 * 422 */ 423 int 424 cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp, 425 diskaddr_t *startblockp, char **partnamep, uint16_t *tagp, void *tg_cookie); 426 427 /* 428 * cmlb_efi_label_capacity: 429 * Get capacity stored in EFI disk label. 430 * 431 * Arguments: 432 * cmlbhandle cmlb handle associated with device. 433 * capacity pointer to capacity stored in EFI disk label. 434 * tg_cookie cookie from target driver to be passed back to target 435 * driver when we call back to it through tg_ops. 436 * 437 * 438 * Notes: 439 * If in-core label is not valid, this functions tries to revalidate 440 * the label. If label is valid and is an EFI label, it stores the capacity 441 * in disk label in the area pointed to by capacity. 442 * 443 * 444 * Return values: 445 * 0 success 446 * EINVAL no valid EFI label or capacity is NULL. 447 * 448 */ 449 int 450 cmlb_efi_label_capacity(cmlb_handle_t cmlbhandle, diskaddr_t *capacity, 451 void *tg_cookie); 452 453 /* 454 * cmlb_ioctl: 455 * Ioctls for label handling will be handled by this function. 456 * These are: 457 * DKIOCGGEOM 458 * DKIOCSGEOM 459 * DKIOCGAPART 460 * DKIOCSAPART 461 * DKIOCGVTOC 462 * DKIOCGETEFI 463 * DKIOCPARTITION 464 * DKIOCSVTOC 465 * DKIOCSETEFI 466 * DKIOCGMBOOT 467 * DKIOCSMBOOT 468 * DKIOCG_PHYGEOM 469 * DKIOCG_VIRTGEOM 470 * DKIOCPARTINFO 471 * 472 * 473 * Arguments: 474 * cmlbhandle handle associated with device. 475 * cmd ioctl operation to be performed 476 * arg user argument, contains data to be set or reference 477 * parameter for get 478 * flag bit flag, indicating open settings, 32/64 bit type 479 * cred_p user credential pointer (not currently used) 480 * rval_p not currently used 481 * tg_cookie cookie from target driver to be passed back to target 482 * driver when we call back to it through tg_ops. 483 * 484 * 485 * 486 * Return values: 487 * 0 488 * EINVAL 489 * ENOTTY 490 * ENXIO 491 * EIO 492 * EFAULT 493 * ENOTSUP 494 * EPERM 495 */ 496 int 497 cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, 498 intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie); 499 500 /* 501 * cmlb_prop_op: 502 * provide common label prop_op(9E) implementation that understands the 503 * size(9p) properties. 504 * 505 * Arguments: 506 * cmlbhandle cmlb handle associated with device. 507 * dev See prop_op(9E) 508 * dip " 509 * prop_op " 510 * mod_flags " 511 * name " 512 * valuep " 513 * lengthp " 514 * part partition number 515 * tg_cookie cookie from target driver to be passed back to target 516 */ 517 int 518 cmlb_prop_op(cmlb_handle_t cmlbhandle, 519 dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, 520 char *name, caddr_t valuep, int *lengthp, int part, void *tg_cookie); 521 522 /* 523 * cmlb_get_devid_block: 524 * get the block number where device id is stored. 525 * 526 * Arguments: 527 * cmlbhandle cmlb handle associated with device. 528 * devidblockp pointer to block number. 529 * tg_cookie cookie from target driver to be passed back to target 530 * driver when we call back to it through tg_ops. 531 * 532 * Notes: 533 * It stores the block number of device id in the area pointed to 534 * by devidblockp. 535 * 536 * Return values: 537 * 0 success 538 * EINVAL device id does not apply to current label type. 539 */ 540 int 541 cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp, 542 void *tg_cookie); 543 544 545 /* 546 * cmlb_close: 547 * 548 * Close the device, revert to a default label minor node for the device, 549 * if it is removable. 550 * 551 * Arguments: 552 * cmlbhandle cmlb handle associated with device. 553 * 554 * tg_cookie cookie from target driver to be passed back to target 555 * driver when we call back to it through tg_ops. 556 * Return values: 557 * 0 Success 558 * ENXIO Re-creating minor node failed. 559 */ 560 int 561 cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie); 562 563 /* 564 * cmlb_detach: 565 * 566 * Invalidate in-core labeling data and remove all minor nodes for 567 * the device associate with handle. 568 * 569 * Arguments: 570 * cmlbhandle cmlb handle associated with device. 571 * tg_cookie cookie from target driver to be passed back to target 572 * driver when we call back to it through tg_ops. 573 * 574 */ 575 void 576 cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie); 577 578 /* 579 * cmlb_free_handle 580 * 581 * Frees handle. 582 * 583 * Arguments: 584 * cmlbhandlep pointer to handle 585 * 586 */ 587 void 588 cmlb_free_handle(cmlb_handle_t *cmlbhandlep); 589 590 #ifdef __cplusplus 591 } 592 #endif 593 594 #endif /* _SYS_CMLB_H */ 595