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 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	"@(#)cmlb.h	1.3	07/09/18 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 
     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