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