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