xref: /illumos-gate/usr/src/uts/common/sys/cmlb.h (revision 92a0208178405fef708b0283ffcaa02fbc3468ff)
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 occurred 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  * cmlb_efi_label_capacity:
414  *	Get capacity stored in EFI disk label.
415  *
416  * Arguments:
417  *	cmlbhandle	cmlb handle associated with device.
418  *	capacity	pointer to capacity stored in EFI disk label.
419  *	tg_cookie	cookie from target driver to be passed back to target
420  *			driver when we call back to it through tg_ops.
421  *
422  *
423  * Notes:
424  *	If in-core label is not valid, this functions tries to revalidate
425  *	the label. If label is valid and is an EFI label, it stores the capacity
426  *      in disk label in the area pointed to by capacity.
427  *
428  *
429  * Return values:
430  *	0	success
431  *	EINVAL  no valid EFI label or capacity is NULL.
432  *
433  */
434 int
435 cmlb_efi_label_capacity(cmlb_handle_t cmlbhandle, diskaddr_t *capacity,
436     void *tg_cookie);
437 
438 /*
439  * cmlb_ioctl:
440  * Ioctls for label handling will be handled by this function.
441  * These are:
442  *	DKIOCGGEOM
443  *	DKIOCSGEOM
444  *	DKIOCGAPART
445  *	DKIOCSAPART
446  *	DKIOCGVTOC
447  *	DKIOCGETEFI
448  *	DKIOCPARTITION
449  *	DKIOCSVTOC
450  * 	DKIOCSETEFI
451  *	DKIOCGMBOOT
452  *	DKIOCSMBOOT
453  *	DKIOCG_PHYGEOM
454  *	DKIOCG_VIRTGEOM
455  *	DKIOCPARTINFO
456  *
457  *
458  *   Arguments:
459  *	cmlbhandle 	handle associated with device.
460  *      cmd     	ioctl operation to be performed
461  *      arg     	user argument, contains data to be set or reference
462  *                      parameter for get
463  *	flag    	bit flag, indicating open settings, 32/64 bit type
464  *      cred_p  	user credential pointer (not currently used)
465  *	rval_p  	not currently used
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  *
470  *
471  * Return values:
472  *	0
473  *	EINVAL
474  *	ENOTTY
475  *	ENXIO
476  *	EIO
477  *	EFAULT
478  *	ENOTSUP
479  *	EPERM
480  */
481 int
482 cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd,
483     intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie);
484 
485 /*
486  * cmlb_prop_op:
487  *	provide common label prop_op(9E) implementation that understands the
488  *	size(9p) properties.
489  *
490  * Arguments:
491  *	cmlbhandle	cmlb handle associated with device.
492  *	dev		See prop_op(9E)
493  *	dip		"
494  *	prop_op		"
495  *	mod_flags	"
496  *	name		"
497  *	valuep		"
498  *	lengthp		"
499  *	part		partition number
500  *	tg_cookie 	cookie from target driver to be passed back to target
501  */
502 int
503 cmlb_prop_op(cmlb_handle_t cmlbhandle,
504     dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
505     char *name, caddr_t valuep, int *lengthp, int part, void *tg_cookie);
506 
507 /*
508  * cmlb_get_devid_block:
509  *	 get the block number where device id is stored.
510  *
511  * Arguments:
512  *	cmlbhandle	cmlb handle associated with device.
513  *	devidblockp	pointer to block number.
514  *	tg_cookie 	cookie from target driver to be passed back to target
515  *			driver when we call back to it through tg_ops.
516  *
517  * Notes:
518  *	It stores the block number of device id in the area pointed to
519  *	by devidblockp.
520  *
521  * Return values:
522  *	0	success
523  *	EINVAL 	device id does not apply to current label type.
524  */
525 int
526 cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp,
527     void *tg_cookie);
528 
529 
530 /*
531  * cmlb_close:
532  *
533  * Close the device, revert to a default label minor node for the device,
534  * if it is removable.
535  *
536  * Arguments:
537  *	cmlbhandle	cmlb handle associated with device.
538  *
539  *	tg_cookie 	cookie from target driver to be passed back to target
540  *			driver when we call back to it through tg_ops.
541  * Return values:
542  *	0	Success
543  * 	ENXIO	Re-creating minor node failed.
544  */
545 int
546 cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie);
547 
548 /*
549  * cmlb_detach:
550  *
551  * Invalidate in-core labeling data and remove all minor nodes for
552  * the device associate with handle.
553  *
554  * Arguments:
555  *	cmlbhandle	cmlb handle associated with device.
556  *	tg_cookie 	cookie from target driver to be passed back to target
557  *			driver when we call back to it through tg_ops.
558  *
559  */
560 void
561 cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie);
562 
563 /*
564  * cmlb_free_handle
565  *
566  *	Frees handle.
567  *
568  * Arguments:
569  *	cmlbhandlep	pointer to handle
570  *
571  */
572 void
573 cmlb_free_handle(cmlb_handle_t *cmlbhandlep);
574 
575 #ifdef	__cplusplus
576 }
577 #endif
578 
579 #endif /* _SYS_CMLB_H */
580