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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #ifndef _SYS_SUNNDI_H 27 #define _SYS_SUNNDI_H 28 29 /* 30 * Sun Specific NDI definitions 31 */ 32 33 #include <sys/esunddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/obpdefs.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #ifdef _KERNEL 42 43 #define NDI_SUCCESS DDI_SUCCESS /* successful return */ 44 #define NDI_FAILURE DDI_FAILURE /* unsuccessful return */ 45 #define NDI_NOMEM -2 /* failed to allocate resources */ 46 #define NDI_BADHANDLE -3 /* bad handle passed to in function */ 47 #define NDI_FAULT -4 /* fault during copyin/copyout */ 48 #define NDI_BUSY -5 /* device busy - could not offline */ 49 #define NDI_UNBOUND -6 /* device not bound to a driver */ 50 51 /* 52 * Property functions: See also, ddipropdefs.h. 53 * In general, the underlying driver MUST be held 54 * to call it's property functions. 55 */ 56 57 /* 58 * Used to create boolean properties 59 */ 60 int 61 ndi_prop_create_boolean(dev_t match_dev, dev_info_t *dip, char *name); 62 63 /* 64 * Used to create, modify, and lookup integer properties 65 */ 66 int 67 ndi_prop_update_int(dev_t match_dev, dev_info_t *dip, char *name, int data); 68 69 int 70 ndi_prop_update_int_array(dev_t match_dev, dev_info_t *dip, char *name, 71 int *data, uint_t nelements); 72 73 int 74 ndi_prop_update_int64(dev_t match_dev, dev_info_t *dip, char *name, 75 int64_t data); 76 77 int 78 ndi_prop_update_int64_array(dev_t match_dev, dev_info_t *dip, char *name, 79 int64_t *data, uint_t nelements); 80 81 /* 82 * Used to create, modify, and lookup string properties 83 */ 84 int 85 ndi_prop_update_string(dev_t match_dev, dev_info_t *dip, char *name, 86 char *data); 87 88 int 89 ndi_prop_update_string_array(dev_t match_dev, dev_info_t *dip, 90 char *name, char **data, uint_t nelements); 91 92 /* 93 * Used to create, modify, and lookup byte properties 94 */ 95 int 96 ndi_prop_update_byte_array(dev_t match_dev, dev_info_t *dip, 97 char *name, uchar_t *data, uint_t nelements); 98 99 /* 100 * Used to remove properties 101 */ 102 int 103 ndi_prop_remove(dev_t dev, dev_info_t *dip, char *name); 104 105 void 106 ndi_prop_remove_all(dev_info_t *dip); 107 108 /* 109 * Nexus Driver Functions 110 */ 111 /* 112 * Allocate and initialize a new dev_info structure. 113 * This routine will often be called at interrupt time by a nexus in 114 * response to a hotplug event, therefore memory allocations are 115 * not allowed to sleep. 116 */ 117 int 118 ndi_devi_alloc(dev_info_t *parent, char *node_name, pnode_t nodeid, 119 dev_info_t **ret_dip); 120 121 void 122 ndi_devi_alloc_sleep(dev_info_t *parent, char *node_name, pnode_t nodeid, 123 dev_info_t **ret_dip); 124 125 /* 126 * Remove an initialized (but not yet attached) dev_info 127 * node from it's parent. 128 */ 129 int 130 ndi_devi_free(dev_info_t *dip); 131 132 /* devinfo locking: use DEVI_BUSY_OWNED in ASSERTs to verify */ 133 void ndi_devi_enter(dev_info_t *dip, int *circ); 134 void ndi_devi_exit(dev_info_t *dip, int circ); 135 int ndi_devi_tryenter(dev_info_t *dip, int *circ); 136 137 /* devinfo ref counting */ 138 void ndi_hold_devi(dev_info_t *dip); 139 void ndi_rele_devi(dev_info_t *dip); 140 141 /* driver ref counting */ 142 struct dev_ops *ndi_hold_driver(dev_info_t *dip); 143 void ndi_rele_driver(dev_info_t *dip); 144 145 /* 146 * Change the node name 147 */ 148 int 149 ndi_devi_set_nodename(dev_info_t *dip, char *name, int flags); 150 151 /* 152 * Place the devinfo in the DS_BOUND state, 153 * binding a driver to the device 154 * 155 * Flags: 156 * all flags are ignored. 157 */ 158 int 159 ndi_devi_bind_driver(dev_info_t *dip, uint_t flags); 160 161 /* 162 * Asynchronous version of ndi_devi_bind_driver, callable from 163 * interrupt context. The dip must be a persistent node. 164 */ 165 int 166 ndi_devi_bind_driver_async(dev_info_t *dip, uint_t flags); 167 168 /* 169 * Return devctl state of the child addressed by "name@addr". 170 * For use by a driver's DEVCTL_DEVICE_GETSTATE handler. 171 */ 172 int 173 ndi_devctl_device_getstate(dev_info_t *parent, struct devctl_iocdata *dcp, 174 uint_t *state); 175 176 /* 177 * Transition the child addressed by "name@addr" to the online state. 178 * For use by a driver's DEVCTL_DEVICE_ONLINE handler. 179 */ 180 int 181 ndi_devctl_device_online(dev_info_t *dip, struct devctl_iocdata *dcp, 182 uint_t flags); 183 184 /* 185 * Transition the child addressed by "name@addr" to the offline state. 186 * For use by a driver's DEVCTL_DEVICE_OFFLINE handler. 187 */ 188 int 189 ndi_devctl_device_offline(dev_info_t *dip, struct devctl_iocdata *dcp, 190 uint_t flags); 191 192 /* 193 * Remove the child addressed by name@addr. 194 * For use by a driver's DEVCTL_DEVICE_REMOVE handler. 195 */ 196 int 197 ndi_devctl_device_remove(dev_info_t *dip, struct devctl_iocdata *dcp, 198 uint_t flags); 199 200 /* 201 * Bus get state 202 * For use by a driver's DEVCTL_BUS_GETSTATE handler. 203 */ 204 int 205 ndi_devctl_bus_getstate(dev_info_t *dip, struct devctl_iocdata *dcp, 206 uint_t *state); 207 208 /* 209 * Place the devinfo in the ONLINE state 210 */ 211 int 212 ndi_devi_online(dev_info_t *dip, uint_t flags); 213 214 /* 215 * Generic devctl ioctl handler 216 */ 217 int 218 ndi_devctl_ioctl(dev_info_t *dip, int cmd, intptr_t arg, int mode, 219 uint_t flags); 220 221 /* 222 * Asynchronous version of ndi_devi_online, callable from interrupt 223 * context. The dip must be a persistent node. 224 */ 225 int 226 ndi_devi_online_async(dev_info_t *dip, uint_t flags); 227 228 229 /* 230 * Configure children of a nexus node. 231 * 232 * Flags: 233 * NDI_ONLINE_ATTACH - Attach driver to devinfo node when placing 234 * the device Online. 235 * NDI_CONFIG - Recursively configure children if child is nexus node 236 */ 237 int 238 ndi_devi_config(dev_info_t *dip, int flags); 239 240 int 241 ndi_devi_config_driver(dev_info_t *dip, int flags, major_t major); 242 243 int 244 ndi_devi_config_one(dev_info_t *dip, char *devnm, dev_info_t **dipp, int flags); 245 246 /* 247 * Unconfigure children of a nexus node. 248 * 249 * Flags: 250 * NDI_DEVI_REMOVE - Remove child devinfo nodes 251 * 252 * NDI_UNCONFIG - Put child devinfo nodes to uninitialized state, 253 * release resources held by child nodes. 254 */ 255 int 256 ndi_devi_unconfig(dev_info_t *dip, int flags); 257 258 int 259 e_ddi_devi_unconfig(dev_info_t *dip, dev_info_t **dipp, int flags); 260 261 int 262 ndi_devi_unconfig_one(dev_info_t *dip, char *devnm, dev_info_t **dipp, 263 int flags); 264 265 int 266 ndi_devi_unconfig_driver(dev_info_t *dip, int flags, major_t major); 267 268 void 269 ndi_set_bus_private(dev_info_t *dip, boolean_t up, uint32_t port_type, 270 void *data); 271 272 void * 273 ndi_get_bus_private(dev_info_t *dip, boolean_t up); 274 275 boolean_t 276 ndi_port_type(dev_info_t *dip, boolean_t up, uint32_t port_type); 277 278 /* 279 * Create/Destroy Interrupt Resource Management (IRM) Pools. 280 */ 281 int 282 ndi_irm_create(dev_info_t *dip, ddi_irm_params_t *paramsp, 283 ddi_irm_pool_t **pool_retp); 284 285 int 286 ndi_irm_destroy(ddi_irm_pool_t *poolp); 287 288 /* 289 * Take a device node "Offline". 290 * 291 * Offline means to detach the device instance from the bound 292 * driver and setting the devinfo state to prevent deferred attach 293 * from re-attaching the device instance. 294 * 295 * Flags: 296 * NDI_DEVI_REMOVE - Remove the node from the devinfo tree after 297 * first taking it Offline. 298 */ 299 300 #define NDI_DEVI_REMOVE 0x00000001 /* remove after unconfig */ 301 #define NDI_ONLINE_ATTACH 0x00000002 /* online/attach after config */ 302 #define NDI_MDI_FALLBACK 0x00000004 /* Leadville to fallback to phci */ 303 #define NDI_CONFIG 0x00000008 /* recursively config descendants */ 304 #define NDI_UNCONFIG 0x00000010 /* unconfig to uninitialized state */ 305 #define NDI_DEVI_BIND 0x00000020 /* transition to DS_BOUND state */ 306 #define NDI_DEVI_PERSIST 0x00000040 /* do not config offlined nodes */ 307 #define NDI_PROMNAME 0x00000080 /* name comes from prom */ 308 #define NDI_DEVFS_CLEAN 0x00001000 /* clean dv_nodes only, no detach */ 309 #define NDI_AUTODETACH 0x00002000 /* moduninstall daemon */ 310 #define NDI_NO_EVENT 0x00004000 /* don't devfs add/remove events */ 311 #define NDI_DEVI_DEBUG 0x00008000 /* turn on observability */ 312 #define NDI_CONFIG_REPROBE 0x00010000 /* force reprobe (deferred attach) */ 313 #define NDI_DEVI_ONLINE 0x00020000 /* force offlined device to online */ 314 #define NDI_DEVI_OFFLINE 0x00040000 /* set detached device to offline */ 315 #define NDI_POST_EVENT 0x00080000 /* Post NDI events before remove */ 316 #define NDI_BRANCH_EVENT_OP 0x01000000 /* branch op needs branch event */ 317 #define NDI_NO_EVENT_STATE_CHNG 0x02000000 /* don't change the event state */ 318 #define NDI_DRV_CONF_REPROBE 0x04000000 /* reprobe conf-enum'd nodes only */ 319 #define NDI_DETACH_DRIVER 0x08000000 /* performing driver_detach */ 320 #define NDI_MTC_OFF 0x10000000 /* disable multi-threading */ 321 #define NDI_USER_REQ 0x20000000 /* user requested operation */ 322 323 /* ndi interface flag values */ 324 #define NDI_SLEEP 0x000000 325 #define NDI_NOSLEEP 0x100000 326 #define NDI_EVENT_NOPASS 0x200000 /* do not pass event req up the tree */ 327 328 int 329 ndi_devi_offline(dev_info_t *dip, uint_t flags); 330 331 /* 332 * Find the child dev_info node of parent nexus 'p' whose name 333 * matches "cname"@"caddr". Use ndi_devi_findchild() instead. 334 */ 335 dev_info_t * 336 ndi_devi_find(dev_info_t *p, char *cname, char *caddr); 337 338 /* 339 * Find the child dev_info node of parent nexus 'p' whose name 340 * matches device name "name"@"addr". 341 */ 342 dev_info_t * 343 ndi_devi_findchild(dev_info_t *p, char *devname); 344 345 /* 346 * Find the child dev_info node of parent nexus 'p' whose name 347 * matches "dname"@"ua". If a child doesn't have a "ua" 348 * value, it calls the function "make_ua" to create it. 349 */ 350 dev_info_t * 351 ndi_devi_findchild_by_callback(dev_info_t *p, char *dname, char *ua, 352 int (*make_ua)(dev_info_t *, char *, int)); 353 354 /* 355 * Maintain DEVI_DEVICE_REMOVED hotplug devi_state for remove/reinsert hotplug 356 * of open devices. 357 */ 358 int 359 ndi_devi_device_isremoved(dev_info_t *dip); 360 int 361 ndi_devi_device_remove(dev_info_t *dip); 362 int 363 ndi_devi_device_insert(dev_info_t *dip); 364 365 /* 366 * generate debug msg via NDI_DEVI_DEBUG flag 367 */ 368 #define NDI_DEBUG(flags, args) \ 369 if (flags & NDI_DEVI_DEBUG) cmn_err args 370 371 /* 372 * Copy in the devctl IOCTL data structure and the strings referenced 373 * by the structure. 374 * 375 * Convenience functions for use by nexus drivers as part of the 376 * implementation of devctl IOCTL handling. 377 */ 378 int 379 ndi_dc_allochdl(void *iocarg, struct devctl_iocdata **rdcp); 380 381 void 382 ndi_dc_freehdl(struct devctl_iocdata *dcp); 383 384 char * 385 ndi_dc_getpath(struct devctl_iocdata *dcp); 386 387 char * 388 ndi_dc_getname(struct devctl_iocdata *dcp); 389 390 char * 391 ndi_dc_getaddr(struct devctl_iocdata *dcp); 392 393 nvlist_t * 394 ndi_dc_get_ap_data(struct devctl_iocdata *dcp); 395 396 char * 397 ndi_dc_getminorname(struct devctl_iocdata *dcp); 398 399 int 400 ndi_dc_return_dev_state(dev_info_t *dip, struct devctl_iocdata *dcp); 401 402 int 403 ndi_dc_return_ap_state(devctl_ap_state_t *ap, struct devctl_iocdata *dcp); 404 405 int 406 ndi_dc_return_bus_state(dev_info_t *dip, struct devctl_iocdata *dcp); 407 408 int 409 ndi_dc_devi_create(struct devctl_iocdata *dcp, dev_info_t *pdip, int flags, 410 dev_info_t **rdip); 411 412 int 413 ndi_get_bus_state(dev_info_t *dip, uint_t *rstate); 414 415 int 416 ndi_set_bus_state(dev_info_t *dip, uint_t state); 417 418 /* 419 * Post an event notification up the device tree hierarchy to the 420 * parent nexus, until claimed by a bus nexus driver or the top 421 * of the dev_info tree is reached. 422 */ 423 int 424 ndi_post_event(dev_info_t *dip, dev_info_t *rdip, ddi_eventcookie_t eventhdl, 425 void *impl_data); 426 427 /* 428 * Called by the NDI Event Framework to deliver a registration request to the 429 * appropriate bus nexus driver. 430 */ 431 int 432 ndi_busop_add_eventcall(dev_info_t *dip, dev_info_t *rdip, 433 ddi_eventcookie_t eventhdl, void (*callback)(), void *arg, 434 ddi_callback_id_t *cb_id); 435 436 /* 437 * Called by the NDI Event Framework to deliver an unregister request to the 438 * appropriate bus nexus driver. 439 */ 440 int 441 ndi_busop_remove_eventcall(dev_info_t *ddip, ddi_callback_id_t id); 442 443 /* 444 * Called by the NDI Event Framework and/or a bus nexus driver's 445 * implementation of the (*bus_get_eventcookie)() interface up the device tree 446 * hierarchy, until claimed by a bus nexus driver or the top of the dev_info 447 * tree is reached. The NDI Event Framework will skip nexus drivers which are 448 * not configured to handle NDI events. 449 */ 450 int 451 ndi_busop_get_eventcookie(dev_info_t *dip, dev_info_t *rdip, char *name, 452 ddi_eventcookie_t *event_cookiep); 453 454 /* 455 * ndi event callback support routines: 456 * 457 * these functions require an opaque ndi event handle 458 */ 459 typedef struct ndi_event_hdl *ndi_event_hdl_t; 460 461 /* 462 * structure for maintaining each registered callback 463 */ 464 typedef struct ndi_event_callbacks { 465 struct ndi_event_callbacks *ndi_evtcb_next; 466 struct ndi_event_callbacks *ndi_evtcb_prev; 467 dev_info_t *ndi_evtcb_dip; 468 char *devname; /* name of device defining this callback */ 469 void (*ndi_evtcb_callback)(); 470 void *ndi_evtcb_arg; 471 ddi_eventcookie_t ndi_evtcb_cookie; 472 } ndi_event_callbacks_t; 473 474 /* 475 * a nexus driver defines events that it can support using the 476 * following structure 477 */ 478 typedef struct ndi_event_definition { 479 int ndi_event_tag; 480 char *ndi_event_name; 481 ddi_plevel_t ndi_event_plevel; 482 uint_t ndi_event_attributes; 483 } ndi_event_definition_t; 484 485 typedef struct ndi_event_cookie { 486 ndi_event_definition_t *definition; /* Event Description */ 487 dev_info_t *ddip; /* Devi defining this event */ 488 ndi_event_callbacks_t *callback_list; /* Cb's reg'd to w/ this evt */ 489 struct ndi_event_cookie *next_cookie; /* Next cookie def'd in hdl */ 490 } ndi_event_cookie_t; 491 492 493 #define NDI_EVENT(cookie) ((struct ndi_event_cookie *)(void *)(cookie)) 494 #define NDI_EVENT_NAME(cookie) (NDI_EVENT(cookie)->definition->ndi_event_name) 495 #define NDI_EVENT_TAG(cookie) (NDI_EVENT(cookie)->definition->ndi_event_tag) 496 #define NDI_EVENT_ATTRIBUTES(cookie) \ 497 (NDI_EVENT(cookie)->definition->ndi_event_attributes) 498 #define NDI_EVENT_PLEVEL(cookie) \ 499 (NDI_EVENT(cookie)->definition->ndi_event_plevel) 500 #define NDI_EVENT_DDIP(cookie) (NDI_EVENT(cookie)->ddip) 501 502 /* ndi_event_attributes */ 503 #define NDI_EVENT_POST_TO_ALL 0x0 /* broadcast: post to all handlers */ 504 #define NDI_EVENT_POST_TO_TGT 0x1 /* call only specific child's hdlr */ 505 506 typedef struct ndi_event_set { 507 ushort_t ndi_events_version; 508 ushort_t ndi_n_events; 509 ndi_event_definition_t *ndi_event_defs; 510 } ndi_event_set_t; 511 512 513 #define NDI_EVENTS_REV0 0 514 #define NDI_EVENTS_REV1 1 515 516 /* 517 * allocate an ndi event handle 518 */ 519 int 520 ndi_event_alloc_hdl(dev_info_t *dip, ddi_iblock_cookie_t cookie, 521 ndi_event_hdl_t *ndi_event_hdl, uint_t flag); 522 523 /* 524 * free the ndi event handle 525 */ 526 int 527 ndi_event_free_hdl(ndi_event_hdl_t handle); 528 529 /* 530 * bind or unbind a set of events to/from the event handle 531 */ 532 int 533 ndi_event_bind_set(ndi_event_hdl_t handle, 534 ndi_event_set_t *ndi_event_set, 535 uint_t flag); 536 537 int 538 ndi_event_unbind_set(ndi_event_hdl_t handle, 539 ndi_event_set_t *ndi_event_set, 540 uint_t flag); 541 542 /* 543 * get an event cookie 544 */ 545 int 546 ndi_event_retrieve_cookie(ndi_event_hdl_t handle, 547 dev_info_t *child_dip, 548 char *eventname, 549 ddi_eventcookie_t *cookiep, 550 uint_t flag); 551 552 /* 553 * add an event callback info to the ndi event handle 554 */ 555 int 556 ndi_event_add_callback(ndi_event_hdl_t handle, 557 dev_info_t *child_dip, 558 ddi_eventcookie_t cookie, 559 void (*event_callback) 560 (dev_info_t *, 561 ddi_eventcookie_t, 562 void *arg, 563 void *impldata), 564 void *arg, 565 uint_t flag, 566 ddi_callback_id_t *cb_id); 567 568 /* 569 * remove an event callback registration from the ndi event handle 570 */ 571 int 572 ndi_event_remove_callback(ndi_event_hdl_t handle, ddi_callback_id_t id); 573 574 /* 575 * perform callbacks for a specified cookie 576 */ 577 int 578 ndi_event_run_callbacks(ndi_event_hdl_t handle, dev_info_t *child_dip, 579 ddi_eventcookie_t cookie, void *bus_impldata); 580 581 /* 582 * do callback for just one child_dip, regardless of attributes 583 */ 584 int ndi_event_do_callback(ndi_event_hdl_t handle, dev_info_t *child_dip, 585 ddi_eventcookie_t cookie, void *bus_impldata); 586 587 /* 588 * ndi_event_tag_to_cookie: utility function to find an event cookie 589 * given an event tag 590 */ 591 ddi_eventcookie_t 592 ndi_event_tag_to_cookie(ndi_event_hdl_t handle, int event_tag); 593 594 /* 595 * ndi_event_cookie_to_tag: utility function to find an event tag 596 * given an event_cookie 597 */ 598 int 599 ndi_event_cookie_to_tag(ndi_event_hdl_t handle, 600 ddi_eventcookie_t cookie); 601 602 /* 603 * ndi_event_cookie_to_name: utility function to find an event 604 * name given an event_cookie 605 */ 606 char * 607 ndi_event_cookie_to_name(ndi_event_hdl_t handle, 608 ddi_eventcookie_t cookie); 609 610 /* 611 * ndi_event_tag_to_name: utility function to find an event 612 * name given an event_tag 613 */ 614 char * 615 ndi_event_tag_to_name(ndi_event_hdl_t handle, int event_tag); 616 617 dev_info_t * 618 ndi_devi_config_vhci(char *, int); 619 620 #ifdef DEBUG 621 /* 622 * ndi_event_dump_hdl: debug functionality used to display event handle 623 */ 624 void 625 ndi_event_dump_hdl(struct ndi_event_hdl *hdl, char *location); 626 #endif 627 628 /* 629 * Default busop bus_config helper functions 630 */ 631 int 632 ndi_busop_bus_config(dev_info_t *pdip, uint_t flags, ddi_bus_config_op_t op, 633 void *arg, dev_info_t **child, clock_t reset_delay); 634 635 int 636 ndi_busop_bus_unconfig(dev_info_t *dip, uint_t flags, ddi_bus_config_op_t op, 637 void *arg); 638 639 640 /* 641 * Bus Resource allocation structures and function prototypes exported 642 * by busra module 643 */ 644 645 /* structure for specifying a request */ 646 typedef struct ndi_ra_request { 647 uint_t ra_flags; /* General flags */ 648 /* see bit definitions below */ 649 650 uint64_t ra_len; /* Requested allocation length */ 651 652 uint64_t ra_addr; /* Specific base address requested */ 653 654 uint64_t ra_boundbase; /* Base address of the area for */ 655 /* the allocated resource to be */ 656 /* restricted to */ 657 658 uint64_t ra_boundlen; /* Length of the area, starting */ 659 /* from ra_boundbase, for the */ 660 /* allocated resource to be */ 661 /* restricted to. */ 662 663 uint64_t ra_align_mask; /* Alignment mask used for */ 664 /* allocated base address */ 665 } ndi_ra_request_t; 666 667 668 /* ra_flags bit definitions */ 669 #define NDI_RA_ALIGN_SIZE 0x0001 /* Set the alignment of the */ 670 /* allocated resource address */ 671 /* according to the ra_len */ 672 /* value (alignment mask will */ 673 /* be (ra_len - 1)). Value of */ 674 /* ra_len has to be power of 2. */ 675 /* If this flag is set, value of */ 676 /* ra_align_mask will be ignored. */ 677 678 679 #define NDI_RA_ALLOC_BOUNDED 0x0002 /* Indicates that the resource */ 680 /* should be restricted to the */ 681 /* area specified by ra_boundbase */ 682 /* and ra_boundlen */ 683 684 #define NDI_RA_ALLOC_SPECIFIED 0x0004 /* Indicates that a specific */ 685 /* address (ra_addr value) is */ 686 /* requested. */ 687 688 #define NDI_RA_ALLOC_PARTIAL_OK 0x0008 /* Indicates if requested size */ 689 /* (ra_len) chunk is not available */ 690 /* then allocate as big chunk as */ 691 /* possible which is less than or */ 692 /* equal to ra_len size. */ 693 694 695 /* return values specific to bus resource allocator */ 696 #define NDI_RA_PARTIAL_REQ -7 697 698 699 700 701 /* Predefined types for generic type of resources */ 702 #define NDI_RA_TYPE_MEM "memory" 703 #define NDI_RA_TYPE_IO "io" 704 #define NDI_RA_TYPE_PCI_BUSNUM "pci_bus_number" 705 #define NDI_RA_TYPE_PCI_PREFETCH_MEM "pci_prefetchable_memory" 706 #define NDI_RA_TYPE_INTR "interrupt" 707 708 709 710 /* flag bit definition */ 711 #define NDI_RA_PASS 0x0001 /* pass request up the dev tree */ 712 713 714 /* 715 * Prototype definitions for functions exported 716 */ 717 718 int 719 ndi_ra_map_setup(dev_info_t *dip, char *type); 720 721 int 722 ndi_ra_map_destroy(dev_info_t *dip, char *type); 723 724 int 725 ndi_ra_alloc(dev_info_t *dip, ndi_ra_request_t *req, uint64_t *basep, 726 uint64_t *lenp, char *type, uint_t flag); 727 728 int 729 ndi_ra_free(dev_info_t *dip, uint64_t base, uint64_t len, char *type, 730 uint_t flag); 731 732 733 /* 734 * ndi_dev_is_prom_node: Return non-zero if the node is a prom node 735 */ 736 int ndi_dev_is_prom_node(dev_info_t *); 737 738 /* 739 * ndi_dev_is_pseudo_node: Return non-zero if the node is a pseudo node. 740 * NB: all non-prom nodes are pseudo nodes. 741 * c.f. ndi_dev_is_persistent_node 742 */ 743 int ndi_dev_is_pseudo_node(dev_info_t *); 744 745 /* 746 * ndi_dev_is_persistent_node: Return non-zero if the node has the 747 * property of persistence. 748 */ 749 int ndi_dev_is_persistent_node(dev_info_t *); 750 751 /* 752 * ndi_dev_is_hotplug_node: Return non-zero if the node was created by hotplug. 753 */ 754 int ndi_dev_is_hotplug_node(dev_info_t *); 755 756 /* 757 * ndi_dev_is_hidden_node: Return non-zero if the node is hidden. 758 */ 759 int ndi_dev_is_hidden_node(dev_info_t *); 760 761 /* 762 * ndi_devi_set_hidden: mark a node as hidden 763 * ndi_devi_clr_hidden: mark a node as visible 764 */ 765 void ndi_devi_set_hidden(dev_info_t *); 766 void ndi_devi_clr_hidden(dev_info_t *); 767 768 /* 769 * Event posted when a fault is reported 770 */ 771 #define DDI_DEVI_FAULT_EVENT "DDI:DEVI_FAULT" 772 773 struct ddi_fault_event_data { 774 dev_info_t *f_dip; 775 ddi_fault_impact_t f_impact; 776 ddi_fault_location_t f_location; 777 const char *f_message; 778 ddi_devstate_t f_oldstate; 779 }; 780 781 /* 782 * Access handle/DMA handle fault flag setting/clearing functions for nexi 783 */ 784 void ndi_set_acc_fault(ddi_acc_handle_t ah); 785 void ndi_clr_acc_fault(ddi_acc_handle_t ah); 786 void ndi_set_dma_fault(ddi_dma_handle_t dh); 787 void ndi_clr_dma_fault(ddi_dma_handle_t dh); 788 789 /* Driver.conf property merging */ 790 int ndi_merge_node(dev_info_t *, int (*)(dev_info_t *, char *, int)); 791 void ndi_merge_wildcard_node(dev_info_t *); 792 793 /* 794 * Ndi 'flavor' support: These interfaces are to support a nexus driver 795 * with multiple 'flavors' of children (devi_flavor of child), coupled 796 * with a child flavor-specifc private data mechanism (via devi_flavor_v 797 * of parent). This is provided as an extension to ddi_[sg]et_driver_private, 798 * where the vanilla 'flavor' is what is stored or retrieved via 799 * ddi_[sg]et_driver_private. 800 * 801 * Flavors are indexed with a small integer. The first flavor, flavor 802 * zero, is always present and reserved as the 'vanilla' flavor. 803 * Space for extra flavors can be allocated and private pointers 804 * with respect to each flavor set and retrieved. 805 * 806 * NOTE:For a nexus driver, if the need to support multiple flavors of 807 * children is understood from the begining, then a private 'flavor' 808 * mechanism can be implemented via ddi_[sg]et_driver_private. 809 * 810 * With SCSA, the need to support multiple flavors of children was not 811 * anticipated, and ddi_get_driver_private(9F) of an initiator port 812 * devinfo node was publicly defined in the DDI to return a 813 * scsi_device(9S) child-flavor specific value: a pointer to 814 * scsi_hba_tran(9S). Over the years, each time the need to support 815 * a new flavor of child has occurred, a new form of overload/kludge 816 * has been devised. The ndi 'flavors' interfaces provide a simple way 817 * to address this issue that can be used by both SCSA nexus support, 818 * and by other nexus drivers. 819 */ 820 821 /* 822 * Interfaces to maintain flavor-specific private data for children of self 823 */ 824 #define NDI_FLAVOR_VANILLA 0 825 826 void ndi_flavorv_alloc(dev_info_t *self, int nflavors); 827 void ndi_flavorv_set(dev_info_t *self, ndi_flavor_t child_flavor, void *); 828 void *ndi_flavorv_get(dev_info_t *self, ndi_flavor_t child_flavor); 829 830 /* Interfaces for 'self' nexus driver to get/set flavor of child */ 831 void ndi_flavor_set(dev_info_t *child, ndi_flavor_t child_flavor); 832 ndi_flavor_t ndi_flavor_get(dev_info_t *child); 833 834 #endif /* _KERNEL */ 835 836 #ifdef __cplusplus 837 } 838 #endif 839 840 #endif /* _SYS_SUNNDI_H */ 841