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