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