xref: /illumos-gate/usr/src/uts/sun4v/sys/vdsk_common.h (revision 1979231e)
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 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #ifndef	_VDSK_COMMON_H
28 #define	_VDSK_COMMON_H
29 
30 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 /*
37  * This header file contains the private LDoms Virtual Disk (vDisk) definitions
38  * common to both the server (vds) and the client (vdc)
39  */
40 
41 #include <sys/machparam.h>
42 #include <sys/vtoc.h>
43 
44 #include <sys/ldc.h>
45 #include <sys/vio_common.h>
46 #include <sys/vio_mailbox.h>
47 
48 /*
49  * vDisk definitions
50  */
51 
52 /*
53  * The number of Descriptor Ring entries
54  *
55  * Constraints:
56  * 	- overall DRing size must be greater than 8K (MMU_PAGESIZE)
57  *	- overall DRing size should be 8K aligned (desirable but not enforced)
58  *	- DRing entry must be 8 byte aligned
59  */
60 #define	VD_DRING_LEN		512
61 
62 /*
63  *
64  */
65 #define	VD_DRING_ENTRY_SZ	(sizeof (vd_dring_entry_t) + 		\
66 		(sizeof (ldc_mem_cookie_t) * (VD_MAX_COOKIES - 1)))
67 
68 /*
69  * The maximum block size we can transmit using one Descriptor Ring entry
70  *
71  * Currently no FS uses more than 128K and it doesn't look like they
72  * will either as there is no perf gain to be had by larger values.
73  * ( see ZFS comment at definition of SPA_MAXBLOCKSIZE ).
74  *
75  * We choose 256K to give us some headroom.
76  */
77 #define	VD_MAX_BLOCK_SIZE	(256 * 1024)
78 
79 #define	VD_MAX_COOKIES		((VD_MAX_BLOCK_SIZE / PAGESIZE) + 1)
80 #define	VD_USEC_TIMEOUT		20000
81 #define	VD_LDC_IDS_PROP		"ldc-ids"
82 #define	VD_LDC_MTU		256
83 
84 /*
85  * Flags used by ioctl routines to indicate if a copyin/copyout is needed
86  */
87 #define	VD_COPYOUT		0x1
88 #define	VD_COPYIN		0x2
89 
90 /*
91  * vDisk operations on physical devices
92  */
93 #define	VD_OP_BREAD		0x01	/* Block Read */
94 #define	VD_OP_BWRITE		0x02	/* Block Write */
95 #define	VD_OP_FLUSH		0x03	/* Flush disk write cache contents */
96 #define	VD_OP_GET_WCE		0x04	/* Get disk W$ status */
97 #define	VD_OP_SET_WCE		0x05	/* Enable/Disable disk W$ */
98 #define	VD_OP_GET_VTOC		0x06	/* Get VTOC */
99 #define	VD_OP_SET_VTOC		0x07	/* Set VTOC */
100 #define	VD_OP_GET_DISKGEOM	0x08	/* Get disk geometry */
101 #define	VD_OP_SET_DISKGEOM	0x09	/* Set disk geometry */
102 #define	VD_OP_SCSICMD		0x0a	/* SCSI control command */
103 #define	VD_OP_MASK		0xFF	/* mask of all possible operations */
104 #define	VD_OP_COUNT		10	/* Number of operations */
105 
106 /*
107  * Definitions of the various ways vds can export disk support to vdc.
108  */
109 typedef enum vd_disk_type {
110 	VD_DISK_TYPE_UNK = 0,		/* Unknown device type */
111 	VD_DISK_TYPE_SLICE,		/* slice in block device */
112 	VD_DISK_TYPE_DISK		/* entire disk (slice 2) */
113 } vd_disk_type_t;
114 
115 /*
116  * vDisk Descriptor payload
117  */
118 typedef struct vd_dring_payload {
119 	uint64_t	req_id;		/* The request ID being processed */
120 	uint8_t		operation;	/* operation for server to perform */
121 	uint8_t		slice;		/* The disk slice being accessed */
122 	uint16_t	resv1;		/* padding */
123 	uint32_t	status;		/* "errno" of server operation */
124 	uint64_t	addr;		/* LP64	diskaddr_t (block I/O) */
125 	uint64_t	nbytes;		/* LP64 size_t */
126 	uint32_t	ncookies;	/* Number of cookies used */
127 	uint32_t	resv2;		/* padding */
128 
129 	ldc_mem_cookie_t	cookie[1];	/* variable sized array */
130 } vd_dring_payload_t;
131 
132 
133 /*
134  * vDisk Descriptor entry
135  */
136 typedef struct vd_dring_entry {
137 	vio_dring_entry_hdr_t		hdr;		/* common header */
138 	vd_dring_payload_t		payload;	/* disk specific data */
139 } vd_dring_entry_t;
140 
141 
142 /*
143  * vDisk control operation structures
144  */
145 
146 /*
147  * vDisk geometry definition (VD_OP_GET_DISKGEOM and VD_OP_SET_DISKGEOM)
148  */
149 typedef struct vd_geom {
150 	uint16_t	ncyl;		/* number of data cylinders */
151 	uint16_t	acyl;		/* number of alternate cylinders */
152 	uint16_t	bcyl;		/* cyl offset for fixed head area */
153 	uint16_t	nhead;		/* number of heads */
154 	uint16_t	nsect;		/* number of data sectors per track */
155 	uint16_t	intrlv;		/* interleave factor */
156 	uint16_t	apc;		/* alternates per cyl (SCSI only) */
157 	uint16_t	rpm;		/* revolutions per minute */
158 	uint16_t	pcyl;		/* number of physical cylinders */
159 	uint16_t	write_reinstruct;	/* # sectors to skip, writes */
160 	uint16_t	read_reinstruct;	/* # sectors to skip, reads */
161 } vd_geom_t;
162 
163 
164 /*
165  * vDisk partition definition
166  */
167 typedef struct vd_partition {
168 	uint16_t	id_tag;		/* ID tag of partition */
169 	uint16_t	perm;		/* permission flags for partition */
170 	uint32_t	reserved;	/* padding */
171 	uint64_t	start;		/* block number of partition start */
172 	uint64_t	nblocks;	/* number of blocks in partition */
173 } vd_partition_t;
174 
175 /*
176  * vDisk VTOC definition (VD_OP_GET_VTOC and VD_OP_SET_VTOC)
177  */
178 #define	VD_VOLNAME_LEN		8	/* length of volume_name field */
179 #define	VD_ASCIILABEL_LEN	128	/* length of ascii_label field */
180 typedef struct vd_vtoc {
181 	char		volume_name[VD_VOLNAME_LEN];	/* volume name */
182 	uint16_t	sector_size;		/* sector size in bytes */
183 	uint16_t	num_partitions;		/* number of partitions */
184 	char		ascii_label[VD_ASCIILABEL_LEN];	/* ASCII label */
185 	vd_partition_t	partition[V_NUMPAR];	/* partition headers */
186 } vd_vtoc_t;
187 
188 
189 /*
190  * Copy the contents of a vd_geom_t to the contents of a dk_geom struct
191  */
192 #define	VD_GEOM2DK_GEOM(vd_geom, dk_geom)				\
193 {									\
194 	bzero((dk_geom), sizeof (*(dk_geom)));				\
195 	(dk_geom)->dkg_ncyl		= (vd_geom)->ncyl;		\
196 	(dk_geom)->dkg_acyl		= (vd_geom)->acyl;		\
197 	(dk_geom)->dkg_bcyl		= (vd_geom)->bcyl;		\
198 	(dk_geom)->dkg_nhead		= (vd_geom)->nhead;		\
199 	(dk_geom)->dkg_nsect		= (vd_geom)->nsect;		\
200 	(dk_geom)->dkg_intrlv		= (vd_geom)->intrlv;		\
201 	(dk_geom)->dkg_apc		= (vd_geom)->apc;		\
202 	(dk_geom)->dkg_rpm		= (vd_geom)->rpm;		\
203 	(dk_geom)->dkg_pcyl		= (vd_geom)->pcyl;		\
204 	(dk_geom)->dkg_write_reinstruct	= (vd_geom)->write_reinstruct;	\
205 	(dk_geom)->dkg_read_reinstruct	= (vd_geom)->read_reinstruct;	\
206 }
207 
208 /*
209  * Copy the contents of a vd_vtoc_t to the contents of a vtoc struct
210  */
211 #define	VD_VTOC2VTOC(vd_vtoc, vtoc)					\
212 {									\
213 	bzero((vtoc), sizeof (*(vtoc)));				\
214 	bcopy((vd_vtoc)->volume_name, (vtoc)->v_volume,			\
215 	    MIN(sizeof ((vd_vtoc)->volume_name),			\
216 		sizeof ((vtoc)->v_volume)));				\
217 	bcopy((vd_vtoc)->ascii_label, (vtoc)->v_asciilabel,		\
218 	    MIN(sizeof ((vd_vtoc)->ascii_label),			\
219 		sizeof ((vtoc)->v_asciilabel)));			\
220 	(vtoc)->v_sanity	= VTOC_SANE;				\
221 	(vtoc)->v_version	= V_VERSION;				\
222 	(vtoc)->v_sectorsz	= (vd_vtoc)->sector_size;		\
223 	(vtoc)->v_nparts	= (vd_vtoc)->num_partitions;		\
224 	for (int i = 0; i < (vd_vtoc)->num_partitions; i++) {		\
225 		(vtoc)->v_part[i].p_tag	= (vd_vtoc)->partition[i].id_tag; \
226 		(vtoc)->v_part[i].p_flag = (vd_vtoc)->partition[i].perm; \
227 		(vtoc)->v_part[i].p_start = (vd_vtoc)->partition[i].start; \
228 		(vtoc)->v_part[i].p_size = (vd_vtoc)->partition[i].nblocks; \
229 	}								\
230 }
231 
232 /*
233  * Copy the contents of a dk_geom struct to the contents of a vd_geom_t
234  */
235 #define	DK_GEOM2VD_GEOM(dk_geom, vd_geom)				\
236 {									\
237 	bzero((vd_geom), sizeof (*(vd_geom)));				\
238 	(vd_geom)->ncyl			= (dk_geom)->dkg_ncyl;		\
239 	(vd_geom)->acyl			= (dk_geom)->dkg_acyl;		\
240 	(vd_geom)->bcyl			= (dk_geom)->dkg_bcyl;		\
241 	(vd_geom)->nhead		= (dk_geom)->dkg_nhead;		\
242 	(vd_geom)->nsect		= (dk_geom)->dkg_nsect;		\
243 	(vd_geom)->intrlv		= (dk_geom)->dkg_intrlv;	\
244 	(vd_geom)->apc			= (dk_geom)->dkg_apc;		\
245 	(vd_geom)->rpm			= (dk_geom)->dkg_rpm;		\
246 	(vd_geom)->pcyl			= (dk_geom)->dkg_pcyl;		\
247 	(vd_geom)->write_reinstruct	= (dk_geom)->dkg_write_reinstruct; \
248 	(vd_geom)->read_reinstruct	= (dk_geom)->dkg_read_reinstruct; \
249 }
250 
251 /*
252  * Copy the contents of a vtoc struct to the contents of a vd_vtoc_t
253  */
254 #define	VTOC2VD_VTOC(vtoc, vd_vtoc)					\
255 {									\
256 	bzero((vd_vtoc), sizeof (*(vd_vtoc)));				\
257 	bcopy((vtoc)->v_volume, (vd_vtoc)->volume_name,			\
258 	    MIN(sizeof ((vtoc)->v_volume),				\
259 		sizeof ((vd_vtoc)->volume_name)));			\
260 	bcopy((vtoc)->v_asciilabel, (vd_vtoc)->ascii_label,		\
261 	    MIN(sizeof ((vtoc)->v_asciilabel),				\
262 		sizeof ((vd_vtoc)->ascii_label)));			\
263 	(vd_vtoc)->sector_size			= (vtoc)->v_sectorsz;	\
264 	(vd_vtoc)->num_partitions		= (vtoc)->v_nparts;	\
265 	for (int i = 0; i < (vtoc)->v_nparts; i++) {			\
266 		(vd_vtoc)->partition[i].id_tag	= (vtoc)->v_part[i].p_tag; \
267 		(vd_vtoc)->partition[i].perm	= (vtoc)->v_part[i].p_flag; \
268 		(vd_vtoc)->partition[i].start	= (vtoc)->v_part[i].p_start; \
269 		(vd_vtoc)->partition[i].nblocks	= (vtoc)->v_part[i].p_size; \
270 	}								\
271 }
272 
273 
274 #ifdef	__cplusplus
275 }
276 #endif
277 
278 #endif	/* _VDSK_COMMON_H */
279