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 2008 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 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 #include <sys/dktp/fdisk.h> 36 37 /* 38 * structure used for getting phygeom and virtgeom from target driver 39 */ 40 typedef struct cmlb_geom { 41 unsigned int g_ncyl; 42 unsigned short g_acyl; 43 unsigned short g_nhead; 44 unsigned short g_nsect; 45 unsigned short g_secsize; 46 diskaddr_t g_capacity; 47 unsigned short g_intrlv; 48 unsigned short g_rpm; 49 } cmlb_geom_t; 50 51 52 typedef struct tg_attribute { 53 int media_is_writable; 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 * 0 non-removable, 1 removable. 250 * 251 * is_hotpluggable whether or not device is hotpluggable. 252 * 0 non-hotpluggable, 1 hotpluggable. 253 * 254 * node_type minor node type (as used by ddi_create_minor_node) 255 * 256 * alter_behavior 257 * bit flags: 258 * 259 * CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT: create 260 * an alternate slice for the default label, if 261 * device type is DTYPE_DIRECT an architectures default 262 * label type is VTOC16. 263 * Otherwise alternate slice will no be created. 264 * 265 * 266 * CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8: report a default 267 * geometry and label for DKIOCGGEOM and DKIOCGVTOC 268 * on architecture with VTOC 8 label types. 269 * 270 * CMLB_OFF_BY_ONE: do the workaround for legacy off-by- 271 * one bug in obtaining capacity (used for sd). 272 * 273 * 274 * cmlbhandle cmlb handle associated with device 275 * 276 * tg_cookie cookie from target driver to be passed back to target 277 * driver when we call back to it through tg_ops. 278 * 279 * cmlb does not interpret the values. It is currently 280 * used for sd to indicate whether retries are allowed 281 * on commands or not. e.g when cmlb entries are called 282 * from interrupt context on removable media, sd rather 283 * not have retries done. 284 * 285 * 286 * 287 * Notes: 288 * Assumes a default label based on capacity for non-removable devices. 289 * If capacity > 1TB, EFI is assumed otherwise VTOC (default VTOC 290 * for the architecture). 291 * For removable devices, default label type is assumed to be VTOC 292 * type. Create minor nodes based on a default label type. 293 * Label on the media is not validated. 294 * minor number consists of: 295 * if _SUNOS_VTOC_8 is defined 296 * lowest 3 bits is taken as partition number 297 * the rest is instance number 298 * if _SUNOS_VTOC_16 is defined 299 * lowest 6 bits is taken as partition number 300 * the rest is instance number 301 * 302 * 303 * Return values: 304 * 0 Success 305 * ENXIO creating minor nodes failed. 306 * EINVAL invalid arg, unsupported tg_ops version 307 * 308 */ 309 int 310 cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type, 311 int is_removable, int is_hotpluggable, char *node_type, 312 int alter_behavior, cmlb_handle_t cmlbhandle, void *tg_cookie); 313 314 315 /* 316 * cmlb_validate: 317 * 318 * Validates label. 319 * 320 * Arguments 321 * cmlbhandle cmlb handle associated with device. 322 * 323 * int flags 324 * currently used for verbosity control. 325 * CMLB_SILENT is the only current definition for it 326 * tg_cookie cookie from target driver to be passed back to target 327 * driver when we call back to it through tg_ops. 328 * Notes: 329 * If new label type is different from the current, adjust minor nodes 330 * accordingly. 331 * 332 * Return values: 333 * 0 success 334 * Note: having fdisk but no solaris partition is assumed 335 * success. 336 * 337 * ENOMEM memory allocation failed 338 * EIO i/o errors during read or get capacity 339 * EACCESS reservation conflicts 340 * EINVAL label was corrupt, or no default label was assumed 341 * ENXIO invalid handle 342 * 343 */ 344 int 345 cmlb_validate(cmlb_handle_t cmlbhandle, int flags, void *tg_cookie); 346 347 /* 348 * cmlb_invalidate: 349 * Invalidate in core label data 350 * 351 * Arguments: 352 * cmlbhandle cmlb handle associated with device. 353 * tg_cookie cookie from target driver to be passed back to target 354 * driver when we call back to it through tg_ops. 355 */ 356 void 357 cmlb_invalidate(cmlb_handle_t cmlbhandle, void *tg_cookie); 358 359 360 361 /* 362 * cmlb_is_valid 363 * Get status on whether the incore label/geom data is valid 364 * 365 * Arguments: 366 * cmlbhandle cmlb handle associated with device. 367 * 368 * Return values: 369 * TRUE if valid 370 * FALSE otherwise. 371 * 372 */ 373 int 374 cmlb_is_valid(cmlb_handle_t cmlbhandle); 375 376 /* 377 * cmlb_partinfo: 378 * Get partition info for specified partition number. 379 * 380 * Arguments: 381 * cmlbhandle cmlb handle associated with device. 382 * part partition number 383 * driver when we call back to it through tg_ops. 384 * nblocksp pointer to number of blocks 385 * startblockp pointer to starting block 386 * partnamep pointer to name of partition 387 * tagp pointer to tag info 388 * tg_cookie cookie from target driver to be passed back to target 389 * 390 * Notes: 391 * If in-core label is not valid, this functions tries to revalidate 392 * the label. If label is valid, it stores the total number of blocks 393 * in this partition in the area pointed to by nblocksp, starting 394 * block number in area pointed to by startblockp, pointer to partition 395 * name in area pointed to by partnamep, and tag value in area 396 * pointed by tagp. 397 * For EFI labels, tag value will be set to 0. 398 * 399 * For all nblocksp, startblockp and partnamep, tagp, a value of NULL 400 * indicates the corresponding info is not requested. 401 * 402 * 403 * Return values: 404 * 0 success 405 * EINVAL no valid label or requested partition number is invalid. 406 * 407 */ 408 int 409 cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp, 410 diskaddr_t *startblockp, char **partnamep, uint16_t *tagp, void *tg_cookie); 411 412 /* 413 * cmlb_efi_label_capacity: 414 * Get capacity stored in EFI disk label. 415 * 416 * Arguments: 417 * cmlbhandle cmlb handle associated with device. 418 * capacity pointer to capacity stored in EFI disk label. 419 * tg_cookie cookie from target driver to be passed back to target 420 * driver when we call back to it through tg_ops. 421 * 422 * 423 * Notes: 424 * If in-core label is not valid, this functions tries to revalidate 425 * the label. If label is valid and is an EFI label, it stores the capacity 426 * in disk label in the area pointed to by capacity. 427 * 428 * 429 * Return values: 430 * 0 success 431 * EINVAL no valid EFI label or capacity is NULL. 432 * 433 */ 434 int 435 cmlb_efi_label_capacity(cmlb_handle_t cmlbhandle, diskaddr_t *capacity, 436 void *tg_cookie); 437 438 /* 439 * cmlb_ioctl: 440 * Ioctls for label handling will be handled by this function. 441 * These are: 442 * DKIOCGGEOM 443 * DKIOCSGEOM 444 * DKIOCGAPART 445 * DKIOCSAPART 446 * DKIOCGVTOC 447 * DKIOCGETEFI 448 * DKIOCPARTITION 449 * DKIOCSVTOC 450 * DKIOCSETEFI 451 * DKIOCGMBOOT 452 * DKIOCSMBOOT 453 * DKIOCG_PHYGEOM 454 * DKIOCG_VIRTGEOM 455 * DKIOCPARTINFO 456 * 457 * 458 * Arguments: 459 * cmlbhandle handle associated with device. 460 * cmd ioctl operation to be performed 461 * arg user argument, contains data to be set or reference 462 * parameter for get 463 * flag bit flag, indicating open settings, 32/64 bit type 464 * cred_p user credential pointer (not currently used) 465 * rval_p not currently used 466 * tg_cookie cookie from target driver to be passed back to target 467 * driver when we call back to it through tg_ops. 468 * 469 * 470 * 471 * Return values: 472 * 0 473 * EINVAL 474 * ENOTTY 475 * ENXIO 476 * EIO 477 * EFAULT 478 * ENOTSUP 479 * EPERM 480 */ 481 int 482 cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, 483 intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie); 484 485 /* 486 * cmlb_prop_op: 487 * provide common label prop_op(9E) implementation that understands the 488 * size(9p) properties. 489 * 490 * Arguments: 491 * cmlbhandle cmlb handle associated with device. 492 * dev See prop_op(9E) 493 * dip " 494 * prop_op " 495 * mod_flags " 496 * name " 497 * valuep " 498 * lengthp " 499 * part partition number 500 * tg_cookie cookie from target driver to be passed back to target 501 */ 502 int 503 cmlb_prop_op(cmlb_handle_t cmlbhandle, 504 dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags, 505 char *name, caddr_t valuep, int *lengthp, int part, void *tg_cookie); 506 507 /* 508 * cmlb_get_devid_block: 509 * get the block number where device id is stored. 510 * 511 * Arguments: 512 * cmlbhandle cmlb handle associated with device. 513 * devidblockp pointer to block number. 514 * tg_cookie cookie from target driver to be passed back to target 515 * driver when we call back to it through tg_ops. 516 * 517 * Notes: 518 * It stores the block number of device id in the area pointed to 519 * by devidblockp. 520 * 521 * Return values: 522 * 0 success 523 * EINVAL device id does not apply to current label type. 524 */ 525 int 526 cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp, 527 void *tg_cookie); 528 529 530 /* 531 * cmlb_close: 532 * 533 * Close the device, revert to a default label minor node for the device, 534 * if it is removable. 535 * 536 * Arguments: 537 * cmlbhandle cmlb handle associated with device. 538 * 539 * tg_cookie cookie from target driver to be passed back to target 540 * driver when we call back to it through tg_ops. 541 * Return values: 542 * 0 Success 543 * ENXIO Re-creating minor node failed. 544 */ 545 int 546 cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie); 547 548 /* 549 * cmlb_detach: 550 * 551 * Invalidate in-core labeling data and remove all minor nodes for 552 * the device associate with handle. 553 * 554 * Arguments: 555 * cmlbhandle cmlb handle associated with device. 556 * tg_cookie cookie from target driver to be passed back to target 557 * driver when we call back to it through tg_ops. 558 * 559 */ 560 void 561 cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie); 562 563 /* 564 * cmlb_free_handle 565 * 566 * Frees handle. 567 * 568 * Arguments: 569 * cmlbhandlep pointer to handle 570 * 571 */ 572 void 573 cmlb_free_handle(cmlb_handle_t *cmlbhandlep); 574 575 #ifdef __cplusplus 576 } 577 #endif 578 579 #endif /* _SYS_CMLB_H */ 580