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_DDI_HP_IMPL_H 27 #define _SYS_DDI_HP_IMPL_H 28 29 /* 30 * Sun DDI hotplug implementation specific definitions 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #ifdef _KERNEL 38 39 /* Flags for sync request and async hotplug request */ 40 #define DDI_HP_REQ_SYNC 0x0001 41 #define DDI_HP_REQ_ASYNC 0x0002 42 43 /* Check if a handle represents a port or a connector */ 44 #define DDI_HP_IS_VIRTUAL_PORT(hdlp) \ 45 (hdlp->cn_info.cn_type == DDI_HP_CN_TYPE_VIRTUAL_PORT) 46 47 /* 48 * ddi_hp_cn_handle_t 49 * 50 * DDI handle for a registered Hotplug Connection (CN) 51 */ 52 typedef struct ddi_hp_cn_handle { 53 dev_info_t *cn_dip; /* The dip that the handle is linked */ 54 ddi_hp_cn_info_t cn_info; /* Connection info */ 55 struct ddi_hp_cn_handle *next; /* Next Connector/Port. */ 56 } ddi_hp_cn_handle_t; 57 58 typedef struct ddi_hp_cn_async_event_entry { 59 dev_info_t *dip; 60 char *cn_name; 61 ddi_hp_cn_state_t target_state; 62 } ddi_hp_cn_async_event_entry_t; 63 64 /* 65 * ddi_hp_op_t 66 * 67 * Typedef for Hotplug OPS commands used with bus_hp_op() 68 */ 69 typedef enum { 70 DDI_HPOP_CN_GET_STATE = 1, /* Get Connection state */ 71 DDI_HPOP_CN_CHANGE_STATE, /* Change Connection state */ 72 DDI_HPOP_CN_PROBE, /* Probe Connection */ 73 DDI_HPOP_CN_UNPROBE, /* Unprobe Connection */ 74 DDI_HPOP_CN_GET_PROPERTY, /* Get bus specific property */ 75 DDI_HPOP_CN_SET_PROPERTY, /* Set bus specific property */ 76 DDI_HPOP_CN_CREATE_PORT, /* Create a port for virtual hotplug */ 77 DDI_HPOP_CN_REMOVE_PORT /* Remove an empty port */ 78 } ddi_hp_op_t; 79 80 #define DDIHP_CN_OPS(hdlp, op, arg, result, ret) \ 81 if (DDI_HP_IS_VIRTUAL_PORT(hdlp)) \ 82 ret = ddihp_port_ops(hdlp, op, arg, result); \ 83 else \ 84 ret = ddihp_connector_ops(hdlp, op, arg, result); 85 86 #define NEXUS_HAS_HP_OP(dip) \ 87 ((DEVI(dip)->devi_ops->devo_bus_ops) && \ 88 (DEVI(dip)->devi_ops->devo_bus_ops->busops_rev >= BUSO_REV_10) && \ 89 (DEVI(dip)->devi_ops->devo_bus_ops->bus_hp_op)) 90 91 /* 92 * ddi_hp_cn_sysevent_t 93 * 94 * The following correspond to sysevent defined subclasses 95 */ 96 typedef enum { 97 DDI_HP_CN_STATE_CHANGE, 98 DDI_HP_CN_REQ 99 } ddi_hp_cn_sysevent_t; 100 101 /* 102 * Control structure for tree walk during configure/unconfigure operation. 103 */ 104 typedef struct ddi_hp_cn_cfg { 105 boolean_t online; /* TRUE for online children; */ 106 /* FALSE for offline children. */ 107 int rv; /* Return error code */ 108 } ddi_hp_cn_cfg_t; 109 110 /* 111 * Misc 112 */ 113 114 /* Append a node to list */ 115 #define DDIHP_LIST_APPEND(type, head, node) \ 116 if (node) { \ 117 type *curr, *prev = NULL; \ 118 (node)->next = NULL; \ 119 for (curr = (head); curr; prev = curr, curr = curr->next); \ 120 if (prev == NULL) \ 121 (head) = (node); \ 122 else \ 123 prev->next = (node); \ 124 } 125 126 /* Remove a node from a list */ 127 #define DDIHP_LIST_REMOVE(type, head, node) \ 128 if (node) { \ 129 type *curr, *prev = NULL; \ 130 for (curr = (head); curr; prev = curr, curr = curr->next) { \ 131 if (curr == (node)) \ 132 break; \ 133 } \ 134 if (curr) { \ 135 if (prev == NULL) \ 136 (head) = (head)->next; \ 137 else \ 138 prev->next = curr->next; \ 139 } \ 140 } 141 142 int ddihp_modctl(int hp_op, char *path, char *cn_name, uintptr_t arg, 143 uintptr_t rval); 144 ddi_hp_cn_handle_t *ddihp_cn_name_to_handle(dev_info_t *dip, char *cn_name); 145 int ddihp_cn_getstate(ddi_hp_cn_handle_t *hdlp); 146 int ddihp_port_ops(ddi_hp_cn_handle_t *hdlp, ddi_hp_op_t op, 147 void *arg, void *result); 148 int ddihp_connector_ops(ddi_hp_cn_handle_t *hdlp, 149 ddi_hp_op_t op, void *arg, void *result); 150 void ddihp_cn_gen_sysevent(ddi_hp_cn_handle_t *hdlp, 151 ddi_hp_cn_sysevent_t event_sub_class, int hint, int kmflag); 152 int ddihp_cn_unregister(ddi_hp_cn_handle_t *hdlp); 153 154 #endif /* _KERNEL */ 155 156 #ifdef __cplusplus 157 } 158 #endif 159 160 #endif /* _SYS_DDI_HP_IMPL_H */ 161