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