xref: /illumos-gate/usr/src/uts/common/sys/cmlb.h (revision 56e2cc86321ec889bf83a888d902c60d6fb2ef8d)
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 } tg_attribute_t;
53 
54 
55 
56 /* bit definitions for alter_behavior passed to cmlb_attach */
57 
58 #define	CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT	0x00000001
59 #define	CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8		0x00000002
60 #define	CMLB_OFF_BY_ONE					0x00000004
61 #define	CMLB_FAKE_LABEL_ONE_PARTITION			0x00000008
62 #define	CMLB_INTERNAL_MINOR_NODES			0x00000010
63 
64 /* bit definitions of flag passed to cmlb_validate */
65 #define	CMLB_SILENT					0x00000001
66 
67 /* version for tg_ops */
68 #define	TG_DK_OPS_VERSION_0	0
69 #define	TG_DK_OPS_VERSION_1	1
70 
71 /* definitions for cmd passed to tg_rdwr */
72 #define	TG_READ			0
73 #define	TG_WRITE		1
74 
75 /* definitions for cmd passed to tg_getinfo */
76 #define	TG_GETPHYGEOM		1
77 #define	TG_GETVIRTGEOM		2
78 #define	TG_GETCAPACITY		3
79 #define	TG_GETBLOCKSIZE		4
80 #define	TG_GETATTR		5
81 
82 
83 /*
84  * Ops vector including utility functions into target driver that cmlb uses.
85  */
86 typedef struct cmlb_tg_ops {
87 	int	tg_version;
88 
89 	/*
90 	 * tg_rdwr:
91 	 *	perform read/write on target device associated with devi.
92 	 *
93 	 * Arguments:
94 	 *
95 	 *	devi:		pointer to device's dev_info structure.
96 	 *
97 	 *	cmd:		operation to perform.
98 	 *			Possible values: TG_READ, TG_WRITE
99 	 *
100 	 *	bufp:		pointer to allocated buffer for transfer
101 	 *
102 	 *	start_block:	starting block number to read/write (based on
103 	 *			system blocksize, DEV_BSIZE)
104 	 *
105 	 *	reqlength:	requested transfer length (in bytes)
106 	 *
107 	 *	tg_cookie 	cookie from target driver to be passed back to
108 	 *			target driver when we call back to it through
109 	 *			tg_ops.
110 	 *
111 	 * Note: It is the responsibility of caller to make sure
112 	 *	length of buffer pointed to by bufp is at least equal to
113 	 *	requested transfer length
114 	 *
115 	 * Return values:
116 	 *	0		success
117 	 *	ENOMEM		can not allocate memory
118 	 *	EACCESS  	reservation conflict
119 	 *	EIO		I/O error
120 	 *	EFAULT		copyin/copyout error
121 	 *	ENXIO		internal error/ invalid devi
122 	 *	EINVAL		invalid command value.
123 	 */
124 	int (*tg_rdwr)(dev_info_t *devi, uchar_t cmd, void *bufp,
125 	    diskaddr_t start_block, size_t reqlength, void *tg_cookie);
126 
127 	/*
128 	 * tg_getinfo:
129 	 * 	Report the information requested on device/media and
130 	 *	store the requested info in area pointed to by arg.
131 	 *
132 	 * Arguments:
133 	 *	devi:		pointer to device's dev_info structure.
134 	 *
135 	 *	cmd:		operation to perform
136 	 *
137 	 *	arg:		arg for the operation for result.
138 	 *
139 	 *	tg_cookie 	cookie from target driver to be passed back to
140 	 *			target driver when we call back to it through
141 	 *			tg_ops.
142 	 *
143 	 * 	Possible commands and the interpretation of arg:
144 	 *
145 	 *	cmd:
146 	 *		TG_GETPHYGEOM
147 	 *			Obtain raw physical geometry from target,
148 	 *			and store in structure pointed to by arg,
149 	 *			a cmlb_geom_t structure.
150 	 *
151 	 * 		TG_GETVIRTGEOM:
152 	 *			Obtain HBA geometry for the target and
153 	 *			store in struct pointed to by arg,
154 	 *			a cmlb_geom_t structure.
155 	 *
156 	 *		TG_GETCAPACITY:
157 	 *			Report the capacity of the target (in system
158 	 *			blocksize (DEV_BSIZE) and store in the
159 	 *			space pointed to by arg, a diskaddr_t.
160 	 *
161 	 *		TG_GETBLOCKSIZE:
162 	 *			Report the block size of the target
163 	 *			in the space pointed to by arg, a uint32_t.
164 	 *
165 	 *		TG_GETATTR:
166 	 * 			Report the information requested on
167 	 *			device/media and store in area pointed to by
168 	 *			arg, a tg_attribute_t structure.
169 	 *			Return values:
170 	 *
171 	 * Return values:
172 	 *	0		success
173 	 *
174 	 *	EACCESS		reservation conflict
175 	 *
176 	 *	ENXIO		internal error/invalid devi
177 	 *
178 	 *	EINVAL		When command is TG_GETPHYGEOM or
179 	 *			TG_GETVIRTGEOM, or TG_GETATTR, this return code
180 	 *			indicates the operation is not applicable to
181 	 *			target.
182 	 *			In case of TG_GETCAP, this return code
183 	 *			indicates no media in the drive.
184 	 *
185 	 *	EIO		An error occurred during obtaining info
186 	 *			from device/media.
187 	 *
188 	 *	ENOTSUP		In case of TG_GETCAP, target does not
189 	 *			support getting capacity info.
190 	 *
191 	 *	ENOTTY		Unknown command.
192 	 *
193 	 *
194 	 */
195 	int (*tg_getinfo)(dev_info_t *devi, int cmd, void *arg,
196 	    void *tg_cookie);
197 
198 } cmlb_tg_ops_t;
199 
200 
201 typedef struct __cmlb_handle *cmlb_handle_t;
202 
203 /*
204  *
205  * Functions exported from cmlb
206  *
207  * Note: Most these functions can callback to target driver through the
208  * tg_ops functions. Target driver should consider this for synchronization.
209  * Any functions that may adjust minor nodes should be called when
210  * the target driver ensures it is safe to do so.
211  */
212 
213 /*
214  * cmlb_alloc_handle:
215  *
216  *	Allocates a handle.
217  *
218  * Arguments:
219  *	cmlbhandlep	pointer to handle
220  *
221  * Notes:
222  *	Allocates a handle and stores the allocated handle in the area
223  *	pointed to by cmlbhandlep
224  *
225  * Context:
226  *	Kernel thread only (can sleep).
227  */
228 void
229 cmlb_alloc_handle(cmlb_handle_t *cmlbhandlep);
230 
231 
232 /*
233  * cmlb_attach:
234  *
235  *	Attach handle to device, create minor nodes for device.
236  *
237  *
238  * Arguments:
239  * 	devi		pointer to device's dev_info structure.
240  * 	tgopsp		pointer to array of functions cmlb can use to callback
241  *			to target driver.
242  *
243  *	device_type	Peripheral device type as defined in
244  *			scsi/generic/inquiry.h
245  *
246  *	is_removable	whether or not device is removable.
247  *
248  *	is_hotpluggable	whether or not device is hotpluggable.
249  *
250  *	node_type	minor node type (as used by ddi_create_minor_node)
251  *
252  *	alter_behavior
253  *			bit flags:
254  *
255  *			CMLB_CREATE_ALTSLICE_VTOC_16_DTYPE_DIRECT: create
256  *			an alternate slice for the default label, if
257  *			device type is DTYPE_DIRECT an architectures default
258  *			label type is VTOC16.
259  *			Otherwise alternate slice will no be created.
260  *
261  *
262  *			CMLB_FAKE_GEOM_LABEL_IOCTLS_VTOC8: report a default
263  *			geometry and label for DKIOCGGEOM and DKIOCGVTOC
264  *			on architecture with VTOC 8 label types.
265  *
266  * 			CMLB_OFF_BY_ONE: do the workaround for legacy off-by-
267  *			one bug in obtaining capacity (used for sd).
268  *
269  *
270  *	cmlbhandle	cmlb handle associated with device
271  *
272  *	tg_cookie 	cookie from target driver to be passed back to target
273  *			driver when we call back to it through tg_ops.
274  *
275  *			cmlb does not interpret the values. It is currently
276  *			used for sd to indicate whether retries are allowed
277  *			on commands or not. e.g when cmlb entries are called
278  *			from interrupt context on removable media, sd rather
279  *			not have retries done.
280  *
281  *
282  *
283  * Notes:
284  *	Assumes a default label based on capacity for non-removable devices.
285  *	If capacity > 1TB, EFI is assumed otherwise VTOC (default VTOC
286  *	for the architecture).
287  *	For removable devices, default label type is assumed to be VTOC
288  *	type. Create minor nodes based on a default label type.
289  *	Label on the media is not validated.
290  *	minor number consists of:
291  *		if _SUNOS_VTOC_8 is defined
292  *			lowest 3 bits is taken as partition number
293  *			the rest is instance number
294  *		if _SUNOS_VTOC_16 is defined
295  *			lowest 6 bits is taken as partition number
296  *			the rest is instance number
297  *
298  *
299  * Return values:
300  *	0 	Success
301  * 	ENXIO 	creating minor nodes failed.
302  *	EINVAL	invalid arg, unsupported tg_ops version
303  *
304  */
305 int
306 cmlb_attach(dev_info_t *devi, cmlb_tg_ops_t *tgopsp, int device_type,
307     boolean_t is_removable, boolean_t is_hotpluggable, char *node_type,
308     int alter_behavior, cmlb_handle_t cmlbhandle, void *tg_cookie);
309 
310 
311 /*
312  * cmlb_validate:
313  *
314  *	Validates label.
315  *
316  * Arguments
317  *	cmlbhandle	cmlb handle associated with device.
318  *
319  * 	int 		flags
320  *			currently used for verbosity control.
321  *			CMLB_SILENT is the only current definition for it
322  *	tg_cookie 	cookie from target driver to be passed back to target
323  *			driver when we call back to it through tg_ops.
324  * Notes:
325  *	If new label type is different from the current, adjust minor nodes
326  *	accordingly.
327  *
328  * Return values:
329  *	0		success
330  *			Note: having fdisk but no solaris partition is assumed
331  *			success.
332  *
333  *	ENOMEM		memory allocation failed
334  *	EIO		i/o errors during read or get capacity
335  * 	EACCESS		reservation conflicts
336  * 	EINVAL		label was corrupt, or no default label was assumed
337  *	ENXIO		invalid handle
338  *
339  */
340 int
341 cmlb_validate(cmlb_handle_t cmlbhandle, int flags, void *tg_cookie);
342 
343 /*
344  * cmlb_invalidate:
345  *	Invalidate in core label data
346  *
347  * Arguments:
348  *	cmlbhandle	cmlb handle associated with device.
349  *	tg_cookie 	cookie from target driver to be passed back to target
350  *			driver when we call back to it through tg_ops.
351  */
352 void
353 cmlb_invalidate(cmlb_handle_t cmlbhandle, void *tg_cookie);
354 
355 
356 
357 /*
358  * cmlb_is_valid
359  *	 Get status on whether the incore label/geom data is valid
360  *
361  * Arguments:
362  *      cmlbhandle      cmlb handle associated with device.
363  *
364  * Return values:
365  *      TRUE if valid
366  *      FALSE otherwise.
367  *
368  */
369 boolean_t
370 cmlb_is_valid(cmlb_handle_t cmlbhandle);
371 
372 /*
373  * cmlb_partinfo:
374  *	Get partition info for specified partition number.
375  *
376  * Arguments:
377  *	cmlbhandle	cmlb handle associated with device.
378  *	part		partition number
379  *			driver when we call back to it through tg_ops.
380  *	nblocksp	pointer to number of blocks
381  *	startblockp	pointer to starting block
382  *	partnamep	pointer to name of partition
383  *	tagp		pointer to tag info
384  *	tg_cookie 	cookie from target driver to be passed back to target
385  *
386  * Notes:
387  *	If in-core label is not valid, this functions tries to revalidate
388  *	the label. If label is valid, it stores the total number of blocks
389  *	in this partition in the area pointed to by nblocksp, starting
390  *	block number in area pointed to by startblockp,  pointer to partition
391  *	name in area pointed to by partnamep, and tag value in area
392  *	pointed by tagp.
393  *	For EFI labels, tag value will be set to 0.
394  *
395  *	For all nblocksp, startblockp and partnamep, tagp, a value of NULL
396  *	indicates the corresponding info is not requested.
397  *
398  *
399  * Return values:
400  *	0	success
401  *	EINVAL  no valid label or requested partition number is invalid.
402  *
403  */
404 int
405 cmlb_partinfo(cmlb_handle_t cmlbhandle, int part, diskaddr_t *nblocksp,
406     diskaddr_t *startblockp, char **partnamep, uint16_t *tagp, void *tg_cookie);
407 
408 /*
409  * cmlb_efi_label_capacity:
410  *	Get capacity stored in EFI disk label.
411  *
412  * Arguments:
413  *	cmlbhandle	cmlb handle associated with device.
414  *	capacity	pointer to capacity stored in EFI disk label.
415  *	tg_cookie	cookie from target driver to be passed back to target
416  *			driver when we call back to it through tg_ops.
417  *
418  *
419  * Notes:
420  *	If in-core label is not valid, this functions tries to revalidate
421  *	the label. If label is valid and is an EFI label, it stores the capacity
422  *      in disk label in the area pointed to by capacity.
423  *
424  *
425  * Return values:
426  *	0	success
427  *	EINVAL  no valid EFI label or capacity is NULL.
428  *
429  */
430 int
431 cmlb_efi_label_capacity(cmlb_handle_t cmlbhandle, diskaddr_t *capacity,
432     void *tg_cookie);
433 
434 /*
435  * cmlb_ioctl:
436  * Ioctls for label handling will be handled by this function.
437  * These are:
438  *	DKIOCGGEOM
439  *	DKIOCSGEOM
440  *	DKIOCGAPART
441  *	DKIOCSAPART
442  *	DKIOCGVTOC
443  *	DKIOCGETEFI
444  *	DKIOCPARTITION
445  *	DKIOCSVTOC
446  * 	DKIOCSETEFI
447  *	DKIOCGMBOOT
448  *	DKIOCSMBOOT
449  *	DKIOCG_PHYGEOM
450  *	DKIOCG_VIRTGEOM
451  *	DKIOCPARTINFO
452  *
453  *
454  *   Arguments:
455  *	cmlbhandle 	handle associated with device.
456  *      cmd     	ioctl operation to be performed
457  *      arg     	user argument, contains data to be set or reference
458  *                      parameter for get
459  *	flag    	bit flag, indicating open settings, 32/64 bit type
460  *      cred_p  	user credential pointer (not currently used)
461  *	rval_p  	not currently used
462  *	tg_cookie 	cookie from target driver to be passed back to target
463  *			driver when we call back to it through tg_ops.
464  *
465  *
466  *
467  * Return values:
468  *	0
469  *	EINVAL
470  *	ENOTTY
471  *	ENXIO
472  *	EIO
473  *	EFAULT
474  *	ENOTSUP
475  *	EPERM
476  */
477 int
478 cmlb_ioctl(cmlb_handle_t cmlbhandle, dev_t dev, int cmd,
479     intptr_t arg, int flag, cred_t *cred_p, int *rval_p, void *tg_cookie);
480 
481 /*
482  * cmlb_prop_op:
483  *	provide common label prop_op(9E) implementation that understands the
484  *	size(9p) properties.
485  *
486  * Arguments:
487  *	cmlbhandle	cmlb handle associated with device.
488  *	dev		See prop_op(9E)
489  *	dip		"
490  *	prop_op		"
491  *	mod_flags	"
492  *	name		"
493  *	valuep		"
494  *	lengthp		"
495  *	part		partition number
496  *	tg_cookie 	cookie from target driver to be passed back to target
497  */
498 int
499 cmlb_prop_op(cmlb_handle_t cmlbhandle,
500     dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, int mod_flags,
501     char *name, caddr_t valuep, int *lengthp, int part, void *tg_cookie);
502 
503 /*
504  * cmlb_get_devid_block:
505  *	 get the block number where device id is stored.
506  *
507  * Arguments:
508  *	cmlbhandle	cmlb handle associated with device.
509  *	devidblockp	pointer to block number.
510  *	tg_cookie 	cookie from target driver to be passed back to target
511  *			driver when we call back to it through tg_ops.
512  *
513  * Notes:
514  *	It stores the block number of device id in the area pointed to
515  *	by devidblockp.
516  *
517  * Return values:
518  *	0	success
519  *	EINVAL 	device id does not apply to current label type.
520  */
521 int
522 cmlb_get_devid_block(cmlb_handle_t cmlbhandle, diskaddr_t *devidblockp,
523     void *tg_cookie);
524 
525 
526 /*
527  * cmlb_close:
528  *
529  * Close the device, revert to a default label minor node for the device,
530  * if it is removable.
531  *
532  * Arguments:
533  *	cmlbhandle	cmlb handle associated with device.
534  *
535  *	tg_cookie 	cookie from target driver to be passed back to target
536  *			driver when we call back to it through tg_ops.
537  * Return values:
538  *	0	Success
539  * 	ENXIO	Re-creating minor node failed.
540  */
541 int
542 cmlb_close(cmlb_handle_t cmlbhandle, void *tg_cookie);
543 
544 /*
545  * cmlb_detach:
546  *
547  * Invalidate in-core labeling data and remove all minor nodes for
548  * the device associate with handle.
549  *
550  * Arguments:
551  *	cmlbhandle	cmlb handle associated with device.
552  *	tg_cookie 	cookie from target driver to be passed back to target
553  *			driver when we call back to it through tg_ops.
554  *
555  */
556 void
557 cmlb_detach(cmlb_handle_t cmlbhandle, void *tg_cookie);
558 
559 /*
560  * cmlb_free_handle
561  *
562  *	Frees handle.
563  *
564  * Arguments:
565  *	cmlbhandlep	pointer to handle
566  *
567  */
568 void
569 cmlb_free_handle(cmlb_handle_t *cmlbhandlep);
570 
571 #ifdef	__cplusplus
572 }
573 #endif
574 
575 #endif /* _SYS_CMLB_H */
576