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 occured 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 /* 414 * cmlb_ioctl: 415 * Ioctls for label handling will be handled by this function. 416 * These are: 417 * DKIOCGGEOM 418 * DKIOCSGEOM 419 * DKIOCGAPART 420 * DKIOCSAPART 421 * DKIOCGVTOC 422 * DKIOCGETEFI 423 * DKIOCPARTITION 424 * DKIOCSVTOC 425 * DKIOCSETEFI 426 * DKIOCGMBOOT 427 * DKIOCSMBOOT 428 * DKIOCG_PHYGEOM 429 * DKIOCG_VIRTGEOM 430 * DKIOCPARTINFO 431 * 432 * 433 * Arguments: 434 * cmlbhandle handle associated with device. 435 * cmd ioctl operation to be performed 436 * arg user argument, contains data to be set or reference 437 * parameter for get 438 * flag bit flag, indicating open settings, 32/64 bit type 439 * cred_p user credential pointer (not currently used) 440 * rval_p not currently used 441 * tg_cookie cookie from target driver to be passed back to target 442 * driver when we call back to it through tg_ops. 443 * 444 * 445 * 446 * Return values: 447 * 0 448 * EINVAL 449 * ENOTTY 450 * ENXIO 451 * EIO 452 * EFAULT 453 * ENOTSUP 454 * EPERM 455 */ 456 int 457 cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, 458 intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie); 459 460 /* 461 * cmlb_get_devid_block: 462 * get the block number where device id is stored. 463 * 464 * Arguments: 465 * cmlbhandle cmlb handle associated with device. 466 * devidblockp pointer to block number. 467 * tg_cookie cookie from target driver to be passed back to target 468 * driver when we call back to it through tg_ops. 469 * 470 * Notes: 471 * It stores the block number of device id in the area pointed to 472 * by devidblockp. 473 * 474 * Return values: 475 * 0 success 476 * EINVAL device id does not apply to current label type. 477 */ 478 int 479 cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp, 480 void *tg_cookie); 481 482 483 /* 484 * cmlb_close: 485 * 486 * Close the device, revert to a default label minor node for the device, 487 * if it is removable. 488 * 489 * Arguments: 490 * cmlbhandle cmlb handle associated with device. 491 * 492 * tg_cookie cookie from target driver to be passed back to target 493 * driver when we call back to it through tg_ops. 494 * Return values: 495 * 0 Success 496 * ENXIO Re-creating minor node failed. 497 */ 498 int 499 cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie); 500 501 /* 502 * cmlb_detach: 503 * 504 * Invalidate in-core labeling data and remove all minor nodes for 505 * the device associate with handle. 506 * 507 * Arguments: 508 * cmlbhandle cmlb handle associated with device. 509 * tg_cookie cookie from target driver to be passed back to target 510 * driver when we call back to it through tg_ops. 511 * 512 */ 513 void 514 cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie); 515 516 /* 517 * cmlb_free_handle 518 * 519 * Frees handle. 520 * 521 * Arguments: 522 * cmlbhandlep pointer to handle 523 * 524 */ 525 void 526 cmlb_free_handle(cmlb_handle_t *cmlbhandlep); 527 528 #ifdef __cplusplus 529 } 530 #endif 531 532 #endif /* _SYS_CMLB_H */ 533