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