1*3ccda647Slclee /* 2*3ccda647Slclee * CDDL HEADER START 3*3ccda647Slclee * 4*3ccda647Slclee * The contents of this file are subject to the terms of the 5*3ccda647Slclee * Common Development and Distribution License, Version 1.0 only 6*3ccda647Slclee * (the "License"). You may not use this file except in compliance 7*3ccda647Slclee * with the License. 8*3ccda647Slclee * 9*3ccda647Slclee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*3ccda647Slclee * or http://www.opensolaris.org/os/licensing. 11*3ccda647Slclee * See the License for the specific language governing permissions 12*3ccda647Slclee * and limitations under the License. 13*3ccda647Slclee * 14*3ccda647Slclee * When distributing Covered Code, include this CDDL HEADER in each 15*3ccda647Slclee * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*3ccda647Slclee * If applicable, add the following below this CDDL HEADER, with the 17*3ccda647Slclee * fields enclosed by brackets "[]" replaced with your own identifying 18*3ccda647Slclee * information: Portions Copyright [yyyy] [name of copyright owner] 19*3ccda647Slclee * 20*3ccda647Slclee * CDDL HEADER END 21*3ccda647Slclee */ 22*3ccda647Slclee /* 23*3ccda647Slclee * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*3ccda647Slclee * Use is subject to license terms. 25*3ccda647Slclee */ 26*3ccda647Slclee 27*3ccda647Slclee #ifndef _SYS_CMLB_H 28*3ccda647Slclee #define _SYS_CMLB_H 29*3ccda647Slclee 30*3ccda647Slclee #pragma ident "%Z%%M% %I% %E% SMI" 31*3ccda647Slclee 32*3ccda647Slclee #ifdef __cplusplus 33*3ccda647Slclee extern "C" { 34*3ccda647Slclee #endif 35*3ccda647Slclee 36*3ccda647Slclee #include <sys/dktp/fdisk.h> 37*3ccda647Slclee 38*3ccda647Slclee /* 39*3ccda647Slclee * structure used for getting phygeom and virtgeom from target driver 40*3ccda647Slclee */ 41*3ccda647Slclee typedef struct cmlb_geom { 42*3ccda647Slclee unsigned int g_ncyl; 43*3ccda647Slclee unsigned short g_acyl; 44*3ccda647Slclee unsigned short g_nhead; 45*3ccda647Slclee unsigned short g_nsect; 46*3ccda647Slclee unsigned short g_secsize; 47*3ccda647Slclee diskaddr_t g_capacity; 48*3ccda647Slclee unsigned short g_intrlv; 49*3ccda647Slclee unsigned short g_rpm; 50*3ccda647Slclee } cmlb_geom_t; 51*3ccda647Slclee 52*3ccda647Slclee 53*3ccda647Slclee typedef struct tg_attribute { 54*3ccda647Slclee int media_is_writable; 55*3ccda647Slclee } tg_attribute_t; 56*3ccda647Slclee 57*3ccda647Slclee #define TG_READ 0 58*3ccda647Slclee #define TG_WRITE 1 59*3ccda647Slclee 60*3ccda647Slclee #define TG_DK_OPS_VERSION_0 0x0 61*3ccda647Slclee 62*3ccda647Slclee /* flag definitions for alter_behavior arg on attach */ 63*3ccda647Slclee 64*3ccda647Slclee #define CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT 0x00000001 65*3ccda647Slclee #define CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8 0x00000002 66*3ccda647Slclee 67*3ccda647Slclee /* 68*3ccda647Slclee * Ops vector including utility functions into target driver that cmlb uses. 69*3ccda647Slclee */ 70*3ccda647Slclee typedef struct cmlb_tg_ops { 71*3ccda647Slclee int version; 72*3ccda647Slclee /* 73*3ccda647Slclee * tg_rdwr: 74*3ccda647Slclee * perform read/write on target device associated with devi. 75*3ccda647Slclee * Arguments: 76*3ccda647Slclee * devi: pointer to device's dev_info structure. 77*3ccda647Slclee * cmd: operation to perform. 78*3ccda647Slclee * Possible values: TG_READ, TG_WRITE 79*3ccda647Slclee * bufp: pointer to allocated buffer for transfer 80*3ccda647Slclee * start_block: starting block number to read/write (based on 81*3ccda647Slclee * system blocksize, DEV_BSIZE) 82*3ccda647Slclee * 83*3ccda647Slclee * reqlength: requested transfer length (in bytes) 84*3ccda647Slclee * 85*3ccda647Slclee * Note: It is the responsibility of caller to make sure 86*3ccda647Slclee * length of buffer pointed to by bufp is at least equal to 87*3ccda647Slclee * requested transfer length 88*3ccda647Slclee * 89*3ccda647Slclee * Return values: 90*3ccda647Slclee * 0 success 91*3ccda647Slclee * ENOMEM can not allocate memory 92*3ccda647Slclee * EACCESS reservation conflict 93*3ccda647Slclee * EIO I/O error 94*3ccda647Slclee * EFAULT copyin/copyout error 95*3ccda647Slclee * ENXIO internal error/ invalid devi 96*3ccda647Slclee * EINVAL invalid command value. 97*3ccda647Slclee */ 98*3ccda647Slclee int (*tg_rdwr)(dev_info_t *devi, uchar_t cmd, void *bufp, 99*3ccda647Slclee diskaddr_t start_block, size_t reqlength); 100*3ccda647Slclee 101*3ccda647Slclee /* 102*3ccda647Slclee * tg_getphygeom: 103*3ccda647Slclee * Obtain raw physical geometry from target, and store in structure 104*3ccda647Slclee * pointed to by phygeomp 105*3ccda647Slclee * 106*3ccda647Slclee * Arguments: 107*3ccda647Slclee * devi: pointer to device's dev_info structure. 108*3ccda647Slclee * phygeomp pointer to allocated structure for 109*3ccda647Slclee * physical geometry info. 110*3ccda647Slclee * Return values: 111*3ccda647Slclee * 0 success 112*3ccda647Slclee * EACCESS reservation conflict 113*3ccda647Slclee * EINVAL not applicable 114*3ccda647Slclee * EIO other errors occurred. 115*3ccda647Slclee * ENXIO internal error/ invalid devi 116*3ccda647Slclee */ 117*3ccda647Slclee int (*tg_getphygeom)(dev_info_t *devi, cmlb_geom_t *phygeomp); 118*3ccda647Slclee 119*3ccda647Slclee /* 120*3ccda647Slclee * tg_getvirtgeom: 121*3ccda647Slclee * obtain HBA geometry for the target and store in struct pointed 122*3ccda647Slclee * to by virtgeomp 123*3ccda647Slclee * Arguments: 124*3ccda647Slclee * devi: pointer to device's dev_info structure. 125*3ccda647Slclee * virtgeomp pointer to allocated structure for 126*3ccda647Slclee * virtual geometry info. 127*3ccda647Slclee * Return values: 128*3ccda647Slclee * 0 success 129*3ccda647Slclee * EACCESS reservation conflict 130*3ccda647Slclee * EINVAL not applicable or HBA does not provide info. 131*3ccda647Slclee * EIO other errors occured. 132*3ccda647Slclee * ENXIO internal error/ invalid devi 133*3ccda647Slclee * 134*3ccda647Slclee */ 135*3ccda647Slclee int (*tg_getvirtgeom)(dev_info_t *devi, cmlb_geom_t *virtgeomp); 136*3ccda647Slclee 137*3ccda647Slclee /* 138*3ccda647Slclee * tg_getcapacity 139*3ccda647Slclee * Report the capacity of the target (in system blocksize, 140*3ccda647Slclee * DEV_BSIZE) and store the value where capp is pointing to. 141*3ccda647Slclee * 142*3ccda647Slclee * Arguments: 143*3ccda647Slclee * devi: pointer to device's dev_info structure. 144*3ccda647Slclee * capp pointer to capacity value. 145*3ccda647Slclee * 146*3ccda647Slclee * Return values: 147*3ccda647Slclee * 0 success 148*3ccda647Slclee * EINVAL no media in drive 149*3ccda647Slclee * EIO error occured. 150*3ccda647Slclee * ENOTSUP target does not support getting capacity info. 151*3ccda647Slclee * EACCESS reservation conflict 152*3ccda647Slclee * ENXIO internal error/ invalid devi 153*3ccda647Slclee */ 154*3ccda647Slclee int (*tg_getcapacity)(dev_info_t *devi, diskaddr_t *capp); 155*3ccda647Slclee 156*3ccda647Slclee /* 157*3ccda647Slclee * tg_getattribute: 158*3ccda647Slclee * Report the information requested on device/media and 159*3ccda647Slclee * store in area pointed to by tgdevmediainfop 160*3ccda647Slclee * 161*3ccda647Slclee * Arguments: 162*3ccda647Slclee * devi: pointer to device's dev_info structure. 163*3ccda647Slclee * tgattribute pointer to area for attribute info 164*3ccda647Slclee * 165*3ccda647Slclee * Return values: 166*3ccda647Slclee * 0 success 167*3ccda647Slclee * EINVAL no media in drive 168*3ccda647Slclee * EIO error occured. 169*3ccda647Slclee * ENOTSUP target does not support getting capacity info. 170*3ccda647Slclee * EACCESS reservation conflict 171*3ccda647Slclee * 172*3ccda647Slclee * Return values: 173*3ccda647Slclee * ENXIO internal error/ invalid devi 174*3ccda647Slclee * EACCESS reservation conflict 175*3ccda647Slclee * EINVAL not applicable 176*3ccda647Slclee * EIO I/O failed 177*3ccda647Slclee */ 178*3ccda647Slclee int (*tg_getattribute)(dev_info_t *devi, tg_attribute_t 179*3ccda647Slclee *tgattribute); 180*3ccda647Slclee } cmlb_tg_ops_t; 181*3ccda647Slclee 182*3ccda647Slclee 183*3ccda647Slclee typedef struct __cmlb_handle *cmlb_handle_t; 184*3ccda647Slclee 185*3ccda647Slclee /* 186*3ccda647Slclee * 187*3ccda647Slclee * Functions exported from cmlb 188*3ccda647Slclee * 189*3ccda647Slclee * Note: Most these functions can callback to target driver through the 190*3ccda647Slclee * tg_ops functions. Target driver should consider this for synchronization. 191*3ccda647Slclee * Any functions that may adjust minor nodes should be called when 192*3ccda647Slclee * the target driver ensures it is safe to do so. 193*3ccda647Slclee */ 194*3ccda647Slclee 195*3ccda647Slclee /* 196*3ccda647Slclee * cmlb_alloc_handle: 197*3ccda647Slclee * 198*3ccda647Slclee * Allocates a handle. 199*3ccda647Slclee * 200*3ccda647Slclee * Arguments: 201*3ccda647Slclee * cmlbhandlep pointer to handle 202*3ccda647Slclee * 203*3ccda647Slclee * Notes: 204*3ccda647Slclee * Allocates a handle and stores the allocated handle in the area 205*3ccda647Slclee * pointed to by cmlbhandlep 206*3ccda647Slclee * 207*3ccda647Slclee * Context: 208*3ccda647Slclee * Kernel thread only (can sleep). 209*3ccda647Slclee */ 210*3ccda647Slclee void 211*3ccda647Slclee cmlb_alloc_handle(cmlb_handle_t *cmlbhandlep); 212*3ccda647Slclee 213*3ccda647Slclee 214*3ccda647Slclee /* 215*3ccda647Slclee * cmlb_attach: 216*3ccda647Slclee * 217*3ccda647Slclee * Attach handle to device, create minor nodes for device. 218*3ccda647Slclee * 219*3ccda647Slclee * 220*3ccda647Slclee * Arguments: 221*3ccda647Slclee * devi pointer to device's dev_info structure. 222*3ccda647Slclee * tgopsp pointer to array of functions cmlb can use to callback 223*3ccda647Slclee * to target driver. 224*3ccda647Slclee * 225*3ccda647Slclee * device_type Peripheral device type as defined in 226*3ccda647Slclee * scsi/generic/inquiry.h 227*3ccda647Slclee * 228*3ccda647Slclee * is_removable whether or not device is removable. 229*3ccda647Slclee * 0 non-removable, 1 removable. 230*3ccda647Slclee * 231*3ccda647Slclee * node_type minor node type (as used by ddi_create_minor_node) 232*3ccda647Slclee * 233*3ccda647Slclee * alter_behavior 234*3ccda647Slclee * bit flags: 235*3ccda647Slclee * 236*3ccda647Slclee * CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT: create 237*3ccda647Slclee * an alternate slice for the default label, if 238*3ccda647Slclee * device type is DTYPE_DIRECT an architectures default 239*3ccda647Slclee * label type is VTOC16. 240*3ccda647Slclee * Otherwise alternate slice will no be created. 241*3ccda647Slclee * 242*3ccda647Slclee * 243*3ccda647Slclee * CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8: report a default 244*3ccda647Slclee * geometry and label for DKIOCGGEOM and DKIOCGVTOC 245*3ccda647Slclee * on architecture with VTOC 8 label types. 246*3ccda647Slclee * 247*3ccda647Slclee * 248*3ccda647Slclee * cmlbhandle cmlb handle associated with device 249*3ccda647Slclee * 250*3ccda647Slclee * Notes: 251*3ccda647Slclee * Assumes a default label based on capacity for non-removable devices. 252*3ccda647Slclee * If capacity > 1TB, EFI is assumed otherwise VTOC (default VTOC 253*3ccda647Slclee * for the architecture). 254*3ccda647Slclee * For removable devices, default label type is assumed to be VTOC 255*3ccda647Slclee * type. Create minor nodes based on a default label type. 256*3ccda647Slclee * Label on the media is not validated. 257*3ccda647Slclee * minor number consists of: 258*3ccda647Slclee * if _SUNOS_VTOC_8 is defined 259*3ccda647Slclee * lowest 3 bits is taken as partition number 260*3ccda647Slclee * the rest is instance number 261*3ccda647Slclee * if _SUNOS_VTOC_16 is defined 262*3ccda647Slclee * lowest 6 bits is taken as partition number 263*3ccda647Slclee * the rest is instance number 264*3ccda647Slclee * 265*3ccda647Slclee * 266*3ccda647Slclee * Return values: 267*3ccda647Slclee * 0 Success 268*3ccda647Slclee * ENXIO creating minor nodes failed. 269*3ccda647Slclee * 270*3ccda647Slclee */ 271*3ccda647Slclee int 272*3ccda647Slclee cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type, 273*3ccda647Slclee int is_removable, char *node_type, int alter_behavior, cmlb_handle_t 274*3ccda647Slclee cmlbhandle); 275*3ccda647Slclee 276*3ccda647Slclee 277*3ccda647Slclee /* 278*3ccda647Slclee * cmlb_validate: 279*3ccda647Slclee * 280*3ccda647Slclee * Validates label. 281*3ccda647Slclee * 282*3ccda647Slclee * Arguments 283*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 284*3ccda647Slclee * 285*3ccda647Slclee * Notes: 286*3ccda647Slclee * If new label type is different from the current, adjust minor nodes 287*3ccda647Slclee * accordingly. 288*3ccda647Slclee * 289*3ccda647Slclee * Return values: 290*3ccda647Slclee * 0 success 291*3ccda647Slclee * Note: having fdisk but no solaris partition is assumed 292*3ccda647Slclee * success. 293*3ccda647Slclee * 294*3ccda647Slclee * ENOMEM memory allocation failed 295*3ccda647Slclee * EIO i/o errors during read or get capacity 296*3ccda647Slclee * EACCESS reservation conflicts 297*3ccda647Slclee * EINVAL label was corrupt, or no default label was assumed 298*3ccda647Slclee * ENXIO invalid handle 299*3ccda647Slclee * 300*3ccda647Slclee */ 301*3ccda647Slclee int 302*3ccda647Slclee cmlb_validate(cmlb_handle_t cmlbhandle); 303*3ccda647Slclee 304*3ccda647Slclee /* 305*3ccda647Slclee * cmlb_invalidate: 306*3ccda647Slclee * Invalidate in core label data 307*3ccda647Slclee * 308*3ccda647Slclee * Arguments: 309*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 310*3ccda647Slclee */ 311*3ccda647Slclee void 312*3ccda647Slclee cmlb_invalidate(cmlb_handle_t cmlbhandle); 313*3ccda647Slclee 314*3ccda647Slclee 315*3ccda647Slclee /* 316*3ccda647Slclee * cmlb_partinfo: 317*3ccda647Slclee * Get partition info for specified partition number. 318*3ccda647Slclee * 319*3ccda647Slclee * Arguments: 320*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 321*3ccda647Slclee * part partition number 322*3ccda647Slclee * nblocksp pointer to number of blocks 323*3ccda647Slclee * startblockp pointer to starting block 324*3ccda647Slclee * partnamep pointer to name of partition 325*3ccda647Slclee * tagp pointer to tag info 326*3ccda647Slclee * 327*3ccda647Slclee * 328*3ccda647Slclee * Notes: 329*3ccda647Slclee * If in-core label is not valid, this functions tries to revalidate 330*3ccda647Slclee * the label. If label is valid, it stores the total number of blocks 331*3ccda647Slclee * in this partition in the area pointed to by nblocksp, starting 332*3ccda647Slclee * block number in area pointed to by startblockp, pointer to partition 333*3ccda647Slclee * name in area pointed to by partnamep, and tag value in area 334*3ccda647Slclee * pointed by tagp. 335*3ccda647Slclee * For EFI labels, tag value will be set to 0. 336*3ccda647Slclee * 337*3ccda647Slclee * For all nblocksp, startblockp and partnamep, tagp, a value of NULL 338*3ccda647Slclee * indicates the corresponding info is not requested. 339*3ccda647Slclee * 340*3ccda647Slclee * 341*3ccda647Slclee * Return values: 342*3ccda647Slclee * 0 success 343*3ccda647Slclee * EINVAL no valid label or requested partition number is invalid. 344*3ccda647Slclee * 345*3ccda647Slclee */ 346*3ccda647Slclee int 347*3ccda647Slclee cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp, 348*3ccda647Slclee diskaddr_t *startblockp, char **partnamep, uint16_t *tagp); 349*3ccda647Slclee 350*3ccda647Slclee 351*3ccda647Slclee /* 352*3ccda647Slclee * cmlb_ioctl: 353*3ccda647Slclee * Ioctls for label handling will be handled by this function. 354*3ccda647Slclee * These are: 355*3ccda647Slclee * DKIOCGGEOM 356*3ccda647Slclee * DKIOCSGEOM 357*3ccda647Slclee * DKIOCGAPART 358*3ccda647Slclee * DKIOCSAPART 359*3ccda647Slclee * DKIOCGVTOC 360*3ccda647Slclee * DKIOCGETEFI 361*3ccda647Slclee * DKIOCPARTITION 362*3ccda647Slclee * DKIOCSVTOC 363*3ccda647Slclee * DKIOCSETEFI 364*3ccda647Slclee * DKIOCGMBOOT 365*3ccda647Slclee * DKIOCSMBOOT 366*3ccda647Slclee * DKIOCG_PHYGEOM 367*3ccda647Slclee * DKIOCG_VIRTGEOM 368*3ccda647Slclee * DKIOCPARTINFO 369*3ccda647Slclee * 370*3ccda647Slclee * 371*3ccda647Slclee * Arguments: 372*3ccda647Slclee * cmlbhandle handle associated with device. 373*3ccda647Slclee * cmd ioctl operation to be performed 374*3ccda647Slclee * arg user argument, contains data to be set or reference 375*3ccda647Slclee * parameter for get 376*3ccda647Slclee * flag bit flag, indicating open settings, 32/64 bit type 377*3ccda647Slclee * cred_p user credential pointer (not currently used) 378*3ccda647Slclee * rval_p not currently used 379*3ccda647Slclee * 380*3ccda647Slclee * 381*3ccda647Slclee * Return values: 382*3ccda647Slclee * 0 383*3ccda647Slclee * EINVAL 384*3ccda647Slclee * ENOTTY 385*3ccda647Slclee * ENXIO 386*3ccda647Slclee * EIO 387*3ccda647Slclee * EFAULT 388*3ccda647Slclee * ENOTSUP 389*3ccda647Slclee * EPERM 390*3ccda647Slclee */ 391*3ccda647Slclee int 392*3ccda647Slclee cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd, intptr_t arg, 393*3ccda647Slclee int flag, cred_t *cred_p, int *rval_p); 394*3ccda647Slclee 395*3ccda647Slclee /* 396*3ccda647Slclee * cmlb_get_devid_block: 397*3ccda647Slclee * get the block number where device id is stored. 398*3ccda647Slclee * 399*3ccda647Slclee * Arguments: 400*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 401*3ccda647Slclee * devidblockp pointer to block number. 402*3ccda647Slclee * 403*3ccda647Slclee * Notes: 404*3ccda647Slclee * It stores the block number of device id in the area pointed to 405*3ccda647Slclee * by devidblockp. 406*3ccda647Slclee * with the block number of device id. 407*3ccda647Slclee * 408*3ccda647Slclee * Return values: 409*3ccda647Slclee * 0 success 410*3ccda647Slclee * EINVAL device id does not apply to current label type. 411*3ccda647Slclee */ 412*3ccda647Slclee int 413*3ccda647Slclee cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp); 414*3ccda647Slclee 415*3ccda647Slclee 416*3ccda647Slclee /* 417*3ccda647Slclee * cmlb_close: 418*3ccda647Slclee * 419*3ccda647Slclee * Close the device, revert to a default label minor node for the device, 420*3ccda647Slclee * if it is removable. 421*3ccda647Slclee * 422*3ccda647Slclee * Arguments: 423*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 424*3ccda647Slclee * 425*3ccda647Slclee * Return values: 426*3ccda647Slclee * 0 Success 427*3ccda647Slclee * ENXIO Re-creating minor node failed. 428*3ccda647Slclee */ 429*3ccda647Slclee int 430*3ccda647Slclee cmlb_close(cmlb_handle_t cmlbhandle); 431*3ccda647Slclee 432*3ccda647Slclee /* 433*3ccda647Slclee * cmlb_detach: 434*3ccda647Slclee * 435*3ccda647Slclee * Invalidate in-core labeling data and remove all minor nodes for 436*3ccda647Slclee * the device associate with handle. 437*3ccda647Slclee * 438*3ccda647Slclee * Arguments: 439*3ccda647Slclee * cmlbhandle cmlb handle associated with device. 440*3ccda647Slclee * 441*3ccda647Slclee */ 442*3ccda647Slclee void 443*3ccda647Slclee cmlb_detach(cmlb_handle_t cmlbhandle); 444*3ccda647Slclee 445*3ccda647Slclee /* 446*3ccda647Slclee * cmlb_free_handle 447*3ccda647Slclee * 448*3ccda647Slclee * Frees handle. 449*3ccda647Slclee * 450*3ccda647Slclee * Arguments: 451*3ccda647Slclee * cmlbhandlep pointer to handle 452*3ccda647Slclee * 453*3ccda647Slclee */ 454*3ccda647Slclee void 455*3ccda647Slclee cmlb_free_handle(cmlb_handle_t *cmlbhandlep); 456*3ccda647Slclee 457*3ccda647Slclee #ifdef __cplusplus 458*3ccda647Slclee } 459*3ccda647Slclee #endif 460*3ccda647Slclee 461*3ccda647Slclee #endif /* _SYS_CMLB_H */ 462