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 (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 #ifndef	_SYS_DEVINFO_IMPL_H
26 #define	_SYS_DEVINFO_IMPL_H
27 
28 #include <sys/ddi_impldefs.h>
29 
30 /*
31  * This file is separate from libdevinfo.h because the devinfo driver
32  * needs to know about the stuff. Library consumer should not care
33  * about stuff defined here.
34  *
35  * The only exception is di_priv_data (consolidation private) and
36  * DINFO* ioctls.
37  */
38 
39 #ifdef	__cplusplus
40 extern "C" {
41 #endif
42 
43 /* ioctl commands for devinfo driver */
44 
45 #define	DIIOC		(0xdf<<8)
46 #define	DIIOC_MASK	(0xffff00ff)
47 
48 /*
49  * Any combination of the following ORed together will take a snapshot
50  * of the device configuration data.
51  */
52 #define	DINFOSUBTREE	(DIIOC | 0x01)	/* include subtree */
53 #define	DINFOMINOR	(DIIOC | 0x02)	/* include minor data */
54 #define	DINFOPROP	(DIIOC | 0x04)	/* include properties */
55 #define	DINFOPATH	(DIIOC | 0x08)	/* include i/o pathing information */
56 
57 /* private bits */
58 #define	DINFOPRIVDATA	(DIIOC | 0x10)	/* include private data */
59 #define	DINFOFORCE	(DIIOC | 0x20)	/* force load all drivers */
60 #define	DINFOCACHE	(DIIOC | 0x100000) /* use cached data  */
61 #define	DINFOCLEANUP	(DIIOC | 0x200000) /* cleanup /etc/devices files */
62 
63 /* new public flag for the layered drivers framework */
64 #define	DINFOLYR	(DIIOC | 0x40)	/* get device layering information */
65 
66 /* new public flag for the hotplug framework */
67 #define	DINFOHP		(DIIOC | 0x400000)  /* include hotplug information */
68 
69 /*
70  * Straight ioctl commands, not bitwise operation
71  */
72 #define	DINFOUSRLD	(DIIOC | 0x80)	/* copy snapshot to usrland */
73 #define	DINFOLODRV	(DIIOC | 0x81)	/* force load a driver */
74 #define	DINFOIDENT	(DIIOC | 0x82)	/* identify the driver */
75 
76 /*
77  * ioctl for taking a snapshot a single node and all nodes
78  */
79 #define	DINFOCPYONE	DIIOC
80 #define	DINFOCPYALL	(DINFOSUBTREE | DINFOPROP | DINFOMINOR)
81 
82 #define	DI_MAGIC	0xdfdf	/* magic number returned by DINFOIDENT */
83 
84 /* driver ops encoding */
85 
86 #define	DI_BUS_OPS	0x1
87 #define	DI_CB_OPS	0x2
88 #define	DI_STREAM_OPS	0x4
89 
90 /* property list enumeration */
91 
92 #define	DI_PROP_DRV_LIST	0
93 #define	DI_PROP_SYS_LIST	1
94 #define	DI_PROP_GLB_LIST	2
95 #define	DI_PROP_HW_LIST		3
96 
97 /* misc parameters */
98 
99 #define	MAX_TREE_DEPTH	64
100 #define	MAX_PTR_IN_PRV	5
101 #define	DI_SNAPSHOT_VERSION_0	0	/* reserved */
102 #define	DI_SNAPSHOT_VERSION_1	1	/* reserved */
103 #define	DI_SNAPSHOT_VERSION_2	2	/* reserved */
104 #define	DI_SNAPSHOT_VERSION	DI_SNAPSHOT_VERSION_2	/* current version */
105 #define	DI_PRIVDATA_VERSION_0	10	/* Start from 10 so caller must set */
106 #define	DI_BIG_ENDIAN		0	/* reserved */
107 #define	DI_LITTLE_ENDIAN	1	/* reserved */
108 
109 #define	DI_CACHE_MAGIC		0xdfcac6ed	/* magic # for cache */
110 #define	DI_CACHE_PERMS		(0444)
111 #define	DI_CACHE_SNAPSHOT_FLAGS	\
112 	(DINFOFORCE|DINFOSUBTREE|DINFOMINOR|DINFOPROP|DINFOPATH)
113 
114 #define	DI_NODE(addr)		((struct di_node *)((void *)(addr)))
115 #define	DI_MINOR(addr)		((struct di_minor *)((void *)(addr)))
116 #define	DI_PROP(addr)		((struct di_prop *)((void *)(addr)))
117 #define	DI_PATH(addr)		((struct di_path *)((void *)(addr)))
118 #define	DI_PATHPROP(addr)	((struct di_path_prop *)((void *)(addr)))
119 #define	DI_ALL(addr)		((struct di_all *)((void *)(addr)))
120 #define	DI_DEVNM(addr)		((struct di_devnm *)((void *)(addr)))
121 #define	DI_LINK(addr)		((struct di_link *)((void *)(addr)))
122 #define	DI_LNODE(addr)		((struct di_lnode *)((void *)(addr)))
123 #define	DI_PRIV_FORMAT(addr)	((struct di_priv_format *)((void *)(addr)))
124 #define	DI_HP(addr)		((struct di_hp *)((void *)(addr)))
125 #define	DI_ALIAS(addr)		((struct di_alias *)((void *)(addr)))
126 
127 /*
128  * multipath component definitions:  Follows the registered component of
129  * the mpxio system.
130  */
131 #define	MULTIPATH_COMPONENT_NONE	0
132 #define	MULTIPATH_COMPONENT_VHCI	0x1
133 #define	MULTIPATH_COMPONENT_PHCI	0x2
134 #define	MULTIPATH_COMPONENT_CLIENT	0x4
135 
136 typedef int32_t di_off_t;
137 
138 /*
139  * devinfo driver snapshot data structure
140  */
141 struct di_all {
142 	int	version;	/* snapshot version, reserved */
143 	int	cache_magic;	/* magic number for cached snapshot */
144 	int	pd_version;	/* private data format version */
145 	int	endianness;	/* reserved for future use */
146 	int	generation;	/* reserved for future use */
147 	uint32_t	cache_checksum;	/* snapshot checksum */
148 	uint64_t	snapshot_time;	/* snapshot timestamp */
149 	di_off_t	top_devinfo;  /* actual top devinfo in snapshot */
150 	di_off_t	top_vhci_devinfo;
151 	di_off_t	devnames;
152 	di_off_t	ppdata_format;	/* parent priv data format array */
153 	di_off_t	dpdata_format;	/* driver priv data format array */
154 	di_off_t	aliases;	/* offset to alias tree */
155 	int	n_ppdata;	/* size of ppdata_format array */
156 	int	n_dpdata;	/* size of pddata_format array */
157 	int	devcnt;		/* size of devnames array */
158 	uint_t	command;	/* same as in di_init() */
159 	uint_t	map_size;	/* size of the snapshot */
160 	char	req_path[MAXPATHLEN];	/* path to requested root */
161 	char	root_path[1];	/* path to actual snapshot root */
162 };
163 
164 struct di_devnm {
165 	di_off_t name;
166 	di_off_t global_prop;
167 	di_off_t head;	/* head of per instance list */
168 	int flags;	/* driver attachment info */
169 	int instance;	/* next instance to assign */
170 	uint_t ops;	/* bit-encoded driver ops */
171 };
172 
173 
174 struct di_lnode;
175 
176 struct di_link {
177 	di_off_t	self;
178 	int		count;
179 	int		spec_type;	/* block or char access type */
180 	di_off_t	src_lnode;	/* src di_lnode */
181 	di_off_t	tgt_lnode;	/* tgt di_lnode */
182 	di_off_t	src_link_next;	/* next src di_link /w same di_lnode */
183 	di_off_t	tgt_link_next;	/* next tgt di_link /w same di_lnode */
184 	di_off_t	src_node_next;	/* next src di_link /w same di_node */
185 	di_off_t	tgt_node_next;	/* next tgt di_link /w same di_node */
186 	uint64_t 	user_private_data;
187 };
188 
189 struct di_lnode {
190 	di_off_t	self;
191 
192 	/*
193 	 * public information describing a link endpoint
194 	 */
195 	major_t		dev_major;	/* dev_t can be 64-bit */
196 	minor_t		dev_minor;	/* dev_t can be 64-bit */
197 	di_off_t	node;		/* offset of di_node */
198 
199 	/*
200 	 * di_link ptr to links comming into this node
201 	 * (this lnode is the target of these di_links)
202 	 */
203 	di_off_t	link_in;
204 
205 	/*
206 	 * di_link ptr to links going out of this node
207 	 * (this lnode is the source of these di_links)
208 	 */
209 	di_off_t	link_out;
210 
211 	/*
212 	 * di_lnode pointer to the next lnode associated with the
213 	 * same di_node
214 	 */
215 	di_off_t	node_next;
216 
217 	uint64_t 	user_private_data;
218 };
219 
220 struct di_node {	/* useful info to export for each tree node */
221 	/*
222 	 * offset to di_node structures
223 	 */
224 	di_off_t self;		/* make it self addressable */
225 	di_off_t parent;	/* offset of parent node */
226 	di_off_t child;		/* offset of child node */
227 	di_off_t sibling;	/* offset of sibling */
228 	di_off_t next;		/* next node on per-instance list */
229 	/*
230 	 * offset to char strings of current node
231 	 */
232 	di_off_t node_name;	/* offset of device node name */
233 	di_off_t address;	/* offset of address part of name */
234 	di_off_t bind_name;	/* offset of binding name */
235 	di_off_t compat_names;	/* offset of compatible names */
236 	/*
237 	 * offset to property lists, private data, etc.
238 	 */
239 	di_off_t minor_data;
240 	di_off_t drv_prop;
241 	di_off_t sys_prop;
242 	di_off_t glob_prop;
243 	di_off_t hw_prop;
244 	di_off_t parent_data;
245 	di_off_t driver_data;
246 	di_off_t multipath_client;
247 	di_off_t multipath_phci;
248 	di_off_t devid;		/* registered device id */
249 	di_off_t pm_info;	/* RESERVED FOR FUTURE USE */
250 	/*
251 	 * misc values
252 	 */
253 	int compat_length;	/* size of compatible name list */
254 	int drv_major;		/* for indexing into devnames array */
255 	/*
256 	 * value attributes of current node
257 	 */
258 	int instance;		/* instance number */
259 	int nodeid;		/* node id */
260 	ddi_node_class_t node_class;	/* node class */
261 	int attributes;		/* node attributes */
262 	uint_t state;		/* hotplugging device state */
263 	ddi_node_state_t node_state;	/* devinfo state */
264 
265 	di_off_t lnodes;	/* lnodes associated with this di_node */
266 	di_off_t tgt_links;
267 	di_off_t src_links;
268 
269 	uint32_t di_pad1;	/* 4 byte padding for 32bit x86 app. */
270 	uint64_t user_private_data;
271 	/*
272 	 * offset to link vhci/phci nodes.
273 	 */
274 	di_off_t next_vhci;
275 	di_off_t top_phci;
276 	di_off_t next_phci;
277 	uint32_t multipath_component;	/* stores MDI_COMPONENT_* value. */
278 	/*
279 	 * devi_flags field
280 	 */
281 	uint32_t flags;
282 	uint32_t di_pad2;	/* 4 byte padding for 32bit x86 app. */
283 	/*
284 	 * offset to hotplug nodes.
285 	 */
286 	di_off_t hp_data;
287 };
288 
289 /*
290  * chain of ddi_minor_data structure
291  */
292 struct di_minor {
293 	di_off_t	self;		/* make it self addressable */
294 	di_off_t	next;		/* next one in the chain */
295 	di_off_t	name;		/* name of node */
296 	di_off_t	node_type;	/* block, byte, serial, network */
297 	ddi_minor_type	type;		/* data type */
298 	major_t		dev_major;	/* dev_t can be 64-bit */
299 	minor_t		dev_minor;
300 	int		spec_type;	/* block or char */
301 	unsigned int	mdclass;	/* no longer used, may be removed */
302 	di_off_t	node;		/* address of di_node */
303 	uint64_t 	user_private_data;
304 };
305 
306 typedef enum {
307 	DI_PATH_STATE_UNKNOWN,
308 	DI_PATH_STATE_OFFLINE,
309 	DI_PATH_STATE_STANDBY,
310 	DI_PATH_STATE_ONLINE,
311 	DI_PATH_STATE_FAULT
312 } di_path_state_t;
313 
314 /*
315  * multipathing information structures
316  */
317 struct di_path {
318 	di_off_t	self;		/* make it self addressable */
319 	di_off_t	path_c_link;	/* next pathinfo via client linkage */
320 	di_off_t	path_p_link;	/* next pathinfo via phci linkage */
321 	di_off_t	path_client;	/* reference to client node */
322 	di_off_t	path_phci;	/* reference to phci node */
323 	di_off_t	path_prop;	/* property list */
324 	di_off_t	path_addr;	/* path addressing information */
325 	di_path_state_t path_state;	/* path state */
326 	uint_t		path_snap_state; /* describes valid fields */
327 	int		path_instance;	/* path instance */
328 	uint64_t 	user_private_data;
329 	uint_t		path_flags;	/* path flags */
330 };
331 
332 /*
333  * chain of hotplug information structures
334  */
335 struct di_hp {
336 	di_off_t	self;		/* make it self addressable */
337 	di_off_t	next;		/* next one in chain */
338 	di_off_t	hp_name;	/* name of hotplug connection */
339 	int		hp_connection;	/* connection number */
340 	int		hp_depends_on;	/* connection number depended upon */
341 	int		hp_state;	/* current hotplug state */
342 	int		hp_type;	/* connection type: PCI, ... */
343 	di_off_t	hp_type_str;	/* description of connection type */
344 	uint32_t	hp_last_change;	/* timestamp of last change */
345 	di_off_t	hp_child;	/* child device node */
346 };
347 
348 /*
349  * Flags for snap_state
350  */
351 #define	DI_PATH_SNAP_NOCLIENT	0x01	/* client endpt not in snapshot */
352 #define	DI_PATH_SNAP_NOPHCI	0x02	/* phci endpt not in snapshot */
353 #define	DI_PATH_SNAP_ENDPTS	0x04	/* Endpoints have been postprocessed */
354 
355 #define	DI_PATH_SNAP_NOCLINK	0x10	/* client linkage not in snapshot */
356 #define	DI_PATH_SNAP_NOPLINK	0x20	/* phci linkage not in snapshot */
357 #define	DI_PATH_SNAP_LINKS	0x40	/* linkages have been postprocessed */
358 
359 /*
360  * Flags for path_flags
361  */
362 #define	DI_PATH_FLAGS_DEVICE_REMOVED	0x01	/* peer of DI_DEVICE_REMOVED */
363 
364 /*
365  * path properties
366  */
367 struct di_path_prop {
368 	di_off_t	self;		/* make it self addressable */
369 	di_off_t	prop_next;	/* next property linkage */
370 	di_off_t	prop_name;	/* property name */
371 	di_off_t	prop_data;	/* property data */
372 	int		prop_type;	/* property data type */
373 	int		prop_len;	/* prop length in bytes */
374 };
375 
376 /*
377  * Now the properties.
378  */
379 struct di_prop {
380 	di_off_t	self;		/* make it self addressable */
381 	di_off_t	next;
382 	di_off_t	prop_name;	/* Property name */
383 	di_off_t	prop_data;	/* property data */
384 	major_t		dev_major;	/* dev_t can be 64 bit */
385 	minor_t		dev_minor;
386 	int		prop_flags;	/* mark prop value types & more */
387 	int		prop_len;	/* prop len in bytes (boolean if 0) */
388 	int		prop_list;	/* which list (DI_PROP_SYS_LIST), etc */
389 };
390 
391 /*
392  * Private data stuff for supporting prtconf.
393  * Allows one level of indirection of fixed sized obj or obj array.
394  * The array size may be an int member of the array.
395  */
396 
397 struct di_priv_format {
398 	char drv_name[MAXPATHLEN];	/* name of parent drv for ppdata */
399 	size_t bytes;			/* size in bytes of this struct */
400 	struct {			/* ptrs to dereference */
401 		int size;	/* size of object assoc. this ptr */
402 		int offset;	/* location of pointer within struct */
403 		int len_offset;	/* offset to var. containing the len */
404 	} ptr[MAX_PTR_IN_PRV];
405 };
406 
407 struct di_priv_data {
408 	int version;
409 	int n_parent;
410 	int n_driver;
411 	struct di_priv_format *parent;
412 	struct di_priv_format *driver;
413 };
414 
415 
416 /*
417  * structure for saving alias information
418  */
419 struct di_alias {
420 	di_off_t	self;		/* make it self addressable */
421 	di_off_t	curroff;	/* offset to curr dip's snapshot */
422 	di_off_t	next;		/* next alias */
423 	char		alias[1];	/* alias path */
424 };
425 
426 /*
427  * structure passed in from ioctl
428  */
429 struct dinfo_io {
430 	char root_path[MAXPATHLEN];
431 	struct di_priv_data priv;
432 };
433 
434 #ifdef	__cplusplus
435 }
436 #endif
437 
438 #endif	/* _SYS_DEVINFO_IMPL_H */
439