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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef	_SYS_PSHOT_H
28#define	_SYS_PSHOT_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#ifdef	__cplusplus
33extern "C" {
34#endif
35
36#include <sys/sunndi.h>
37
38/*
39 * user accessable features
40 */
41
42/* determines max pshot_minor allocation per softstate */
43#define	PSHOT_MAX_MINOR_PERINST		2
44#define	PSHOT_MAX_MINOR_NAMELEN		16
45
46#define	PSHOT_NODENAME_DEVCTL		"devctl"
47#define	PSHOT_NODENAME_TESTCTL		"testctl"
48
49#define	PSHOT_PROP_DEVNAME	"dev-name"
50#define	PSHOT_PROP_DEVNT	"dev-nt"
51#define	PSHOT_PROP_DEVCOMPAT	"dev-compat"
52
53
54#ifdef	_KERNEL
55
56
57#define	PARENT_IS_PSHOT(self)	\
58	(ddi_driver_major(self) == ddi_driver_major(ddi_get_parent(self)))
59
60
61static int pshot_debug = 0;
62static int pshot_event_test_enable = 0;
63
64#ifdef DEBUG
65#define	pshot_debug pshot_debug_on
66#define	pshot_event_test_enable pshot_event_test_on
67
68static int pshot_debug_on = 0;
69static int pshot_event_test_on = 0;
70
71#endif
72
73#define	PSHOT_MAX_CBCACHE	6
74#define	PSHOT_MAX_TSTCACHE	8
75
76/*
77 * soft state and minor node management
78 * (includes user features above)
79 */
80
81/*
82 * a "node number" is currently implemented as an index into a pshot_minor_t
83 * array, therefore the max must be less than PSHOT_MAX_MINOR_PERINST and
84 * ideally, the minor array should be fully populated, with a node number
85 * defined for each index
86 */
87#define	PSHOT_NODENUM_DEVCTL		0
88#define	PSHOT_NODENUM_TESTCTL		1
89#define	PSHOT_MAX_NODENUM		PSHOT_NODENUM_TESTCTL
90
91typedef struct pshot_minor pshot_minor_t;
92typedef struct pshot pshot_t;
93
94struct pshot_minor {
95	pshot_t		*pshot;
96	minor_t		minor;
97	char		name[PSHOT_MAX_MINOR_NAMELEN];
98};
99
100struct pshot {
101	kmutex_t	lock;
102	uint_t		state;
103	dev_info_t	*dip;
104	int		instance;
105	ndi_event_hdl_t	ndi_event_hdl;
106	ndi_event_set_t	ndi_events;
107	ddi_iblock_cookie_t	iblock_cookie;
108	ddi_callback_id_t 	callback_cache[PSHOT_MAX_CBCACHE];
109	ddi_callback_id_t	test_callback_cache[PSHOT_MAX_TSTCACHE];
110
111	pshot_minor_t	nodes[PSHOT_MAX_MINOR_PERINST];
112	int	level;		/* pm power level */
113	int	busy;		/* pm busy state */
114	int	busy_ioctl;	/* track busy and idle ioctl calls */
115};
116
117
118static size_t pshot_numbits(size_t);
119static minor_t pshot_minor_encode(int, minor_t);
120static int pshot_minor_decode_inst(minor_t);
121static minor_t pshot_minor_decode_nodenum(minor_t);
122
123#define	PSHOT_NODENUM_BITS()	pshot_numbits(PSHOT_MAX_MINOR_PERINST)
124
125/*
126 * children device configuration
127 */
128
129typedef struct pshot_device {
130	char *name;
131	char *nodetype;
132	char *compat;
133} pshot_device_t;
134
135#define	PSHOT_DEV_ANYNT		0x1
136
137static char *pshot_str2nt(char *);
138static pshot_device_t *pshot_devices_from_props(dev_info_t *, size_t *, int);
139static void pshot_devices_free(pshot_device_t *, size_t);
140static int pshot_devices_setup(dev_info_t *);
141static int pshot_devices_grow(pshot_device_t **, size_t,
142    const pshot_device_t *, size_t);
143
144
145/*
146 * softstate state bits
147 */
148#define	IS_OPEN				0x0001
149#define	IS_OPEN_EXCL			0x0002
150#define	DEV_RESET_PENDING		0x0004
151#define	BUS_RESET_PENDING		0x0008
152#define	POWER_FLAG			0x0010
153#define	FAIL_SUSPEND_FLAG		0x0020
154#define	STRICT_PARENT			0x0040
155#define	NO_INVOL_FLAG			0x0080
156#define	PM_SUPPORTED			0x0100
157
158/*
159 * Leaf ops (supports hotplug controls to the device)
160 */
161static int pshot_open(dev_t *, int, int, cred_t *);
162static int pshot_close(dev_t, int, int, cred_t *);
163static int pshot_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
164static int pshot_probe(dev_info_t *);
165static int pshot_attach(dev_info_t *, ddi_attach_cmd_t);
166static int pshot_detach(dev_info_t *, ddi_detach_cmd_t);
167static int pshot_info(dev_info_t *, ddi_info_cmd_t,  void *, void **);
168static int pshot_power(dev_info_t *dip, int cmpt, int level);
169
170static int pshot_devctl(pshot_t *, minor_t, int, intptr_t, int, cred_t *,
171    int *);
172static int pshot_testctl(pshot_t *, minor_t, int, intptr_t, int, cred_t *,
173    int *);
174
175/*
176 * Event handling prototype support.
177 */
178#define	PSHOT_EVENT_NAME_DEV_OFFLINE	"pshot_dev_offline"
179#define	PSHOT_EVENT_NAME_DEV_RESET	"pshot_dev_reset"
180#define	PSHOT_EVENT_NAME_BUS_RESET	"pshot_bus_reset"
181#define	PSHOT_EVENT_NAME_BUS_QUIESCE	"pshot_bus_quiesce"
182#define	PSHOT_EVENT_NAME_BUS_UNQUIESCE	"pshot_bus_unquiesce"
183#define	PSHOT_EVENT_NAME_BUS_TEST_POST	"pshot_bus_test_post"
184#define	PSHOT_EVENT_NAME_DEBUG_SET	"pshot_debug_set"
185#define	PSHOT_EVENT_NAME_SUB_RESET	"pshot_sub_reset"
186						/* for hash sanity check */
187
188#define	PSHOT_EVENT_TAG_OFFLINE		0
189#define	PSHOT_EVENT_TAG_DEV_RESET	1
190#define	PSHOT_EVENT_TAG_BUS_RESET	2
191#define	PSHOT_EVENT_TAG_BUS_QUIESCE	3
192#define	PSHOT_EVENT_TAG_BUS_UNQUIESCE	4
193#define	PSHOT_EVENT_TAG_TEST_POST	5
194
195typedef struct pshot_event_callback {
196	dev_info_t			*dip;
197	int				(*callback)();
198	void				*arg;
199	struct pshot_event_callback	*next;
200} ps_callback_t;
201
202
203static void pshot_event_cb(dev_info_t *dip, ddi_eventcookie_t cookie,
204	void *arg, void *bus_impldata);
205
206static int pshot_event(pshot_t *pshot, int event_tag, dev_info_t *child,
207	void *bus_impldata);
208
209#ifdef DEBUG
210static void pshot_event_cb_test(dev_info_t *dip, ddi_eventcookie_t cookie,
211    void *arg, void *bus_impldata);
212static void pshot_event_test(void *arg);
213static void pshot_event_test_post_one(void *arg);
214#endif
215
216/* event busops */
217static int pshot_get_eventcookie(dev_info_t *dip, dev_info_t *rdip,
218    char *name, ddi_eventcookie_t *event_cookiep);
219static int pshot_add_eventcall(dev_info_t *dip, dev_info_t *rdip,
220    ddi_eventcookie_t eventid, void (*callback)(), void *arg,
221    ddi_callback_id_t *cb_id);
222static int pshot_remove_eventcall(dev_info_t *dip, ddi_callback_id_t cb_id);
223static int pshot_post_event(dev_info_t *dip, dev_info_t *rdip,
224    ddi_eventcookie_t eventid, void *impl_data);
225
226/* function prototypes */
227static int pshot_ctl(dev_info_t *dip, dev_info_t *rdip, ddi_ctl_enum_t ctlop,
228    void *arg, void *result);
229static int pshot_initchild(dev_info_t *, dev_info_t *);
230static int pshot_uninitchild(dev_info_t *, dev_info_t *);
231static int pshot_bus_config(dev_info_t *, uint_t,
232	ddi_bus_config_op_t, void *, dev_info_t **);
233static int pshot_bus_unconfig(dev_info_t *, uint_t,
234    ddi_bus_config_op_t, void *);
235static int pshot_bus_config_setup_nexus(dev_info_t *, char *cname, char *caddr);
236static int pshot_bus_config_setup_leaf(dev_info_t *, char *cname, char *caddr);
237static int pshot_bus_config_test_specials(dev_info_t *parent,
238	char *devname, char *cname, char *caddr);
239static int pshot_bus_introp(dev_info_t *, dev_info_t *, ddi_intr_op_t,
240	ddi_intr_handle_impl_t *, void *);
241
242static void pshot_setup_autoattach(dev_info_t *);
243static int pshot_bus_power(dev_info_t *dip, void *impl_arg,
244	    pm_bus_power_op_t op, void *arg, void *result);
245static void pshot_nexus_properties(dev_info_t *, dev_info_t *, char *, char *);
246static void pshot_leaf_properties(dev_info_t *, dev_info_t *, char *, char *);
247
248
249#endif /* _KERNEL */
250
251
252#ifdef	__cplusplus
253}
254#endif
255
256#endif /* _SYS_PSHOT_H */
257