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