xref: /titanic_53/usr/src/uts/sun4/sys/fcode.h (revision 4ab75253616c6d68e967c10221bb663c0bfa99df)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*4ab75253Smrj  * Common Development and Distribution License (the "License").
6*4ab75253Smrj  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
226d22b733Sdhain  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #ifndef	_SYS_FCODE_H
277c478bd9Sstevel@tonic-gate #define	_SYS_FCODE_H
287c478bd9Sstevel@tonic-gate 
297c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
327c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
337c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
347c478bd9Sstevel@tonic-gate #include <sys/fc_plat.h>
357c478bd9Sstevel@tonic-gate #include <sys/pci.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
387c478bd9Sstevel@tonic-gate extern "C" {
397c478bd9Sstevel@tonic-gate #endif
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate /*
427c478bd9Sstevel@tonic-gate  * The FCode driver presents a private interface to the fcode
437c478bd9Sstevel@tonic-gate  * user level interpreter.  This interface is subject to change
447c478bd9Sstevel@tonic-gate  * at any time and is only provided for use by the fcode interpreter.
457c478bd9Sstevel@tonic-gate  *
467c478bd9Sstevel@tonic-gate  * The user program opens the device, causing a new instance of
477c478bd9Sstevel@tonic-gate  * the driver to be cloned.  This instance is specific to a specific
487c478bd9Sstevel@tonic-gate  * instance of a new device managed by the kernel and driver framework.
497c478bd9Sstevel@tonic-gate  *
507c478bd9Sstevel@tonic-gate  * The interpreter does an FC_GET_PARAMETERS ioctl to get the fcode
517c478bd9Sstevel@tonic-gate  * length, which can be mmap-ed (at offset 0) to provide access to a copy
527c478bd9Sstevel@tonic-gate  * of the device's fcode.
537c478bd9Sstevel@tonic-gate  *
547c478bd9Sstevel@tonic-gate  * The interpreter uses the FC_RUN_PRIV ioctl to request privileged
557c478bd9Sstevel@tonic-gate  * operations to be run by the driver.
567c478bd9Sstevel@tonic-gate  *
577c478bd9Sstevel@tonic-gate  * The interpreter sends an FC_VALIDATE ioctl to notify the
587c478bd9Sstevel@tonic-gate  * driver that it's done interpreting FCode to signify a normal
597c478bd9Sstevel@tonic-gate  * ending sequence when the interpreter later closes the device.
607c478bd9Sstevel@tonic-gate  * This way the driver can easily distinguish between the user
617c478bd9Sstevel@tonic-gate  * level interpreter failing and finishing normally, thus validating
627c478bd9Sstevel@tonic-gate  * the interpreters actions and the state it downloads to the driver.
637c478bd9Sstevel@tonic-gate  * The 'arg' value in the FC_VALIDATE ioctl is ignored, there
647c478bd9Sstevel@tonic-gate  * are no arguments to this ioctl.
657c478bd9Sstevel@tonic-gate  */
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate #define	FCIOC			(0xfc<<8)
687c478bd9Sstevel@tonic-gate #define	FC_GET_PARAMETERS	(FCIOC | 1)
697c478bd9Sstevel@tonic-gate #define	FC_RUN_PRIV		(FCIOC | 2)
707c478bd9Sstevel@tonic-gate #define	FC_VALIDATE		(FCIOC | 3)
717c478bd9Sstevel@tonic-gate #define	FC_GET_MY_ARGS		(FCIOC | 4)
727c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE_DATA	(FCIOC | 5)
736d22b733Sdhain #define	FC_SET_FCODE_ERROR	(FCIOC | 6)
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate #define	FC_GET_MY_ARGS_BUFLEN	256	/* Max my-args length */
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * FC_GET_PARAMETERS: Expected as the first ioctl after a successful
797c478bd9Sstevel@tonic-gate  * open and blocking read (the read returns 0 when there's something
807c478bd9Sstevel@tonic-gate  * to interpret).  The ioctl arg is a pointer to an fc_parameters
817c478bd9Sstevel@tonic-gate  * data structure which is filled in by the driver with the fcode
827c478bd9Sstevel@tonic-gate  * len (if any) and unit address of the new device.
837c478bd9Sstevel@tonic-gate  * Offset 0 .. fcode len may be used as the offset to an mmap call to
847c478bd9Sstevel@tonic-gate  * provide access to a copy of the device fcode. The unit address is
857c478bd9Sstevel@tonic-gate  * returned as a NULL terminated string.
867c478bd9Sstevel@tonic-gate  */
877c478bd9Sstevel@tonic-gate 
887c478bd9Sstevel@tonic-gate struct fc_parameters {
897c478bd9Sstevel@tonic-gate 	int32_t	fcode_size;
907c478bd9Sstevel@tonic-gate 	char	unit_address[OBP_MAXPATHLEN];
917c478bd9Sstevel@tonic-gate 	int	config_address;
927c478bd9Sstevel@tonic-gate };
937c478bd9Sstevel@tonic-gate 
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate 
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  * FC_RUN_PRIV: The ioctl 'arg' is a pointer to an array of fc_cell_t's
987c478bd9Sstevel@tonic-gate  * in the following format:
997c478bd9Sstevel@tonic-gate  *
1007c478bd9Sstevel@tonic-gate  * fc_cell_t[0]: Pointer to a NULL terminated string: service name
1017c478bd9Sstevel@tonic-gate  * fc_cell_t[1]: Number of input arguments (Call this value 'A')
1027c478bd9Sstevel@tonic-gate  * fc_cell_t[2]: Number of output result cells allocated (Call this val 'R')
1037c478bd9Sstevel@tonic-gate  * fc_cell_t[3]: Error Cell (See below)
1047c478bd9Sstevel@tonic-gate  * fc_cell_t[4]: Priv Violation Cell (non-zero if priv. violation)
1057c478bd9Sstevel@tonic-gate  * fc_cell_t[5]: Argument cell[0] (Possibly none)
1067c478bd9Sstevel@tonic-gate  * fc_cell_t[5 + 'A']: Result cell[0] (Possibly none)
1077c478bd9Sstevel@tonic-gate  *
1087c478bd9Sstevel@tonic-gate  * The array is variable sized, and must contain a minimum of 5 fc_cell_t's.
1097c478bd9Sstevel@tonic-gate  * The size (in fc_cell_t's) is 5 + 'A' + 'R'.
1107c478bd9Sstevel@tonic-gate  *
1117c478bd9Sstevel@tonic-gate  * The argument cells are filled in by the caller.  The result cells
1127c478bd9Sstevel@tonic-gate  * (if any) and error cell are returned to the caller by the driver.
1137c478bd9Sstevel@tonic-gate  * The error cell and priv violation cell are filled in and returned
1147c478bd9Sstevel@tonic-gate  * to the caller by the driver.
1157c478bd9Sstevel@tonic-gate  *
1167c478bd9Sstevel@tonic-gate  * Error Cell Values:
1177c478bd9Sstevel@tonic-gate  *
1187c478bd9Sstevel@tonic-gate  *	-1:	The call itself failed (the service name was unknown).
1197c478bd9Sstevel@tonic-gate  *
1207c478bd9Sstevel@tonic-gate  *	0:	No error (though the result cells may indicate results
1217c478bd9Sstevel@tonic-gate  *		that signify an error consistent with the service request.)
1227c478bd9Sstevel@tonic-gate  *
1237c478bd9Sstevel@tonic-gate  * Priv Violation Cell Values:
1247c478bd9Sstevel@tonic-gate  *
1257c478bd9Sstevel@tonic-gate  *	0:	No priv violation
1267c478bd9Sstevel@tonic-gate  *
1277c478bd9Sstevel@tonic-gate  *	-1:	Executing the request caused a priv. violation.
1287c478bd9Sstevel@tonic-gate  *		For example, an rl@ from an address not mapped in
1297c478bd9Sstevel@tonic-gate  *		by the interpreter.
1307c478bd9Sstevel@tonic-gate  */
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate #define	FC_ERR_NONE	fc_int2cell(0)
1337c478bd9Sstevel@tonic-gate #define	FC_ERR_SVC_NAME	fc_int2cell(-1)
1347c478bd9Sstevel@tonic-gate 
1357c478bd9Sstevel@tonic-gate #define	FC_PRIV_OK	fc_intcell(0)
1367c478bd9Sstevel@tonic-gate #define	FC_PRIV_ERROR	fc_int2cell(-1)
1377c478bd9Sstevel@tonic-gate 
1387c478bd9Sstevel@tonic-gate /*
1397c478bd9Sstevel@tonic-gate  * Client interface template:
1407c478bd9Sstevel@tonic-gate  * The actual number of arguments is nargs.
1417c478bd9Sstevel@tonic-gate  * The actual number of results is nresults.
1427c478bd9Sstevel@tonic-gate  * The variable array 'v' contains 'nargs + nresults' elements
1437c478bd9Sstevel@tonic-gate  */
1447c478bd9Sstevel@tonic-gate struct fc_client_interface {
1457c478bd9Sstevel@tonic-gate 	fc_cell_t	svc_name;
1467c478bd9Sstevel@tonic-gate 	fc_cell_t	nargs;
1477c478bd9Sstevel@tonic-gate 	fc_cell_t	nresults;
1487c478bd9Sstevel@tonic-gate 	fc_cell_t	error;
1497c478bd9Sstevel@tonic-gate 	fc_cell_t	priv_error;
1507c478bd9Sstevel@tonic-gate 	fc_cell_t	v[1];	/* variable array of args and results */
1517c478bd9Sstevel@tonic-gate };
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate typedef	struct fc_client_interface fc_ci_t;
1547c478bd9Sstevel@tonic-gate 
1557c478bd9Sstevel@tonic-gate #define	fc_arg(cp, i)		(cp->v[(i)])
1567c478bd9Sstevel@tonic-gate #define	fc_result(cp, i)	(cp->v[fc_cell2int(cp->nargs) + (i)])
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate #define	FCC_FIXED_CELLS			5
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /*
1617c478bd9Sstevel@tonic-gate  * FC_GET_FCODE_DATA: This ioctl allows userland portion of the fcode
1627c478bd9Sstevel@tonic-gate  * interpreter to get the fcode into a local buffer without having
1637c478bd9Sstevel@tonic-gate  * to use mmap() interface (which calls hat_getkpfnum() routine).
1647c478bd9Sstevel@tonic-gate  * This allows DR kernel cage memory to be relocated while this
1657c478bd9Sstevel@tonic-gate  * fcode buffer is allocated.
1667c478bd9Sstevel@tonic-gate  *
1677c478bd9Sstevel@tonic-gate  * The ioctl arg is a pointer to an fc_fcode_info structure which
1687c478bd9Sstevel@tonic-gate  * has the fcode_size field set with the expected fcode length.
1697c478bd9Sstevel@tonic-gate  * The driver uses this field to validate correct size before using
1707c478bd9Sstevel@tonic-gate  * copyout() to fill in the fcode_ptr buffer with fcode data.
1717c478bd9Sstevel@tonic-gate  */
1727c478bd9Sstevel@tonic-gate typedef struct fc_fcode_info {
1737c478bd9Sstevel@tonic-gate 	int32_t	fcode_size;
1747c478bd9Sstevel@tonic-gate 	char	*fcode_ptr;
1757c478bd9Sstevel@tonic-gate } fc_fcode_info_t;
1767c478bd9Sstevel@tonic-gate 
1777c478bd9Sstevel@tonic-gate /*
1787c478bd9Sstevel@tonic-gate  * The service name len (max) is limited by the size of a method name
1797c478bd9Sstevel@tonic-gate  */
1807c478bd9Sstevel@tonic-gate #define	FC_SVC_NAME_LEN		OBP_MAXPROPNAME
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate /*
1837c478bd9Sstevel@tonic-gate  * "Internally" generated service names ...
1847c478bd9Sstevel@tonic-gate  */
1857c478bd9Sstevel@tonic-gate #define	FC_SVC_VALIDATE		"sunos,validate"
1867c478bd9Sstevel@tonic-gate #define	FC_SVC_INVALIDATE	"sunos,invalidate"
1877c478bd9Sstevel@tonic-gate #define	FC_SVC_EXIT		"sunos,exit"
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #define	FC_OPEN_METHOD		"open"
1907c478bd9Sstevel@tonic-gate #define	FC_CLOSE_METHOD		"close"
1917c478bd9Sstevel@tonic-gate #define	FC_FIND_FCODE		"$find"
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*
1947c478bd9Sstevel@tonic-gate  * Property related group:
1957c478bd9Sstevel@tonic-gate  *
1967c478bd9Sstevel@tonic-gate  * sunos,get*proplen ( propname-cstr phandle -- proplen )
1977c478bd9Sstevel@tonic-gate  * sunos,get*prop ( propname-cstr buf phandle -- proplen )
1987c478bd9Sstevel@tonic-gate  *
1997c478bd9Sstevel@tonic-gate  * sunos,property ( propname-cstr buf len phandle -- )
2007c478bd9Sstevel@tonic-gate  */
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate #define	FC_GET_MY_PROPLEN	"sunos,get-my-proplen"
2037c478bd9Sstevel@tonic-gate #define	FC_GET_MY_PROP		"sunos,get-my-prop"
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate #define	FC_GET_IN_PROPLEN	"sunos,get-inherited-proplen"
2067c478bd9Sstevel@tonic-gate #define	FC_GET_IN_PROP		"sunos,get-inherited-prop"
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate #define	FC_GET_PKG_PROPLEN	"sunos,get-package-proplen"
2097c478bd9Sstevel@tonic-gate #define	FC_GET_PKG_PROP		"sunos,get-package-prop"
2107c478bd9Sstevel@tonic-gate 
2117c478bd9Sstevel@tonic-gate #define	FC_CREATE_PROPERTY	"sunos,property"
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate /*
2147c478bd9Sstevel@tonic-gate  * Register access and dma ... same as 1275
2157c478bd9Sstevel@tonic-gate  *
2167c478bd9Sstevel@tonic-gate  * dma-map-in maps in a suitable aligned user address.
2177c478bd9Sstevel@tonic-gate  */
2187c478bd9Sstevel@tonic-gate #define	FC_RL_FETCH		"rl@"
2197c478bd9Sstevel@tonic-gate #define	FC_RW_FETCH		"rw@"
2207c478bd9Sstevel@tonic-gate #define	FC_RB_FETCH		"rb@"
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate #define	FC_RL_STORE		"rl!"
2237c478bd9Sstevel@tonic-gate #define	FC_RW_STORE		"rw!"
2247c478bd9Sstevel@tonic-gate #define	FC_RB_STORE		"rb!"
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate #define	FC_MAP_IN		"map-in"
2277c478bd9Sstevel@tonic-gate #define	FC_MAP_OUT		"map-out"
2287c478bd9Sstevel@tonic-gate #define	FC_DMA_MAP_IN		"dma-map-in"
2297c478bd9Sstevel@tonic-gate #define	FC_DMA_MAP_OUT		"dma-map-out"
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate /*
2327c478bd9Sstevel@tonic-gate  * PCI configuration space access methods ... same as pci binding
2337c478bd9Sstevel@tonic-gate  */
2347c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_L_FETCH	"config-l@"
2357c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_W_FETCH	"config-w@"
2367c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_B_FETCH	"config-b@"
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_L_STORE	"config-l!"
2397c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_W_STORE	"config-w!"
2407c478bd9Sstevel@tonic-gate #define	FC_PCI_CFG_B_STORE	"config-b!"
2417c478bd9Sstevel@tonic-gate 
2427c478bd9Sstevel@tonic-gate /*
2437c478bd9Sstevel@tonic-gate  * Device node creation ...
2447c478bd9Sstevel@tonic-gate  *
2457c478bd9Sstevel@tonic-gate  * Create a new device with the given name, unit-address, parent.phandle
2467c478bd9Sstevel@tonic-gate  * with a phandle that must have been previously allocated using
2477c478bd9Sstevel@tonic-gate  * sunos,alloc-phandle.  finish-device marks the device creation and
2487c478bd9Sstevel@tonic-gate  * the creation of its properties as complete. (It's a signal to the
2497c478bd9Sstevel@tonic-gate  * the OS that the node is now reasonably complete.)
2507c478bd9Sstevel@tonic-gate  *
2517c478bd9Sstevel@tonic-gate  * sunos,new-device ( name-cstr unit-addr-cstr parent.phandle phandle -- )
2527c478bd9Sstevel@tonic-gate  * finish-device ( phandle  -- )
2537c478bd9Sstevel@tonic-gate  */
2547c478bd9Sstevel@tonic-gate #define	FC_NEW_DEVICE		"sunos,new-device"
2557c478bd9Sstevel@tonic-gate #define	FC_FINISH_DEVICE	"sunos,finish-device"
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate /*
2587c478bd9Sstevel@tonic-gate  * Navigation and configuration:
2597c478bd9Sstevel@tonic-gate  *
2607c478bd9Sstevel@tonic-gate  * sunos,probe-address ( -- phys.lo ... )
2617c478bd9Sstevel@tonic-gate  * sunos,probe-space ( -- phys.hi )
2627c478bd9Sstevel@tonic-gate  *
2637c478bd9Sstevel@tonic-gate  * sunos,ap-phandle ( -- ap.phandle )
2647c478bd9Sstevel@tonic-gate  *	Return attachment point phandle
2657c478bd9Sstevel@tonic-gate  *
2667c478bd9Sstevel@tonic-gate  * sunos,parent ( child.phandle -- parent.phandle )
2677c478bd9Sstevel@tonic-gate  *
2687c478bd9Sstevel@tonic-gate  * child ( parent.phandle -- child.phandle )
2697c478bd9Sstevel@tonic-gate  * peer ( phandle -- phandle.sibling )
2707c478bd9Sstevel@tonic-gate  *
2717c478bd9Sstevel@tonic-gate  * sunos,alloc-phandle ( -- phandle )
2727c478bd9Sstevel@tonic-gate  * Allocates a unique phandle, not associated with the device tree
2737c478bd9Sstevel@tonic-gate  *
2747c478bd9Sstevel@tonic-gate  * sunos,config-child ( -- child.phandle )
2757c478bd9Sstevel@tonic-gate  * Return the phandle of the child being configured.
2767c478bd9Sstevel@tonic-gate  */
2777c478bd9Sstevel@tonic-gate 
2787c478bd9Sstevel@tonic-gate #define	FC_PROBE_ADDRESS	"sunos,probe-address"
2797c478bd9Sstevel@tonic-gate #define	FC_PROBE_SPACE		"sunos,probe-space"
2807c478bd9Sstevel@tonic-gate #define	FC_AP_PHANDLE		"sunos,ap-phandle"
2817c478bd9Sstevel@tonic-gate #define	FC_PARENT		"sunos,parent"
2827c478bd9Sstevel@tonic-gate #define	FC_CHILD_FCODE		"child"
2837c478bd9Sstevel@tonic-gate #define	FC_PEER_FCODE		"peer"
2847c478bd9Sstevel@tonic-gate #define	FC_ALLOC_PHANDLE	"sunos,alloc-phandle"
2857c478bd9Sstevel@tonic-gate #define	FC_CONFIG_CHILD		"sunos,config-child"
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate  * Fcode Drop In Routines:
2897c478bd9Sstevel@tonic-gate  * sunos,get_fcode_size ( cstr -- len )
2907c478bd9Sstevel@tonic-gate  * Returns the size in bytes of the Fcode for a given drop in.
2917c478bd9Sstevel@tonic-gate  * sunos,get_fcode (cstr buf len -- status? )
2927c478bd9Sstevel@tonic-gate  * Returns the Fcode image for a given drop in.
2937c478bd9Sstevel@tonic-gate  */
2947c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE_SIZE	"sunos,get-fcode-size"
2957c478bd9Sstevel@tonic-gate #define	FC_GET_FCODE		"sunos,get-fcode"
2967c478bd9Sstevel@tonic-gate 
2977c478bd9Sstevel@tonic-gate /*
2986d22b733Sdhain  * Values for fc_request 'error'. This has been moved from the _KERNEL
2996d22b733Sdhain  * area to allow the FC_SET_FCODE_ERROR ioctl to use these values to
3006d22b733Sdhain  * signal the kernel as to the disposition of the userland interpreter.
3016d22b733Sdhain  * NOTE: Positive values are used to indicate a kernel error,
3026d22b733Sdhain  * negative values are used to identify userland interpreter errors.
3036d22b733Sdhain  */
3046d22b733Sdhain #define	FC_SUCCESS	0		/* FCode interpreted successfully */
3056d22b733Sdhain #define	FC_TIMEOUT	1		/* Timer expired */
3066d22b733Sdhain #define	FC_ERROR	-1		/* Interpreter error */
3076d22b733Sdhain #define	FC_EXEC_FAILED	-2		/* Interpreter failed to exec */
3086d22b733Sdhain #define	FC_NO_FCODE	-3		/* Interpreter couldn't find fcode */
3096d22b733Sdhain #define	FC_FCODE_ABORT	-4		/* Interpreter called exit(1) */
3106d22b733Sdhain #define	FC_ERROR_VALID(s) ((s) >= FC_FCODE_ABORT) && ((s) <= FC_TIMEOUT)
3116d22b733Sdhain 
3126d22b733Sdhain /*
3137c478bd9Sstevel@tonic-gate  * kernel internal data structures and interfaces
3147c478bd9Sstevel@tonic-gate  * for the fcode interpreter.
3157c478bd9Sstevel@tonic-gate  */
3167c478bd9Sstevel@tonic-gate #if defined(_KERNEL)
3177c478bd9Sstevel@tonic-gate 
3187c478bd9Sstevel@tonic-gate /*
3197c478bd9Sstevel@tonic-gate  * PCI bus-specific arguments.
3207c478bd9Sstevel@tonic-gate  *
3217c478bd9Sstevel@tonic-gate  * We can't get the physical config address of the child from the
3227c478bd9Sstevel@tonic-gate  * unit address, so we supply it here, along with the child's dip
3237c478bd9Sstevel@tonic-gate  * as the bus specific argument to pci_ops_alloc_handle.
3247c478bd9Sstevel@tonic-gate  */
3257c478bd9Sstevel@tonic-gate 
3267c478bd9Sstevel@tonic-gate struct pci_ops_bus_args {
3277c478bd9Sstevel@tonic-gate 	int32_t config_address;		/* phys.hi config addr component */
3287c478bd9Sstevel@tonic-gate };
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate /*
3317c478bd9Sstevel@tonic-gate  * Define data structures for resource lists and handle management
3327c478bd9Sstevel@tonic-gate  *
3337c478bd9Sstevel@tonic-gate  * 'untyped' resources are managed by the provider.
3347c478bd9Sstevel@tonic-gate  */
3357c478bd9Sstevel@tonic-gate struct fc_dma_resource {
3367c478bd9Sstevel@tonic-gate 	void *virt;
3377c478bd9Sstevel@tonic-gate 	size_t len;
3387c478bd9Sstevel@tonic-gate 	ddi_dma_handle_t h;
3397c478bd9Sstevel@tonic-gate 	uint32_t devaddr;
3407c478bd9Sstevel@tonic-gate 	struct buf *bp;
3417c478bd9Sstevel@tonic-gate };
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate struct fc_map_resource {
3447c478bd9Sstevel@tonic-gate 	void *virt;
3457c478bd9Sstevel@tonic-gate 	size_t len;
3467c478bd9Sstevel@tonic-gate 	ddi_acc_handle_t h;
3477c478bd9Sstevel@tonic-gate 	void *regspec;
3487c478bd9Sstevel@tonic-gate };
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate struct fc_nodeid_resource {
3517c478bd9Sstevel@tonic-gate 	int nodeid;		/* An allocated nodeid */
3527c478bd9Sstevel@tonic-gate };
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate struct fc_contigious_resource {
3557c478bd9Sstevel@tonic-gate 	void *virt;
3567c478bd9Sstevel@tonic-gate 	size_t len;
3577c478bd9Sstevel@tonic-gate };
3587c478bd9Sstevel@tonic-gate struct fc_untyped_resource {
3597c478bd9Sstevel@tonic-gate 	int utype;		/* providers private type field */
3607c478bd9Sstevel@tonic-gate 	void (*free)(void *);	/* function to free the resource */
3617c478bd9Sstevel@tonic-gate 	void *resource;		/* Pointer to the resource */
3627c478bd9Sstevel@tonic-gate };
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate typedef enum {
3657c478bd9Sstevel@tonic-gate 	RT_DMA = 0,
3667c478bd9Sstevel@tonic-gate 	RT_MAP,
3677c478bd9Sstevel@tonic-gate 	RT_NODEID,
3687c478bd9Sstevel@tonic-gate 	RT_CONTIGIOUS,
3697c478bd9Sstevel@tonic-gate 	RT_UNTYPED
3707c478bd9Sstevel@tonic-gate } fc_resource_type_t;
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate struct fc_resource {
3737c478bd9Sstevel@tonic-gate 	struct fc_resource *next;
3747c478bd9Sstevel@tonic-gate 	fc_resource_type_t type;
3757c478bd9Sstevel@tonic-gate 	union {
3767c478bd9Sstevel@tonic-gate 		struct fc_dma_resource d;
3777c478bd9Sstevel@tonic-gate 		struct fc_map_resource m;
3787c478bd9Sstevel@tonic-gate 		struct fc_nodeid_resource n;
3797c478bd9Sstevel@tonic-gate 		struct fc_contigious_resource c;
3807c478bd9Sstevel@tonic-gate 		struct fc_untyped_resource r;
3817c478bd9Sstevel@tonic-gate 	} un;
3827c478bd9Sstevel@tonic-gate };
3837c478bd9Sstevel@tonic-gate 
3847c478bd9Sstevel@tonic-gate #define	fc_dma_virt	un.d.virt
3857c478bd9Sstevel@tonic-gate #define	fc_dma_len	un.d.len
3867c478bd9Sstevel@tonic-gate #define	fc_dma_handle	un.d.h
3877c478bd9Sstevel@tonic-gate #define	fc_dma_devaddr	un.d.devaddr
3887c478bd9Sstevel@tonic-gate #define	fc_dma_bp	un.d.bp
3897c478bd9Sstevel@tonic-gate 
3907c478bd9Sstevel@tonic-gate #define	fc_map_virt	un.m.virt
3917c478bd9Sstevel@tonic-gate #define	fc_map_len	un.m.len
3927c478bd9Sstevel@tonic-gate #define	fc_map_handle	un.m.h
3937c478bd9Sstevel@tonic-gate #define	fc_regspec	un.m.regspec
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate #define	fc_nodeid_r	un.n.nodeid
3967c478bd9Sstevel@tonic-gate 
3977c478bd9Sstevel@tonic-gate #define	fc_contig_virt	un.c.virt
3987c478bd9Sstevel@tonic-gate #define	fc_contig_len	un.c.len
3997c478bd9Sstevel@tonic-gate 
4007c478bd9Sstevel@tonic-gate #define	fc_untyped_type	un.r.utype
4017c478bd9Sstevel@tonic-gate #define	fc_untyped_free	un.r.free
4027c478bd9Sstevel@tonic-gate #define	fc_untyped_r	un.r.resource
4037c478bd9Sstevel@tonic-gate 
4047c478bd9Sstevel@tonic-gate struct fc_phandle_entry {
4057c478bd9Sstevel@tonic-gate 	struct fc_phandle_entry *next;
4067c478bd9Sstevel@tonic-gate 	dev_info_t	*dip;
4077c478bd9Sstevel@tonic-gate 	fc_phandle_t	h;
4087c478bd9Sstevel@tonic-gate };
4097c478bd9Sstevel@tonic-gate 
4107c478bd9Sstevel@tonic-gate extern void fc_phandle_table_alloc(struct fc_phandle_entry **);
4117c478bd9Sstevel@tonic-gate extern void fc_phandle_table_free(struct fc_phandle_entry **);
4127c478bd9Sstevel@tonic-gate extern dev_info_t *fc_phandle_to_dip(struct fc_phandle_entry **, fc_phandle_t);
4137c478bd9Sstevel@tonic-gate extern fc_phandle_t fc_dip_to_phandle(struct fc_phandle_entry **, dev_info_t *);
4147c478bd9Sstevel@tonic-gate extern void fc_add_dip_to_phandle(struct fc_phandle_entry **, dev_info_t *,
4157c478bd9Sstevel@tonic-gate     fc_phandle_t);
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate /*
4187c478bd9Sstevel@tonic-gate  * Structures and functions for managing our own subtree rooted
4197c478bd9Sstevel@tonic-gate  * at the attachment point. The parent linkage is established
4207c478bd9Sstevel@tonic-gate  * at node creation time.  The 'downwards' linkage isn't established
4217c478bd9Sstevel@tonic-gate  * until the node is bound.
4227c478bd9Sstevel@tonic-gate  */
4237c478bd9Sstevel@tonic-gate struct fc_device_tree {
4247c478bd9Sstevel@tonic-gate 	dev_info_t *dip;
4257c478bd9Sstevel@tonic-gate 	struct fc_device_tree *child;
4267c478bd9Sstevel@tonic-gate 	struct fc_device_tree *peer;
4277c478bd9Sstevel@tonic-gate };
4287c478bd9Sstevel@tonic-gate 
4297c478bd9Sstevel@tonic-gate void fc_add_child(dev_info_t *child, dev_info_t *parent,
4307c478bd9Sstevel@tonic-gate     struct fc_device_tree *head);
4317c478bd9Sstevel@tonic-gate 
4327c478bd9Sstevel@tonic-gate void fc_remove_child(dev_info_t *child, struct fc_device_tree *head);
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate dev_info_t *fc_child_node(dev_info_t *parent, struct fc_device_tree *head);
4357c478bd9Sstevel@tonic-gate dev_info_t *fc_peer_node(dev_info_t *devi, struct fc_device_tree *head);
4367c478bd9Sstevel@tonic-gate struct fc_device_tree *fc_find_node(dev_info_t *, struct fc_device_tree *);
4377c478bd9Sstevel@tonic-gate 
4387c478bd9Sstevel@tonic-gate void fc_create_device_tree(dev_info_t *ap, struct fc_device_tree **head);
4397c478bd9Sstevel@tonic-gate void fc_remove_device_tree(struct fc_device_tree **head);
4407c478bd9Sstevel@tonic-gate 
4417c478bd9Sstevel@tonic-gate /*
4427c478bd9Sstevel@tonic-gate  * Our handles represent a list of resources associated with an
4437c478bd9Sstevel@tonic-gate  * attachment point.  The handles chain, just as the ops functions
4447c478bd9Sstevel@tonic-gate  * do, with the ops caller responsible for remembering the handle
4457c478bd9Sstevel@tonic-gate  * of the ops function below it. NB: Externally, this data structure
4467c478bd9Sstevel@tonic-gate  * is opaque. (Not all members may be present in each chained cookie.)
4477c478bd9Sstevel@tonic-gate  * For example, the dtree head is valid in only a single instance
4487c478bd9Sstevel@tonic-gate  * of a set of chained cookies, so use the access function to find it.)
4497c478bd9Sstevel@tonic-gate  */
4507c478bd9Sstevel@tonic-gate struct fc_resource_list {
4517c478bd9Sstevel@tonic-gate 	struct fc_resource *head;
4527c478bd9Sstevel@tonic-gate 	void *next_handle;		/* next handle in chain */
4537c478bd9Sstevel@tonic-gate 	dev_info_t *ap;			/* Attachment point dip */
4547c478bd9Sstevel@tonic-gate 	dev_info_t *child;		/* Child being configured, if any */
4557c478bd9Sstevel@tonic-gate 	dev_info_t *cdip;		/* Current node, if any */
4567c478bd9Sstevel@tonic-gate 	int cdip_state;			/* node creation state - see below */
4577c478bd9Sstevel@tonic-gate 	void *fcode;			/* fcode kernel address */
4587c478bd9Sstevel@tonic-gate 	size_t fcode_size;		/* fcode size or zero */
4597c478bd9Sstevel@tonic-gate 	char *unit_address;		/* childs unit address */
4607c478bd9Sstevel@tonic-gate 	char *my_args;			/* initial setting for my-args */
4617c478bd9Sstevel@tonic-gate 	void *bus_args;			/* bus dependent arguments */
4627c478bd9Sstevel@tonic-gate 	struct fc_phandle_entry *ptable; /* devinfo/phandle table */
4637c478bd9Sstevel@tonic-gate 	struct fc_device_tree *dtree;	/* Our subtree (leaf cookie only) */
4647c478bd9Sstevel@tonic-gate };
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate typedef struct fc_resource_list *fco_handle_t;
4677c478bd9Sstevel@tonic-gate 
4687c478bd9Sstevel@tonic-gate /*
4697c478bd9Sstevel@tonic-gate  * Values for cdip_state:
4707c478bd9Sstevel@tonic-gate  */
4717c478bd9Sstevel@tonic-gate #define	FC_CDIP_NOSTATE		0x00	/* No state - no nodes created */
4727c478bd9Sstevel@tonic-gate #define	FC_CDIP_STARTED		0x01	/* Node started - dip in cdip */
4737c478bd9Sstevel@tonic-gate #define	FC_CDIP_DONE		0x02	/* Node finished - last dip in cdip */
4747c478bd9Sstevel@tonic-gate #define	FC_CDIP_CONFIG		0x10	/* subtree configured */
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate /*
4777c478bd9Sstevel@tonic-gate  * Functions to allocate handles for the fcode_interpreter.
4787c478bd9Sstevel@tonic-gate  *
4797c478bd9Sstevel@tonic-gate  * This function allocates a handle, used to store resources
4807c478bd9Sstevel@tonic-gate  * associated with this fcode request including the address of
4817c478bd9Sstevel@tonic-gate  * the mapped in and copied in fcode and it's size or NULL, 0
4827c478bd9Sstevel@tonic-gate  * if there is no fcode (the interpreter may look for a drop-in
4837c478bd9Sstevel@tonic-gate  * driver if there is no fcode), the unit address of child and
4847c478bd9Sstevel@tonic-gate  * bus specific arguments.  For PCI, the bus specific arguments
4857c478bd9Sstevel@tonic-gate  * include the child's prototype dip and the config address of
4867c478bd9Sstevel@tonic-gate  * the child, which can't be derived from the unit address.
4877c478bd9Sstevel@tonic-gate  *
4887c478bd9Sstevel@tonic-gate  * The 'handle' returned also contains resource information
4897c478bd9Sstevel@tonic-gate  * about any allocations of kernel resources that the fcode
4907c478bd9Sstevel@tonic-gate  * may have created.  Thus, the handle's life is the life
4917c478bd9Sstevel@tonic-gate  * of the plug-in card and can't be released until the card
4927c478bd9Sstevel@tonic-gate  * is removed.  Upon release, the resources are released.
4937c478bd9Sstevel@tonic-gate  */
4947c478bd9Sstevel@tonic-gate extern fco_handle_t
4957c478bd9Sstevel@tonic-gate fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
4967c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address, void *bus_args);
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate extern fco_handle_t
4997c478bd9Sstevel@tonic-gate pci_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
5007c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address,
5017c478bd9Sstevel@tonic-gate     struct pci_ops_bus_args *bus_args);
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate extern fco_handle_t
5047c478bd9Sstevel@tonic-gate gp2_fc_ops_alloc_handle(dev_info_t *ap, dev_info_t *config_child,
5057c478bd9Sstevel@tonic-gate     void *fcode, size_t fcode_size, char *unit_address,
5067c478bd9Sstevel@tonic-gate     char *my_args);
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate extern void pci_fc_ops_free_handle(fco_handle_t handle);
5097c478bd9Sstevel@tonic-gate extern void gp2_fc_ops_free_handle(fco_handle_t handle);
5107c478bd9Sstevel@tonic-gate extern void fc_ops_free_handle(fco_handle_t handle);
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate extern struct fc_phandle_entry **fc_handle_to_phandle_head(fco_handle_t rp);
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate struct fc_device_tree **fc_handle_to_dtree_head(fco_handle_t);
5157c478bd9Sstevel@tonic-gate struct fc_device_tree *fc_handle_to_dtree(fco_handle_t);
5167c478bd9Sstevel@tonic-gate 
5177c478bd9Sstevel@tonic-gate /*
5187c478bd9Sstevel@tonic-gate  * fc_ops_t is the main glue back to the framework and attachment point driver
5197c478bd9Sstevel@tonic-gate  * for privileged driver operations.  The framework/driver provides a pointer
5207c478bd9Sstevel@tonic-gate  * to the fc_ops function to handle the request given in the args.  The dip
5217c478bd9Sstevel@tonic-gate  * and handle are passed back to the framework/driver to distinguish
5227c478bd9Sstevel@tonic-gate  * requests, if necessary.  The argument array is an array of fc_cell_t's
5237c478bd9Sstevel@tonic-gate  * and is defined in fcode.h
5247c478bd9Sstevel@tonic-gate  *
5257c478bd9Sstevel@tonic-gate  * The ops function should return -1 to indicate that the service name is
5267c478bd9Sstevel@tonic-gate  * unknown and return the value 0 to indicate that the service name was known
5277c478bd9Sstevel@tonic-gate  * and processed (even if it failed).  ops functions may chain, using the
5287c478bd9Sstevel@tonic-gate  * return code to communicate if the current function handled the service
5297c478bd9Sstevel@tonic-gate  * request. Using this technique, the driver can provide certain ops functions
5307c478bd9Sstevel@tonic-gate  * and allow a framework ops function to handle standardized ops functions,
5317c478bd9Sstevel@tonic-gate  * or work hand in hand with a framework function so both can handle an op.
5327c478bd9Sstevel@tonic-gate  * If an ops function is not handled, thus returning -1 to the driver, the
5337c478bd9Sstevel@tonic-gate  * driver will log an error noting the name of the service and return the
5347c478bd9Sstevel@tonic-gate  * error to the caller.
5357c478bd9Sstevel@tonic-gate  */
5367c478bd9Sstevel@tonic-gate typedef int (fc_ops_t)(dev_info_t *, fco_handle_t, fc_ci_t *);
5377c478bd9Sstevel@tonic-gate 
5387c478bd9Sstevel@tonic-gate extern fc_ops_t fc_ops;
5397c478bd9Sstevel@tonic-gate extern fc_ops_t pci_fc_ops;
5407c478bd9Sstevel@tonic-gate extern fc_ops_t gp2_fc_ops;
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate /*
5437c478bd9Sstevel@tonic-gate  * Internal structure used to enque an fcode request
5447c478bd9Sstevel@tonic-gate  * The 'next' and 'busy' fields are protected by a mutex.
5457c478bd9Sstevel@tonic-gate  * Thread synchronization is accomplished via use of the 'busy' field.
5467c478bd9Sstevel@tonic-gate  */
5477c478bd9Sstevel@tonic-gate struct fc_request {
5487c478bd9Sstevel@tonic-gate 	struct fc_request *next;	/* Next in chain (private) */
5497c478bd9Sstevel@tonic-gate 	int		busy;		/* Waiters flag (private; see below) */
5507c478bd9Sstevel@tonic-gate 	int		error;		/* Interpreter return code (private) */
5517c478bd9Sstevel@tonic-gate 	dev_info_t	*ap_dip;	/* Attachment point. ie: pci nexus */
5527c478bd9Sstevel@tonic-gate 	fc_ops_t	*ap_ops;	/* driver's fcode ops function */
5537c478bd9Sstevel@tonic-gate 	fco_handle_t	handle;		/* Caller's private identifier */
5547c478bd9Sstevel@tonic-gate 	timeout_id_t	timeout;	/* Timeout identifier */
5557c478bd9Sstevel@tonic-gate };
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate /*
5587c478bd9Sstevel@tonic-gate  * Values for 'busy'.  The requester initializes the field to FC_R_INIT (0),
5597c478bd9Sstevel@tonic-gate  * then waits for it be set to FC_R_DONE.  The framework sets it to
5607c478bd9Sstevel@tonic-gate  * FC_R_BUSY while working on the request so it can distinguish between
5617c478bd9Sstevel@tonic-gate  * an inactive and an active request.
5627c478bd9Sstevel@tonic-gate  */
5637c478bd9Sstevel@tonic-gate #define	FC_R_INIT	0		/* initialized, on queue */
5647c478bd9Sstevel@tonic-gate #define	FC_R_BUSY	1		/* request is active, busy */
5657c478bd9Sstevel@tonic-gate #define	FC_R_DONE	2		/* request is done and may be deq'd */
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate /*
5687c478bd9Sstevel@tonic-gate  * Function to call to invoke the fcode interpreter.
5697c478bd9Sstevel@tonic-gate  *
5707c478bd9Sstevel@tonic-gate  * This function will wait and return when the interpreter either
5717c478bd9Sstevel@tonic-gate  * completes successfully or fails, returning pass/fail status as
5727c478bd9Sstevel@tonic-gate  * the return code.  Interim calls to the driver's ops function will
5737c478bd9Sstevel@tonic-gate  * be made for both priv. ops and to create device nodes and properties.
5747c478bd9Sstevel@tonic-gate  *
5757c478bd9Sstevel@tonic-gate  * Calling this function will log a message to userland to request the
5767c478bd9Sstevel@tonic-gate  * eventd to start the userland fcode interpreter process. The interpreter
5777c478bd9Sstevel@tonic-gate  * opens /dev/fcode, which clones an instance of the driver, and then
5787c478bd9Sstevel@tonic-gate  * waits in a 'read' until there's an active request.
5797c478bd9Sstevel@tonic-gate  * XXX: For the prototype, we can start it manually or use an init.d script.
5807c478bd9Sstevel@tonic-gate  *
5817c478bd9Sstevel@tonic-gate  * 'ap' is the attachment point dip: that is, the driving parent's dev_info_t
5827c478bd9Sstevel@tonic-gate  * ie: for pci devices, this will be the dip of the pci nexus.
5837c478bd9Sstevel@tonic-gate  *
5847c478bd9Sstevel@tonic-gate  * The 'handle' is provided for the caller, and can be used to
5857c478bd9Sstevel@tonic-gate  * identify the request along with the attachment point dip, both
5867c478bd9Sstevel@tonic-gate  * of which will be passed back to the driver's ops function.
5877c478bd9Sstevel@tonic-gate  * The handle is allocated first by calling a bus-specific
5887c478bd9Sstevel@tonic-gate  * <bus>_ops_handle_alloc function.
5897c478bd9Sstevel@tonic-gate  *
5907c478bd9Sstevel@tonic-gate  * ops functions may chain; an ops function should return -1 if
5917c478bd9Sstevel@tonic-gate  * the call was not recognized, or 0 if the call was recognized.
5927c478bd9Sstevel@tonic-gate  */
5937c478bd9Sstevel@tonic-gate extern int fcode_interpreter(dev_info_t *, fc_ops_t *, fco_handle_t);
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate /*
5967c478bd9Sstevel@tonic-gate  * The fcode implementation uses this function to wait for and 'de-queue'
5977c478bd9Sstevel@tonic-gate  * an fcode request.  It's triggered by a 'read' request from the
5987c478bd9Sstevel@tonic-gate  * userland interpreter. It uses a 'sig' form of waiting (cv_wait_sig),
5997c478bd9Sstevel@tonic-gate  * so the interpreter can interrupt the read.
6007c478bd9Sstevel@tonic-gate  */
6017c478bd9Sstevel@tonic-gate extern struct fc_request *fc_get_request(void);
6027c478bd9Sstevel@tonic-gate 
6037c478bd9Sstevel@tonic-gate /*
6047c478bd9Sstevel@tonic-gate  * When the fcode implementation is finished servicing a request, it calls this
6057c478bd9Sstevel@tonic-gate  * function to mark the request as done and to signal the originating thread
6067c478bd9Sstevel@tonic-gate  * (now waiting in fcode_interpreter) that the request is done.
6077c478bd9Sstevel@tonic-gate  */
6087c478bd9Sstevel@tonic-gate extern void fc_finish_request(struct fc_request *);
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate /*
6117c478bd9Sstevel@tonic-gate  * The fcode implementation uses these functions to manage
6127c478bd9Sstevel@tonic-gate  * resource items and resource lists ...
6137c478bd9Sstevel@tonic-gate  */
6147c478bd9Sstevel@tonic-gate extern void fc_add_resource(fco_handle_t, struct fc_resource *);
6157c478bd9Sstevel@tonic-gate extern void fc_rem_resource(fco_handle_t, struct fc_resource *);
6167c478bd9Sstevel@tonic-gate extern void fc_lock_resource_list(fco_handle_t);
6177c478bd9Sstevel@tonic-gate extern void fc_unlock_resource_list(fco_handle_t);
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate /*
6207c478bd9Sstevel@tonic-gate  * ops common and helper functions
6217c478bd9Sstevel@tonic-gate  */
6227c478bd9Sstevel@tonic-gate extern int fc_fail_op(dev_info_t *, fco_handle_t, fc_ci_t *);
6237c478bd9Sstevel@tonic-gate extern int fc_success_op(dev_info_t *, fco_handle_t, fc_ci_t *);
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate extern int fc_syntax_error(fc_ci_t *, char *);
6267c478bd9Sstevel@tonic-gate extern int fc_priv_error(fc_ci_t *, char *);
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate /*
6297c478bd9Sstevel@tonic-gate  * Recharacterized ddi functions we need to define ...
6307c478bd9Sstevel@tonic-gate  *
6317c478bd9Sstevel@tonic-gate  * The only difference is we call through the attachment point driver,
6327c478bd9Sstevel@tonic-gate  * as a proxy for the child that isn't yet attached. The ddi functions
6337c478bd9Sstevel@tonic-gate  * optimize these functions by not necessarily calling through the
6347c478bd9Sstevel@tonic-gate  * attachment point driver.
6357c478bd9Sstevel@tonic-gate  */
636*4ab75253Smrj int fc_ddi_dma_alloc_handle(dev_info_t *dip, ddi_dma_attr_t *attr,
637*4ab75253Smrj     int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep);
638*4ab75253Smrj int fc_ddi_dma_buf_bind_handle(ddi_dma_handle_t handle, struct buf *bp,
639*4ab75253Smrj     uint_t flags, int (*waitfp)(caddr_t), caddr_t arg,
640*4ab75253Smrj     ddi_dma_cookie_t *cookiep, uint_t *ccountp);
641*4ab75253Smrj int fc_ddi_dma_unbind_handle(ddi_dma_handle_t handle);
642*4ab75253Smrj void fc_ddi_dma_free_handle(ddi_dma_handle_t *handlep);
6437c478bd9Sstevel@tonic-gate int fc_ddi_dma_sync(ddi_dma_handle_t h, off_t o, size_t l, uint_t whom);
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate /*
6467c478bd9Sstevel@tonic-gate  * The ndi prop functions aren't appropriate for the interpreter.
6477c478bd9Sstevel@tonic-gate  * We create byte-array, untyped properties.
6487c478bd9Sstevel@tonic-gate  */
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate int fc_ndi_prop_update(dev_t, dev_info_t *, char *, uchar_t *, uint_t);
6517c478bd9Sstevel@tonic-gate 
6527c478bd9Sstevel@tonic-gate /*
6537c478bd9Sstevel@tonic-gate  * The setup and teardown parts of physio()
6547c478bd9Sstevel@tonic-gate  */
6557c478bd9Sstevel@tonic-gate int fc_physio_setup(struct buf **bpp, void *io_base, size_t io_len);
6567c478bd9Sstevel@tonic-gate void fc_physio_free(struct buf **bpp, void *io_base, size_t io_len);
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate /*
6597c478bd9Sstevel@tonic-gate  * debugging macros
6607c478bd9Sstevel@tonic-gate  */
6617c478bd9Sstevel@tonic-gate extern int fcode_debug;
6627c478bd9Sstevel@tonic-gate #define	dcmn_err(level, args) if (fcode_debug >= level) cmn_err args
6637c478bd9Sstevel@tonic-gate 
6647c478bd9Sstevel@tonic-gate #ifdef DEBUG
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate void fc_debug(char *, uintptr_t, uintptr_t,
6677c478bd9Sstevel@tonic-gate     uintptr_t, uintptr_t, uintptr_t);
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate #define	FC_DEBUG0(level, flag, s) if (fcode_debug >= level) \
6707c478bd9Sstevel@tonic-gate     fc_debug(s, 0, 0, 0, 0, 0)
6717c478bd9Sstevel@tonic-gate #define	FC_DEBUG1(level, flag, fmt, a1) if (fcode_debug >= level) \
6727c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
6737c478bd9Sstevel@tonic-gate #define	FC_DEBUG2(level, flag, fmt, a1, a2) if (fcode_debug >= level) \
6747c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
6757c478bd9Sstevel@tonic-gate #define	FC_DEBUG3(level, flag, fmt, a1, a2, a3) \
6767c478bd9Sstevel@tonic-gate     if (fcode_debug >= level) \
6777c478bd9Sstevel@tonic-gate     fc_debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), (uintptr_t)(a3), 0, 0);
6787c478bd9Sstevel@tonic-gate #else
6797c478bd9Sstevel@tonic-gate #define	FC_DEBUG0(level, flag, s)
6807c478bd9Sstevel@tonic-gate #define	FC_DEBUG1(level, flag, fmt, a1)
6817c478bd9Sstevel@tonic-gate #define	FC_DEBUG2(level, flag, fmt, a1, a2)
6827c478bd9Sstevel@tonic-gate #define	FC_DEBUG3(level, flag, fmt, a1, a2, a3)
6837c478bd9Sstevel@tonic-gate #endif
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate #endif	/* defined(_KERNEL) */
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
6897c478bd9Sstevel@tonic-gate }
6907c478bd9Sstevel@tonic-gate #endif
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate #endif	/* _SYS_FCODE_H */
693