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