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