xref: /titanic_53/usr/src/uts/sun4/sys/fcode.h (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #ifndef	_SYS_FCODE_H
28*7c478bd9Sstevel@tonic-gate #define	_SYS_FCODE_H
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/fc_plat.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/pci.h>
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
39*7c478bd9Sstevel@tonic-gate extern "C" {
40*7c478bd9Sstevel@tonic-gate #endif
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate /*
43*7c478bd9Sstevel@tonic-gate  * The FCode driver presents a private interface to the fcode
44*7c478bd9Sstevel@tonic-gate  * user level interpreter.  This interface is subject to change
45*7c478bd9Sstevel@tonic-gate  * at any time and is only provided for use by the fcode interpreter.
46*7c478bd9Sstevel@tonic-gate  *
47*7c478bd9Sstevel@tonic-gate  * The user program opens the device, causing a new instance of
48*7c478bd9Sstevel@tonic-gate  * the driver to be cloned.  This instance is specific to a specific
49*7c478bd9Sstevel@tonic-gate  * instance of a new device managed by the kernel and driver framework.
50*7c478bd9Sstevel@tonic-gate  *
51*7c478bd9Sstevel@tonic-gate  * The interpreter does an FC_GET_PARAMETERS ioctl to get the fcode
52*7c478bd9Sstevel@tonic-gate  * length, which can be mmap-ed (at offset 0) to provide access to a copy
53*7c478bd9Sstevel@tonic-gate  * of the device's fcode.
54*7c478bd9Sstevel@tonic-gate  *
55*7c478bd9Sstevel@tonic-gate  * The interpreter uses the FC_RUN_PRIV ioctl to request privileged
56*7c478bd9Sstevel@tonic-gate  * operations to be run by the driver.
57*7c478bd9Sstevel@tonic-gate  *
58*7c478bd9Sstevel@tonic-gate  * The interpreter sends an FC_VALIDATE ioctl to notify the
59*7c478bd9Sstevel@tonic-gate  * driver that it's done interpreting FCode to signify a normal
60*7c478bd9Sstevel@tonic-gate  * ending sequence when the interpreter later closes the device.
61*7c478bd9Sstevel@tonic-gate  * This way the driver can easily distinguish between the user
62*7c478bd9Sstevel@tonic-gate  * level interpreter failing and finishing normally, thus validating
63*7c478bd9Sstevel@tonic-gate  * the interpreters actions and the state it downloads to the driver.
64*7c478bd9Sstevel@tonic-gate  * The 'arg' value in the FC_VALIDATE ioctl is ignored, there
65*7c478bd9Sstevel@tonic-gate  * are no arguments to this ioctl.
66*7c478bd9Sstevel@tonic-gate  */
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate #define	FCIOC			(0xfc<<8)
69*7c478bd9Sstevel@tonic-gate #define	FC_GET_PARAMETERS	(FCIOC | 1)
70*7c478bd9Sstevel@tonic-gate #define	FC_RUN_PRIV		(FCIOC | 2)
71*7c478bd9Sstevel@tonic-gate #define	FC_VALIDATE		(FCIOC | 3)
72*7c478bd9Sstevel@tonic-gate #define	FC_GET_MY_ARGS		(FCIOC | 4)
73*7c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE_DATA	(FCIOC | 5)
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate #define	FC_GET_MY_ARGS_BUFLEN	256	/* Max my-args length */
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate /*
78*7c478bd9Sstevel@tonic-gate  * FC_GET_PARAMETERS: Expected as the first ioctl after a successful
79*7c478bd9Sstevel@tonic-gate  * open and blocking read (the read returns 0 when there's something
80*7c478bd9Sstevel@tonic-gate  * to interpret).  The ioctl arg is a pointer to an fc_parameters
81*7c478bd9Sstevel@tonic-gate  * data structure which is filled in by the driver with the fcode
82*7c478bd9Sstevel@tonic-gate  * len (if any) and unit address of the new device.
83*7c478bd9Sstevel@tonic-gate  * Offset 0 .. fcode len may be used as the offset to an mmap call to
84*7c478bd9Sstevel@tonic-gate  * provide access to a copy of the device fcode. The unit address is
85*7c478bd9Sstevel@tonic-gate  * returned as a NULL terminated string.
86*7c478bd9Sstevel@tonic-gate  */
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate struct fc_parameters {
89*7c478bd9Sstevel@tonic-gate 	int32_t	fcode_size;
90*7c478bd9Sstevel@tonic-gate 	char	unit_address[OBP_MAXPATHLEN];
91*7c478bd9Sstevel@tonic-gate 	int	config_address;
92*7c478bd9Sstevel@tonic-gate };
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate /*
97*7c478bd9Sstevel@tonic-gate  * FC_RUN_PRIV: The ioctl 'arg' is a pointer to an array of fc_cell_t's
98*7c478bd9Sstevel@tonic-gate  * in the following format:
99*7c478bd9Sstevel@tonic-gate  *
100*7c478bd9Sstevel@tonic-gate  * fc_cell_t[0]: Pointer to a NULL terminated string: service name
101*7c478bd9Sstevel@tonic-gate  * fc_cell_t[1]: Number of input arguments (Call this value 'A')
102*7c478bd9Sstevel@tonic-gate  * fc_cell_t[2]: Number of output result cells allocated (Call this val 'R')
103*7c478bd9Sstevel@tonic-gate  * fc_cell_t[3]: Error Cell (See below)
104*7c478bd9Sstevel@tonic-gate  * fc_cell_t[4]: Priv Violation Cell (non-zero if priv. violation)
105*7c478bd9Sstevel@tonic-gate  * fc_cell_t[5]: Argument cell[0] (Possibly none)
106*7c478bd9Sstevel@tonic-gate  * fc_cell_t[5 + 'A']: Result cell[0] (Possibly none)
107*7c478bd9Sstevel@tonic-gate  *
108*7c478bd9Sstevel@tonic-gate  * The array is variable sized, and must contain a minimum of 5 fc_cell_t's.
109*7c478bd9Sstevel@tonic-gate  * The size (in fc_cell_t's) is 5 + 'A' + 'R'.
110*7c478bd9Sstevel@tonic-gate  *
111*7c478bd9Sstevel@tonic-gate  * The argument cells are filled in by the caller.  The result cells
112*7c478bd9Sstevel@tonic-gate  * (if any) and error cell are returned to the caller by the driver.
113*7c478bd9Sstevel@tonic-gate  * The error cell and priv violation cell are filled in and returned
114*7c478bd9Sstevel@tonic-gate  * to the caller by the driver.
115*7c478bd9Sstevel@tonic-gate  *
116*7c478bd9Sstevel@tonic-gate  * Error Cell Values:
117*7c478bd9Sstevel@tonic-gate  *
118*7c478bd9Sstevel@tonic-gate  *	-1:	The call itself failed (the service name was unknown).
119*7c478bd9Sstevel@tonic-gate  *
120*7c478bd9Sstevel@tonic-gate  *	0:	No error (though the result cells may indicate results
121*7c478bd9Sstevel@tonic-gate  *		that signify an error consistent with the service request.)
122*7c478bd9Sstevel@tonic-gate  *
123*7c478bd9Sstevel@tonic-gate  * Priv Violation Cell Values:
124*7c478bd9Sstevel@tonic-gate  *
125*7c478bd9Sstevel@tonic-gate  *	0:	No priv violation
126*7c478bd9Sstevel@tonic-gate  *
127*7c478bd9Sstevel@tonic-gate  *	-1:	Executing the request caused a priv. violation.
128*7c478bd9Sstevel@tonic-gate  *		For example, an rl@ from an address not mapped in
129*7c478bd9Sstevel@tonic-gate  *		by the interpreter.
130*7c478bd9Sstevel@tonic-gate  */
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate #define	FC_ERR_NONE	fc_int2cell(0)
133*7c478bd9Sstevel@tonic-gate #define	FC_ERR_SVC_NAME	fc_int2cell(-1)
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate #define	FC_PRIV_OK	fc_intcell(0)
136*7c478bd9Sstevel@tonic-gate #define	FC_PRIV_ERROR	fc_int2cell(-1)
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate /*
139*7c478bd9Sstevel@tonic-gate  * Client interface template:
140*7c478bd9Sstevel@tonic-gate  * The actual number of arguments is nargs.
141*7c478bd9Sstevel@tonic-gate  * The actual number of results is nresults.
142*7c478bd9Sstevel@tonic-gate  * The variable array 'v' contains 'nargs + nresults' elements
143*7c478bd9Sstevel@tonic-gate  */
144*7c478bd9Sstevel@tonic-gate struct fc_client_interface {
145*7c478bd9Sstevel@tonic-gate 	fc_cell_t	svc_name;
146*7c478bd9Sstevel@tonic-gate 	fc_cell_t	nargs;
147*7c478bd9Sstevel@tonic-gate 	fc_cell_t	nresults;
148*7c478bd9Sstevel@tonic-gate 	fc_cell_t	error;
149*7c478bd9Sstevel@tonic-gate 	fc_cell_t	priv_error;
150*7c478bd9Sstevel@tonic-gate 	fc_cell_t	v[1];	/* variable array of args and results */
151*7c478bd9Sstevel@tonic-gate };
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate typedef	struct fc_client_interface fc_ci_t;
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate #define	fc_arg(cp, i)		(cp->v[(i)])
156*7c478bd9Sstevel@tonic-gate #define	fc_result(cp, i)	(cp->v[fc_cell2int(cp->nargs) + (i)])
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate #define	FCC_FIXED_CELLS			5
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate /*
161*7c478bd9Sstevel@tonic-gate  * FC_GET_FCODE_DATA: This ioctl allows userland portion of the fcode
162*7c478bd9Sstevel@tonic-gate  * interpreter to get the fcode into a local buffer without having
163*7c478bd9Sstevel@tonic-gate  * to use mmap() interface (which calls hat_getkpfnum() routine).
164*7c478bd9Sstevel@tonic-gate  * This allows DR kernel cage memory to be relocated while this
165*7c478bd9Sstevel@tonic-gate  * fcode buffer is allocated.
166*7c478bd9Sstevel@tonic-gate  *
167*7c478bd9Sstevel@tonic-gate  * The ioctl arg is a pointer to an fc_fcode_info structure which
168*7c478bd9Sstevel@tonic-gate  * has the fcode_size field set with the expected fcode length.
169*7c478bd9Sstevel@tonic-gate  * The driver uses this field to validate correct size before using
170*7c478bd9Sstevel@tonic-gate  * copyout() to fill in the fcode_ptr buffer with fcode data.
171*7c478bd9Sstevel@tonic-gate  */
172*7c478bd9Sstevel@tonic-gate typedef struct fc_fcode_info {
173*7c478bd9Sstevel@tonic-gate 	int32_t	fcode_size;
174*7c478bd9Sstevel@tonic-gate 	char	*fcode_ptr;
175*7c478bd9Sstevel@tonic-gate } fc_fcode_info_t;
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate /*
178*7c478bd9Sstevel@tonic-gate  * The service name len (max) is limited by the size of a method name
179*7c478bd9Sstevel@tonic-gate  */
180*7c478bd9Sstevel@tonic-gate #define	FC_SVC_NAME_LEN		OBP_MAXPROPNAME
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate /*
183*7c478bd9Sstevel@tonic-gate  * "Internally" generated service names ...
184*7c478bd9Sstevel@tonic-gate  */
185*7c478bd9Sstevel@tonic-gate #define	FC_SVC_VALIDATE		"sunos,validate"
186*7c478bd9Sstevel@tonic-gate #define	FC_SVC_INVALIDATE	"sunos,invalidate"
187*7c478bd9Sstevel@tonic-gate #define	FC_SVC_EXIT		"sunos,exit"
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate #define	FC_OPEN_METHOD		"open"
190*7c478bd9Sstevel@tonic-gate #define	FC_CLOSE_METHOD		"close"
191*7c478bd9Sstevel@tonic-gate #define	FC_FIND_FCODE		"$find"
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate /*
194*7c478bd9Sstevel@tonic-gate  * Property related group:
195*7c478bd9Sstevel@tonic-gate  *
196*7c478bd9Sstevel@tonic-gate  * sunos,get*proplen ( propname-cstr phandle -- proplen )
197*7c478bd9Sstevel@tonic-gate  * sunos,get*prop ( propname-cstr buf phandle -- proplen )
198*7c478bd9Sstevel@tonic-gate  *
199*7c478bd9Sstevel@tonic-gate  * sunos,property ( propname-cstr buf len phandle -- )
200*7c478bd9Sstevel@tonic-gate  */
201*7c478bd9Sstevel@tonic-gate 
202*7c478bd9Sstevel@tonic-gate #define	FC_GET_MY_PROPLEN	"sunos,get-my-proplen"
203*7c478bd9Sstevel@tonic-gate #define	FC_GET_MY_PROP		"sunos,get-my-prop"
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate #define	FC_GET_IN_PROPLEN	"sunos,get-inherited-proplen"
206*7c478bd9Sstevel@tonic-gate #define	FC_GET_IN_PROP		"sunos,get-inherited-prop"
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate #define	FC_GET_PKG_PROPLEN	"sunos,get-package-proplen"
209*7c478bd9Sstevel@tonic-gate #define	FC_GET_PKG_PROP		"sunos,get-package-prop"
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate #define	FC_CREATE_PROPERTY	"sunos,property"
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate /*
214*7c478bd9Sstevel@tonic-gate  * Register access and dma ... same as 1275
215*7c478bd9Sstevel@tonic-gate  *
216*7c478bd9Sstevel@tonic-gate  * dma-map-in maps in a suitable aligned user address.
217*7c478bd9Sstevel@tonic-gate  */
218*7c478bd9Sstevel@tonic-gate #define	FC_RL_FETCH		"rl@"
219*7c478bd9Sstevel@tonic-gate #define	FC_RW_FETCH		"rw@"
220*7c478bd9Sstevel@tonic-gate #define	FC_RB_FETCH		"rb@"
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate #define	FC_RL_STORE		"rl!"
223*7c478bd9Sstevel@tonic-gate #define	FC_RW_STORE		"rw!"
224*7c478bd9Sstevel@tonic-gate #define	FC_RB_STORE		"rb!"
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate #define	FC_MAP_IN		"map-in"
227*7c478bd9Sstevel@tonic-gate #define	FC_MAP_OUT		"map-out"
228*7c478bd9Sstevel@tonic-gate #define	FC_DMA_MAP_IN		"dma-map-in"
229*7c478bd9Sstevel@tonic-gate #define	FC_DMA_MAP_OUT		"dma-map-out"
230*7c478bd9Sstevel@tonic-gate 
231*7c478bd9Sstevel@tonic-gate /*
232*7c478bd9Sstevel@tonic-gate  * PCI configuration space access methods ... same as pci binding
233*7c478bd9Sstevel@tonic-gate  */
234*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_L_FETCH	"config-l@"
235*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_W_FETCH	"config-w@"
236*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_B_FETCH	"config-b@"
237*7c478bd9Sstevel@tonic-gate 
238*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_L_STORE	"config-l!"
239*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_W_STORE	"config-w!"
240*7c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_B_STORE	"config-b!"
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate /*
243*7c478bd9Sstevel@tonic-gate  * Device node creation ...
244*7c478bd9Sstevel@tonic-gate  *
245*7c478bd9Sstevel@tonic-gate  * Create a new device with the given name, unit-address, parent.phandle
246*7c478bd9Sstevel@tonic-gate  * with a phandle that must have been previously allocated using
247*7c478bd9Sstevel@tonic-gate  * sunos,alloc-phandle.  finish-device marks the device creation and
248*7c478bd9Sstevel@tonic-gate  * the creation of its properties as complete. (It's a signal to the
249*7c478bd9Sstevel@tonic-gate  * the OS that the node is now reasonably complete.)
250*7c478bd9Sstevel@tonic-gate  *
251*7c478bd9Sstevel@tonic-gate  * sunos,new-device ( name-cstr unit-addr-cstr parent.phandle phandle -- )
252*7c478bd9Sstevel@tonic-gate  * finish-device ( phandle  -- )
253*7c478bd9Sstevel@tonic-gate  */
254*7c478bd9Sstevel@tonic-gate #define	FC_NEW_DEVICE		"sunos,new-device"
255*7c478bd9Sstevel@tonic-gate #define	FC_FINISH_DEVICE	"sunos,finish-device"
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate /*
258*7c478bd9Sstevel@tonic-gate  * Navigation and configuration:
259*7c478bd9Sstevel@tonic-gate  *
260*7c478bd9Sstevel@tonic-gate  * sunos,probe-address ( -- phys.lo ... )
261*7c478bd9Sstevel@tonic-gate  * sunos,probe-space ( -- phys.hi )
262*7c478bd9Sstevel@tonic-gate  *
263*7c478bd9Sstevel@tonic-gate  * sunos,ap-phandle ( -- ap.phandle )
264*7c478bd9Sstevel@tonic-gate  *	Return attachment point phandle
265*7c478bd9Sstevel@tonic-gate  *
266*7c478bd9Sstevel@tonic-gate  * sunos,parent ( child.phandle -- parent.phandle )
267*7c478bd9Sstevel@tonic-gate  *
268*7c478bd9Sstevel@tonic-gate  * child ( parent.phandle -- child.phandle )
269*7c478bd9Sstevel@tonic-gate  * peer ( phandle -- phandle.sibling )
270*7c478bd9Sstevel@tonic-gate  *
271*7c478bd9Sstevel@tonic-gate  * sunos,alloc-phandle ( -- phandle )
272*7c478bd9Sstevel@tonic-gate  * Allocates a unique phandle, not associated with the device tree
273*7c478bd9Sstevel@tonic-gate  *
274*7c478bd9Sstevel@tonic-gate  * sunos,config-child ( -- child.phandle )
275*7c478bd9Sstevel@tonic-gate  * Return the phandle of the child being configured.
276*7c478bd9Sstevel@tonic-gate  */
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate #define	FC_PROBE_ADDRESS	"sunos,probe-address"
279*7c478bd9Sstevel@tonic-gate #define	FC_PROBE_SPACE		"sunos,probe-space"
280*7c478bd9Sstevel@tonic-gate #define	FC_AP_PHANDLE		"sunos,ap-phandle"
281*7c478bd9Sstevel@tonic-gate #define	FC_PARENT		"sunos,parent"
282*7c478bd9Sstevel@tonic-gate #define	FC_CHILD_FCODE		"child"
283*7c478bd9Sstevel@tonic-gate #define	FC_PEER_FCODE		"peer"
284*7c478bd9Sstevel@tonic-gate #define	FC_ALLOC_PHANDLE	"sunos,alloc-phandle"
285*7c478bd9Sstevel@tonic-gate #define	FC_CONFIG_CHILD		"sunos,config-child"
286*7c478bd9Sstevel@tonic-gate 
287*7c478bd9Sstevel@tonic-gate /*
288*7c478bd9Sstevel@tonic-gate  * Fcode Drop In Routines:
289*7c478bd9Sstevel@tonic-gate  * sunos,get_fcode_size ( cstr -- len )
290*7c478bd9Sstevel@tonic-gate  * Returns the size in bytes of the Fcode for a given drop in.
291*7c478bd9Sstevel@tonic-gate  * sunos,get_fcode (cstr buf len -- status? )
292*7c478bd9Sstevel@tonic-gate  * Returns the Fcode image for a given drop in.
293*7c478bd9Sstevel@tonic-gate  */
294*7c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE_SIZE	"sunos,get-fcode-size"
295*7c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE		"sunos,get-fcode"
296*7c478bd9Sstevel@tonic-gate 
297*7c478bd9Sstevel@tonic-gate /*
298*7c478bd9Sstevel@tonic-gate  * kernel internal data structures and interfaces
299*7c478bd9Sstevel@tonic-gate  * for the fcode interpreter.
300*7c478bd9Sstevel@tonic-gate  */
301*7c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate /*
304*7c478bd9Sstevel@tonic-gate  * PCI bus-specific arguments.
305*7c478bd9Sstevel@tonic-gate  *
306*7c478bd9Sstevel@tonic-gate  * We can't get the physical config address of the child from the
307*7c478bd9Sstevel@tonic-gate  * unit address, so we supply it here, along with the child's dip
308*7c478bd9Sstevel@tonic-gate  * as the bus specific argument to pci_ops_alloc_handle.
309*7c478bd9Sstevel@tonic-gate  */
310*7c478bd9Sstevel@tonic-gate 
311*7c478bd9Sstevel@tonic-gate struct pci_ops_bus_args {
312*7c478bd9Sstevel@tonic-gate 	int32_t config_address;		/* phys.hi config addr component */
313*7c478bd9Sstevel@tonic-gate };
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate /*
316*7c478bd9Sstevel@tonic-gate  * Define data structures for resource lists and handle management
317*7c478bd9Sstevel@tonic-gate  *
318*7c478bd9Sstevel@tonic-gate  * 'untyped' resources are managed by the provider.
319*7c478bd9Sstevel@tonic-gate  */
320*7c478bd9Sstevel@tonic-gate struct fc_dma_resource {
321*7c478bd9Sstevel@tonic-gate 	void *virt;
322*7c478bd9Sstevel@tonic-gate 	size_t len;
323*7c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t h;
324*7c478bd9Sstevel@tonic-gate 	uint32_t devaddr;
325*7c478bd9Sstevel@tonic-gate 	struct buf *bp;
326*7c478bd9Sstevel@tonic-gate };
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate struct fc_map_resource {
329*7c478bd9Sstevel@tonic-gate 	void *virt;
330*7c478bd9Sstevel@tonic-gate 	size_t len;
331*7c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t h;
332*7c478bd9Sstevel@tonic-gate 	void *regspec;
333*7c478bd9Sstevel@tonic-gate };
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate struct fc_nodeid_resource {
336*7c478bd9Sstevel@tonic-gate 	int nodeid;		/* An allocated nodeid */
337*7c478bd9Sstevel@tonic-gate };
338*7c478bd9Sstevel@tonic-gate 
339*7c478bd9Sstevel@tonic-gate struct fc_contigious_resource {
340*7c478bd9Sstevel@tonic-gate 	void *virt;
341*7c478bd9Sstevel@tonic-gate 	size_t len;
342*7c478bd9Sstevel@tonic-gate };
343*7c478bd9Sstevel@tonic-gate struct fc_untyped_resource {
344*7c478bd9Sstevel@tonic-gate 	int utype;		/* providers private type field */
345*7c478bd9Sstevel@tonic-gate 	void (*free)(void *);	/* function to free the resource */
346*7c478bd9Sstevel@tonic-gate 	void *resource;		/* Pointer to the resource */
347*7c478bd9Sstevel@tonic-gate };
348*7c478bd9Sstevel@tonic-gate 
349*7c478bd9Sstevel@tonic-gate typedef enum {
350*7c478bd9Sstevel@tonic-gate 	RT_DMA = 0,
351*7c478bd9Sstevel@tonic-gate 	RT_MAP,
352*7c478bd9Sstevel@tonic-gate 	RT_NODEID,
353*7c478bd9Sstevel@tonic-gate 	RT_CONTIGIOUS,
354*7c478bd9Sstevel@tonic-gate 	RT_UNTYPED
355*7c478bd9Sstevel@tonic-gate } fc_resource_type_t;
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate struct fc_resource {
358*7c478bd9Sstevel@tonic-gate 	struct fc_resource *next;
359*7c478bd9Sstevel@tonic-gate 	fc_resource_type_t type;
360*7c478bd9Sstevel@tonic-gate 	union {
361*7c478bd9Sstevel@tonic-gate 		struct fc_dma_resource d;
362*7c478bd9Sstevel@tonic-gate 		struct fc_map_resource m;
363*7c478bd9Sstevel@tonic-gate 		struct fc_nodeid_resource n;
364*7c478bd9Sstevel@tonic-gate 		struct fc_contigious_resource c;
365*7c478bd9Sstevel@tonic-gate 		struct fc_untyped_resource r;
366*7c478bd9Sstevel@tonic-gate 	} un;
367*7c478bd9Sstevel@tonic-gate };
368*7c478bd9Sstevel@tonic-gate 
369*7c478bd9Sstevel@tonic-gate #define	fc_dma_virt	un.d.virt
370*7c478bd9Sstevel@tonic-gate #define	fc_dma_len	un.d.len
371*7c478bd9Sstevel@tonic-gate #define	fc_dma_handle	un.d.h
372*7c478bd9Sstevel@tonic-gate #define	fc_dma_devaddr	un.d.devaddr
373*7c478bd9Sstevel@tonic-gate #define	fc_dma_bp	un.d.bp
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate #define	fc_map_virt	un.m.virt
376*7c478bd9Sstevel@tonic-gate #define	fc_map_len	un.m.len
377*7c478bd9Sstevel@tonic-gate #define	fc_map_handle	un.m.h
378*7c478bd9Sstevel@tonic-gate #define	fc_regspec	un.m.regspec
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate #define	fc_nodeid_r	un.n.nodeid
381*7c478bd9Sstevel@tonic-gate 
382*7c478bd9Sstevel@tonic-gate #define	fc_contig_virt	un.c.virt
383*7c478bd9Sstevel@tonic-gate #define	fc_contig_len	un.c.len
384*7c478bd9Sstevel@tonic-gate 
385*7c478bd9Sstevel@tonic-gate #define	fc_untyped_type	un.r.utype
386*7c478bd9Sstevel@tonic-gate #define	fc_untyped_free	un.r.free
387*7c478bd9Sstevel@tonic-gate #define	fc_untyped_r	un.r.resource
388*7c478bd9Sstevel@tonic-gate 
389*7c478bd9Sstevel@tonic-gate struct fc_phandle_entry {
390*7c478bd9Sstevel@tonic-gate 	struct fc_phandle_entry *next;
391*7c478bd9Sstevel@tonic-gate 	dev_info_t	*dip;
392*7c478bd9Sstevel@tonic-gate 	fc_phandle_t	h;
393*7c478bd9Sstevel@tonic-gate };
394*7c478bd9Sstevel@tonic-gate 
395*7c478bd9Sstevel@tonic-gate extern void fc_phandle_table_alloc(struct fc_phandle_entry **);
396*7c478bd9Sstevel@tonic-gate extern void fc_phandle_table_free(struct fc_phandle_entry **);
397*7c478bd9Sstevel@tonic-gate extern dev_info_t *fc_phandle_to_dip(struct fc_phandle_entry **, fc_phandle_t);
398*7c478bd9Sstevel@tonic-gate extern fc_phandle_t fc_dip_to_phandle(struct fc_phandle_entry **, dev_info_t *);
399*7c478bd9Sstevel@tonic-gate extern void fc_add_dip_to_phandle(struct fc_phandle_entry **, dev_info_t *,
400*7c478bd9Sstevel@tonic-gate     fc_phandle_t);
401*7c478bd9Sstevel@tonic-gate 
402*7c478bd9Sstevel@tonic-gate /*
403*7c478bd9Sstevel@tonic-gate  * Structures and functions for managing our own subtree rooted
404*7c478bd9Sstevel@tonic-gate  * at the attachment point. The parent linkage is established
405*7c478bd9Sstevel@tonic-gate  * at node creation time.  The 'downwards' linkage isn't established
406*7c478bd9Sstevel@tonic-gate  * until the node is bound.
407*7c478bd9Sstevel@tonic-gate  */
408*7c478bd9Sstevel@tonic-gate struct fc_device_tree {
409*7c478bd9Sstevel@tonic-gate 	dev_info_t *dip;
410*7c478bd9Sstevel@tonic-gate 	struct fc_device_tree *child;
411*7c478bd9Sstevel@tonic-gate 	struct fc_device_tree *peer;
412*7c478bd9Sstevel@tonic-gate };
413*7c478bd9Sstevel@tonic-gate 
414*7c478bd9Sstevel@tonic-gate void fc_add_child(dev_info_t *child, dev_info_t *parent,
415*7c478bd9Sstevel@tonic-gate     struct fc_device_tree *head);
416*7c478bd9Sstevel@tonic-gate 
417*7c478bd9Sstevel@tonic-gate void fc_remove_child(dev_info_t *child, struct fc_device_tree *head);
418*7c478bd9Sstevel@tonic-gate 
419*7c478bd9Sstevel@tonic-gate dev_info_t *fc_child_node(dev_info_t *parent, struct fc_device_tree *head);
420*7c478bd9Sstevel@tonic-gate dev_info_t *fc_peer_node(dev_info_t *devi, struct fc_device_tree *head);
421*7c478bd9Sstevel@tonic-gate struct fc_device_tree *fc_find_node(dev_info_t *, struct fc_device_tree *);
422*7c478bd9Sstevel@tonic-gate 
423*7c478bd9Sstevel@tonic-gate void fc_create_device_tree(dev_info_t *ap, struct fc_device_tree **head);
424*7c478bd9Sstevel@tonic-gate void fc_remove_device_tree(struct fc_device_tree **head);
425*7c478bd9Sstevel@tonic-gate 
426*7c478bd9Sstevel@tonic-gate /*
427*7c478bd9Sstevel@tonic-gate  * Our handles represent a list of resources associated with an
428*7c478bd9Sstevel@tonic-gate  * attachment point.  The handles chain, just as the ops functions
429*7c478bd9Sstevel@tonic-gate  * do, with the ops caller responsible for remembering the handle
430*7c478bd9Sstevel@tonic-gate  * of the ops function below it. NB: Externally, this data structure
431*7c478bd9Sstevel@tonic-gate  * is opaque. (Not all members may be present in each chained cookie.)
432*7c478bd9Sstevel@tonic-gate  * For example, the dtree head is valid in only a single instance
433*7c478bd9Sstevel@tonic-gate  * of a set of chained cookies, so use the access function to find it.)
434*7c478bd9Sstevel@tonic-gate  */
435*7c478bd9Sstevel@tonic-gate struct fc_resource_list {
436*7c478bd9Sstevel@tonic-gate 	struct fc_resource *head;
437*7c478bd9Sstevel@tonic-gate 	void *next_handle;		/* next handle in chain */
438*7c478bd9Sstevel@tonic-gate 	dev_info_t *ap;			/* Attachment point dip */
439*7c478bd9Sstevel@tonic-gate 	dev_info_t *child;		/* Child being configured, if any */
440*7c478bd9Sstevel@tonic-gate 	dev_info_t *cdip;		/* Current node, if any */
441*7c478bd9Sstevel@tonic-gate 	int cdip_state;			/* node creation state - see below */
442*7c478bd9Sstevel@tonic-gate 	void *fcode;			/* fcode kernel address */
443*7c478bd9Sstevel@tonic-gate 	size_t fcode_size;		/* fcode size or zero */
444*7c478bd9Sstevel@tonic-gate 	char *unit_address;		/* childs unit address */
445*7c478bd9Sstevel@tonic-gate 	char *my_args;			/* initial setting for my-args */
446*7c478bd9Sstevel@tonic-gate 	void *bus_args;			/* bus dependent arguments */
447*7c478bd9Sstevel@tonic-gate 	struct fc_phandle_entry *ptable; /* devinfo/phandle table */
448*7c478bd9Sstevel@tonic-gate 	struct fc_device_tree *dtree;	/* Our subtree (leaf cookie only) */
449*7c478bd9Sstevel@tonic-gate };
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate typedef struct fc_resource_list *fco_handle_t;
452*7c478bd9Sstevel@tonic-gate 
453*7c478bd9Sstevel@tonic-gate /*
454*7c478bd9Sstevel@tonic-gate  * Values for cdip_state:
455*7c478bd9Sstevel@tonic-gate  */
456*7c478bd9Sstevel@tonic-gate #define	FC_CDIP_NOSTATE		0x00	/* No state - no nodes created */
457*7c478bd9Sstevel@tonic-gate #define	FC_CDIP_STARTED		0x01	/* Node started - dip in cdip */
458*7c478bd9Sstevel@tonic-gate #define	FC_CDIP_DONE		0x02	/* Node finished - last dip in cdip */
459*7c478bd9Sstevel@tonic-gate #define	FC_CDIP_CONFIG		0x10	/* subtree configured */
460*7c478bd9Sstevel@tonic-gate 
461*7c478bd9Sstevel@tonic-gate /*
462*7c478bd9Sstevel@tonic-gate  * Functions to allocate handles for the fcode_interpreter.
463*7c478bd9Sstevel@tonic-gate  *
464*7c478bd9Sstevel@tonic-gate  * This function allocates a handle, used to store resources
465*7c478bd9Sstevel@tonic-gate  * associated with this fcode request including the address of
466*7c478bd9Sstevel@tonic-gate  * the mapped in and copied in fcode and it's size or NULL, 0
467*7c478bd9Sstevel@tonic-gate  * if there is no fcode (the interpreter may look for a drop-in
468*7c478bd9Sstevel@tonic-gate  * driver if there is no fcode), the unit address of child and
469*7c478bd9Sstevel@tonic-gate  * bus specific arguments.  For PCI, the bus specific arguments
470*7c478bd9Sstevel@tonic-gate  * include the child's prototype dip and the config address of
471*7c478bd9Sstevel@tonic-gate  * the child, which can't be derived from the unit address.
472*7c478bd9Sstevel@tonic-gate  *
473*7c478bd9Sstevel@tonic-gate  * The 'handle' returned also contains resource information
474*7c478bd9Sstevel@tonic-gate  * about any allocations of kernel resources that the fcode
475*7c478bd9Sstevel@tonic-gate  * may have created.  Thus, the handle's life is the life
476*7c478bd9Sstevel@tonic-gate  * of the plug-in card and can't be released until the card
477*7c478bd9Sstevel@tonic-gate  * is removed.  Upon release, the resources are released.
478*7c478bd9Sstevel@tonic-gate  */
479*7c478bd9Sstevel@tonic-gate extern fco_handle_t
480*7c478bd9Sstevel@tonic-gate fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
481*7c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address, void *bus_args);
482*7c478bd9Sstevel@tonic-gate 
483*7c478bd9Sstevel@tonic-gate extern fco_handle_t
484*7c478bd9Sstevel@tonic-gate pci_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
485*7c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address,
486*7c478bd9Sstevel@tonic-gate     struct pci_ops_bus_args *bus_args);
487*7c478bd9Sstevel@tonic-gate 
488*7c478bd9Sstevel@tonic-gate extern fco_handle_t
489*7c478bd9Sstevel@tonic-gate gp2_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
490*7c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address,
491*7c478bd9Sstevel@tonic-gate     char *my_args);
492*7c478bd9Sstevel@tonic-gate 
493*7c478bd9Sstevel@tonic-gate extern void pci_fc_ops_free_handle(fco_handle_t handle);
494*7c478bd9Sstevel@tonic-gate extern void gp2_fc_ops_free_handle(fco_handle_t handle);
495*7c478bd9Sstevel@tonic-gate extern void fc_ops_free_handle(fco_handle_t handle);
496*7c478bd9Sstevel@tonic-gate 
497*7c478bd9Sstevel@tonic-gate extern struct fc_phandle_entry **fc_handle_to_phandle_head(fco_handle_t rp);
498*7c478bd9Sstevel@tonic-gate 
499*7c478bd9Sstevel@tonic-gate struct fc_device_tree **fc_handle_to_dtree_head(fco_handle_t);
500*7c478bd9Sstevel@tonic-gate struct fc_device_tree *fc_handle_to_dtree(fco_handle_t);
501*7c478bd9Sstevel@tonic-gate 
502*7c478bd9Sstevel@tonic-gate /*
503*7c478bd9Sstevel@tonic-gate  * fc_ops_t is the main glue back to the framework and attachment point driver
504*7c478bd9Sstevel@tonic-gate  * for privileged driver operations.  The framework/driver provides a pointer
505*7c478bd9Sstevel@tonic-gate  * to the fc_ops function to handle the request given in the args.  The dip
506*7c478bd9Sstevel@tonic-gate  * and handle are passed back to the framework/driver to distinguish
507*7c478bd9Sstevel@tonic-gate  * requests, if necessary.  The argument array is an array of fc_cell_t's
508*7c478bd9Sstevel@tonic-gate  * and is defined in fcode.h
509*7c478bd9Sstevel@tonic-gate  *
510*7c478bd9Sstevel@tonic-gate  * The ops function should return -1 to indicate that the service name is
511*7c478bd9Sstevel@tonic-gate  * unknown and return the value 0 to indicate that the service name was known
512*7c478bd9Sstevel@tonic-gate  * and processed (even if it failed).  ops functions may chain, using the
513*7c478bd9Sstevel@tonic-gate  * return code to communicate if the current function handled the service
514*7c478bd9Sstevel@tonic-gate  * request. Using this technique, the driver can provide certain ops functions
515*7c478bd9Sstevel@tonic-gate  * and allow a framework ops function to handle standardized ops functions,
516*7c478bd9Sstevel@tonic-gate  * or work hand in hand with a framework function so both can handle an op.
517*7c478bd9Sstevel@tonic-gate  * If an ops function is not handled, thus returning -1 to the driver, the
518*7c478bd9Sstevel@tonic-gate  * driver will log an error noting the name of the service and return the
519*7c478bd9Sstevel@tonic-gate  * error to the caller.
520*7c478bd9Sstevel@tonic-gate  */
521*7c478bd9Sstevel@tonic-gate typedef int (fc_ops_t)(dev_info_t *, fco_handle_t, fc_ci_t *);
522*7c478bd9Sstevel@tonic-gate 
523*7c478bd9Sstevel@tonic-gate extern fc_ops_t fc_ops;
524*7c478bd9Sstevel@tonic-gate extern fc_ops_t pci_fc_ops;
525*7c478bd9Sstevel@tonic-gate extern fc_ops_t gp2_fc_ops;
526*7c478bd9Sstevel@tonic-gate 
527*7c478bd9Sstevel@tonic-gate /*
528*7c478bd9Sstevel@tonic-gate  * Internal structure used to enque an fcode request
529*7c478bd9Sstevel@tonic-gate  * The 'next' and 'busy' fields are protected by a mutex.
530*7c478bd9Sstevel@tonic-gate  * Thread synchronization is accomplished via use of the 'busy' field.
531*7c478bd9Sstevel@tonic-gate  */
532*7c478bd9Sstevel@tonic-gate struct fc_request {
533*7c478bd9Sstevel@tonic-gate 	struct fc_request *next;	/* Next in chain (private) */
534*7c478bd9Sstevel@tonic-gate 	int		busy;		/* Waiters flag (private; see below) */
535*7c478bd9Sstevel@tonic-gate 	int		error;		/* Interpreter return code (private) */
536*7c478bd9Sstevel@tonic-gate 	dev_info_t	*ap_dip;	/* Attachment point. ie: pci nexus */
537*7c478bd9Sstevel@tonic-gate 	fc_ops_t	*ap_ops;	/* driver's fcode ops function */
538*7c478bd9Sstevel@tonic-gate 	fco_handle_t	handle;		/* Caller's private identifier */
539*7c478bd9Sstevel@tonic-gate 	timeout_id_t	timeout;	/* Timeout identifier */
540*7c478bd9Sstevel@tonic-gate };
541*7c478bd9Sstevel@tonic-gate 
542*7c478bd9Sstevel@tonic-gate /*
543*7c478bd9Sstevel@tonic-gate  * Values for 'busy'.  The requester initializes the field to FC_R_INIT (0),
544*7c478bd9Sstevel@tonic-gate  * then waits for it be set to FC_R_DONE.  The framework sets it to
545*7c478bd9Sstevel@tonic-gate  * FC_R_BUSY while working on the request so it can distinguish between
546*7c478bd9Sstevel@tonic-gate  * an inactive and an active request.
547*7c478bd9Sstevel@tonic-gate  */
548*7c478bd9Sstevel@tonic-gate #define	FC_R_INIT	0		/* initialized, on queue */
549*7c478bd9Sstevel@tonic-gate #define	FC_R_BUSY	1		/* request is active, busy */
550*7c478bd9Sstevel@tonic-gate #define	FC_R_DONE	2		/* request is done and may be deq'd */
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate /*
553*7c478bd9Sstevel@tonic-gate  * Values for 'error'.
554*7c478bd9Sstevel@tonic-gate  */
555*7c478bd9Sstevel@tonic-gate #define	FC_SUCCESS	0		/* FCode interpreted successfully */
556*7c478bd9Sstevel@tonic-gate #define	FC_TIMEOUT	1		/* Timer expired */
557*7c478bd9Sstevel@tonic-gate #define	FC_ERROR	-1		/* Interpreter error */
558*7c478bd9Sstevel@tonic-gate 
559*7c478bd9Sstevel@tonic-gate /*
560*7c478bd9Sstevel@tonic-gate  * Function to call to invoke the fcode interpreter.
561*7c478bd9Sstevel@tonic-gate  *
562*7c478bd9Sstevel@tonic-gate  * This function will wait and return when the interpreter either
563*7c478bd9Sstevel@tonic-gate  * completes successfully or fails, returning pass/fail status as
564*7c478bd9Sstevel@tonic-gate  * the return code.  Interim calls to the driver's ops function will
565*7c478bd9Sstevel@tonic-gate  * be made for both priv. ops and to create device nodes and properties.
566*7c478bd9Sstevel@tonic-gate  *
567*7c478bd9Sstevel@tonic-gate  * Calling this function will log a message to userland to request the
568*7c478bd9Sstevel@tonic-gate  * eventd to start the userland fcode interpreter process. The interpreter
569*7c478bd9Sstevel@tonic-gate  * opens /dev/fcode, which clones an instance of the driver, and then
570*7c478bd9Sstevel@tonic-gate  * waits in a 'read' until there's an active request.
571*7c478bd9Sstevel@tonic-gate  * XXX: For the prototype, we can start it manually or use an init.d script.
572*7c478bd9Sstevel@tonic-gate  *
573*7c478bd9Sstevel@tonic-gate  * 'ap' is the attachment point dip: that is, the driving parent's dev_info_t
574*7c478bd9Sstevel@tonic-gate  * ie: for pci devices, this will be the dip of the pci nexus.
575*7c478bd9Sstevel@tonic-gate  *
576*7c478bd9Sstevel@tonic-gate  * The 'handle' is provided for the caller, and can be used to
577*7c478bd9Sstevel@tonic-gate  * identify the request along with the attachment point dip, both
578*7c478bd9Sstevel@tonic-gate  * of which will be passed back to the driver's ops function.
579*7c478bd9Sstevel@tonic-gate  * The handle is allocated first by calling a bus-specific
580*7c478bd9Sstevel@tonic-gate  * <bus>_ops_handle_alloc function.
581*7c478bd9Sstevel@tonic-gate  *
582*7c478bd9Sstevel@tonic-gate  * ops functions may chain; an ops function should return -1 if
583*7c478bd9Sstevel@tonic-gate  * the call was not recognized, or 0 if the call was recognized.
584*7c478bd9Sstevel@tonic-gate  */
585*7c478bd9Sstevel@tonic-gate extern int fcode_interpreter(dev_info_t *, fc_ops_t *, fco_handle_t);
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate /*
588*7c478bd9Sstevel@tonic-gate  * The fcode implementation uses this function to wait for and 'de-queue'
589*7c478bd9Sstevel@tonic-gate  * an fcode request.  It's triggered by a 'read' request from the
590*7c478bd9Sstevel@tonic-gate  * userland interpreter. It uses a 'sig' form of waiting (cv_wait_sig),
591*7c478bd9Sstevel@tonic-gate  * so the interpreter can interrupt the read.
592*7c478bd9Sstevel@tonic-gate  */
593*7c478bd9Sstevel@tonic-gate extern struct fc_request *fc_get_request(void);
594*7c478bd9Sstevel@tonic-gate 
595*7c478bd9Sstevel@tonic-gate /*
596*7c478bd9Sstevel@tonic-gate  * When the fcode implementation is finished servicing a request, it calls this
597*7c478bd9Sstevel@tonic-gate  * function to mark the request as done and to signal the originating thread
598*7c478bd9Sstevel@tonic-gate  * (now waiting in fcode_interpreter) that the request is done.
599*7c478bd9Sstevel@tonic-gate  */
600*7c478bd9Sstevel@tonic-gate extern void fc_finish_request(struct fc_request *);
601*7c478bd9Sstevel@tonic-gate 
602*7c478bd9Sstevel@tonic-gate /*
603*7c478bd9Sstevel@tonic-gate  * The fcode implementation uses these functions to manage
604*7c478bd9Sstevel@tonic-gate  * resource items and resource lists ...
605*7c478bd9Sstevel@tonic-gate  */
606*7c478bd9Sstevel@tonic-gate extern void fc_add_resource(fco_handle_t, struct fc_resource *);
607*7c478bd9Sstevel@tonic-gate extern void fc_rem_resource(fco_handle_t, struct fc_resource *);
608*7c478bd9Sstevel@tonic-gate extern void fc_lock_resource_list(fco_handle_t);
609*7c478bd9Sstevel@tonic-gate extern void fc_unlock_resource_list(fco_handle_t);
610*7c478bd9Sstevel@tonic-gate 
611*7c478bd9Sstevel@tonic-gate /*
612*7c478bd9Sstevel@tonic-gate  * ops common and helper functions
613*7c478bd9Sstevel@tonic-gate  */
614*7c478bd9Sstevel@tonic-gate extern int fc_fail_op(dev_info_t *, fco_handle_t, fc_ci_t *);
615*7c478bd9Sstevel@tonic-gate extern int fc_success_op(dev_info_t *, fco_handle_t, fc_ci_t *);
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate extern int fc_syntax_error(fc_ci_t *, char *);
618*7c478bd9Sstevel@tonic-gate extern int fc_priv_error(fc_ci_t *, char *);
619*7c478bd9Sstevel@tonic-gate 
620*7c478bd9Sstevel@tonic-gate /*
621*7c478bd9Sstevel@tonic-gate  * Recharacterized ddi functions we need to define ...
622*7c478bd9Sstevel@tonic-gate  *
623*7c478bd9Sstevel@tonic-gate  * The only difference is we call through the attachment point driver,
624*7c478bd9Sstevel@tonic-gate  * as a proxy for the child that isn't yet attached. The ddi functions
625*7c478bd9Sstevel@tonic-gate  * optimize these functions by not necessarily calling through the
626*7c478bd9Sstevel@tonic-gate  * attachment point driver.
627*7c478bd9Sstevel@tonic-gate  */
628*7c478bd9Sstevel@tonic-gate int fc_ddi_dma_htoc(dev_info_t *, ddi_dma_handle_t, off_t, ddi_dma_cookie_t *);
629*7c478bd9Sstevel@tonic-gate int fc_ddi_dma_free(dev_info_t *ap, ddi_dma_handle_t h);
630*7c478bd9Sstevel@tonic-gate int fc_ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom);
631*7c478bd9Sstevel@tonic-gate 
632*7c478bd9Sstevel@tonic-gate /*
633*7c478bd9Sstevel@tonic-gate  * The ndi prop functions aren't appropriate for the interpreter.
634*7c478bd9Sstevel@tonic-gate  * We create byte-array, untyped properties.
635*7c478bd9Sstevel@tonic-gate  */
636*7c478bd9Sstevel@tonic-gate 
637*7c478bd9Sstevel@tonic-gate int fc_ndi_prop_update(dev_t, dev_info_t *, char *, uchar_t *, uint_t);
638*7c478bd9Sstevel@tonic-gate 
639*7c478bd9Sstevel@tonic-gate /*
640*7c478bd9Sstevel@tonic-gate  * The setup and teardown parts of physio()
641*7c478bd9Sstevel@tonic-gate  */
642*7c478bd9Sstevel@tonic-gate int fc_physio_setup(struct buf **bpp, void *io_base, size_t io_len);
643*7c478bd9Sstevel@tonic-gate void fc_physio_free(struct buf **bpp, void *io_base, size_t io_len);
644*7c478bd9Sstevel@tonic-gate 
645*7c478bd9Sstevel@tonic-gate /*
646*7c478bd9Sstevel@tonic-gate  * debugging macros
647*7c478bd9Sstevel@tonic-gate  */
648*7c478bd9Sstevel@tonic-gate extern int fcode_debug;
649*7c478bd9Sstevel@tonic-gate #define	dcmn_err(level, args) if (fcode_debug >= level) cmn_err args
650*7c478bd9Sstevel@tonic-gate 
651*7c478bd9Sstevel@tonic-gate #ifdef DEBUG
652*7c478bd9Sstevel@tonic-gate 
653*7c478bd9Sstevel@tonic-gate void fc_debug(char *, uintptr_t, uintptr_t,
654*7c478bd9Sstevel@tonic-gate     uintptr_t, uintptr_t, uintptr_t);
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG0(level, flag, s) if (fcode_debug >= level) \
657*7c478bd9Sstevel@tonic-gate     fc_debug(s, 0, 0, 0, 0, 0)
658*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG1(level, flag, fmt, a1) if (fcode_debug >= level) \
659*7c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
660*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG2(level, flag, fmt, a1, a2) if (fcode_debug >= level) \
661*7c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
662*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG3(level, flag, fmt, a1, a2, a3) \
663*7c478bd9Sstevel@tonic-gate     if (fcode_debug >= level) \
664*7c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0);
665*7c478bd9Sstevel@tonic-gate #else
666*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG0(level, flag, s)
667*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG1(level, flag, fmt, a1)
668*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG2(level, flag, fmt, a1, a2)
669*7c478bd9Sstevel@tonic-gate #define	FC_DEBUG3(level, flag, fmt, a1, a2, a3)
670*7c478bd9Sstevel@tonic-gate #endif
671*7c478bd9Sstevel@tonic-gate 
672*7c478bd9Sstevel@tonic-gate 
673*7c478bd9Sstevel@tonic-gate #endif	/* defined(_KERNEL) */
674*7c478bd9Sstevel@tonic-gate 
675*7c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
676*7c478bd9Sstevel@tonic-gate }
677*7c478bd9Sstevel@tonic-gate #endif
678*7c478bd9Sstevel@tonic-gate 
679*7c478bd9Sstevel@tonic-gate #endif	/* _SYS_FCODE_H */
680