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