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