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