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