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) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #ifndef _SYS_IB_IBNEX_IBNEX_H 26 #define _SYS_IB_IBNEX_IBNEX_H 27 28 /* 29 * ibnex.h 30 * This file contains defines and structures used within the IB Nexus 31 */ 32 33 #ifdef __cplusplus 34 extern "C" { 35 #endif 36 37 #include <sys/sunndi.h> 38 39 /* Defines for return codes within the IB nexus driver */ 40 typedef enum { 41 IBNEX_SUCCESS = 0, 42 IBNEX_FAILURE = -1, 43 IBNEX_OFFLINE_FAILED = -2, 44 IBNEX_BUSY = -3, 45 IBNEX_INVALID_NODE = -4 46 } ibnex_rval_t; 47 48 #define IBNEX_IOC_GUID_LEN 33 49 #define IBNEX_PHCI_GUID_LEN 66 50 51 /* IOC device node specific data */ 52 typedef struct ibnex_ioc_node_s { 53 ib_guid_t iou_guid; /* GUID of the IOU */ 54 ib_guid_t ioc_guid; /* GUID of the IOC */ 55 char ioc_id_string[IB_DM_IOC_ID_STRING_LEN]; 56 uint32_t ioc_ngids; 57 /* This field will be non NULL only for diconnected IOCs */ 58 ib_dm_ioc_ctrl_profile_t *ioc_profile; 59 char ioc_guid_str[IBNEX_IOC_GUID_LEN]; 60 char ioc_phci_guid[IBNEX_PHCI_GUID_LEN]; 61 } ibnex_ioc_node_t; 62 63 /* DLPI device node specific data */ 64 typedef struct ibnex_port_node_s { 65 uint8_t port_num; 66 int port_commsvc_idx; 67 ib_guid_t port_guid; 68 ib_guid_t port_hcaguid; 69 ib_pkey_t port_pkey; 70 dev_info_t *port_pdip; 71 } ibnex_port_node_t; 72 73 /* Pseudo device node specific data */ 74 typedef struct ibnex_pseudo_node_s { 75 char *pseudo_node_addr; /* node addr of drvr */ 76 char *pseudo_unit_addr; /* unit addr of drvr */ 77 int pseudo_unit_addr_len; /* unit addr len */ 78 char *pseudo_devi_name; /* name of driver */ 79 int pseudo_merge_node; /* merge node */ 80 } ibnex_pseudo_node_t; 81 82 /* 83 * Defines for Child device node types. Note that these values are also 84 * in use by usr/src/lib/cfgadm_plugins/ib/common/cfga_ib.h. 85 * Any changes to these need to be reflected in that file as well. 86 */ 87 typedef enum { 88 IBNEX_PORT_COMMSVC_NODE = 0, 89 IBNEX_VPPA_COMMSVC_NODE = 1, 90 IBNEX_HCASVC_COMMSVC_NODE = 2, 91 IBNEX_IOC_NODE = 4, 92 IBNEX_PSEUDO_NODE = 8 93 } ibnex_node_type_t; 94 95 #define IBNEX_HCA_CHILD_NODE (IBNEX_PORT_COMMSVC_NODE | \ 96 IBNEX_VPPA_COMMSVC_NODE | IBNEX_HCASVC_COMMSVC_NODE) 97 98 99 /* 100 * Defines for Child device node state: 101 * 102 * By default the node is set to CONFIGURED state. 103 * CONFIGURED:---(bus_config/cfgadm configure)---->CONFIGURED 104 * CONFIGURED:----(cfgadm unconfigure:success)--->UNCONFIGURED 105 * CONFIGURED:----(cfgadm unconfigure:fail)--->still CONFIGURED 106 * UNCONFIGURED:----(cfgadm configure:success)--->CONFIGURED 107 * 108 * We maintain two additional states: 109 * CONFIGURING:---(bus_config/cfgadm configure in progress 110 * UNCONFIGURING:--(cfgadm unconfigure in progress) 111 * This is maintained to avoid race conditions between multiple cfgadm 112 * operations. 113 */ 114 typedef enum ibnex_node_state_e { 115 IBNEX_CFGADM_CONFIGURED, /* node is "configured" */ 116 IBNEX_CFGADM_UNCONFIGURED, /* node is "unconfigured" */ 117 IBNEX_CFGADM_CONFIGURING, /* node getting configured */ 118 IBNEX_CFGADM_UNCONFIGURING /* node getting unconfigured */ 119 } ibnex_node_state_t; 120 121 /* 122 * Defines for reprobe_state: 123 * IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE 124 * Reprobe and notify if there is a property update 125 * IBNEX_NODE_REPROBE_NOTIFY_ALWAYS 126 * Reprobe and notify always. 127 * IBNEX_NODE_REPROBE_IOC_WAIT 128 * Reprobe for IOC apid waiting 129 * 130 * Device reprobes triggered by ibt_reprobe_dev will result in an DDI 131 * event, even though no prepoerties have changed. 132 */ 133 134 /* 135 * Defines for node_ap_state: 136 * IBNEX_NODE_AP_CONFIGURED 137 * this node was not unconfigured by cfgadm. 138 * IBNEX_NODE_AP_UNCONFIGURED 139 * this node has been unconfigured by cfgadm. 140 * IBNEX_NODE_AP_CONFIGURING 141 * this node is being configured by cfgadm 142 */ 143 #define IBNEX_NODE_AP_CONFIGURED 0x0 144 #define IBNEX_NODE_AP_UNCONFIGURED 0x1 145 #define IBNEX_NODE_AP_CONFIGURING 0x2 146 147 #define IBNEX_NODE_REPROBE_NOTIFY_ON_UPDATE 0x01 148 #define IBNEX_NODE_REPROBE_NOTIFY_ALWAYS 0x02 149 #define IBNEX_NODE_REPROBE_IOC_WAIT 0x04 150 151 /* Node specific information, stored as dev_info_t private data */ 152 typedef struct ibnex_node_data_s { 153 dev_info_t *node_dip; 154 union { 155 ibnex_ioc_node_t ioc_node; 156 ibnex_port_node_t port_node; 157 ibnex_pseudo_node_t pseudo_node; 158 } node_data; 159 struct ibnex_node_data_s *node_next; 160 struct ibnex_node_data_s *node_prev; 161 ibnex_node_type_t node_type; 162 ibnex_node_state_t node_state; 163 int node_reprobe_state; /* Node reprobe flag */ 164 unsigned int node_ap_state; 165 } ibnex_node_data_t; 166 167 /* 168 * The fields of IOC and Port node are initialized when the 169 * device node is created. These are read only for the rest 170 * of the IBnexus driver. 171 */ 172 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_ioc_node_s)) 173 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_port_node_s)) 174 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_pseudo_node_s)) 175 _NOTE(SCHEME_PROTECTS_DATA("stable data", ibnex_node_data_s)) 176 177 #define IBNEX_VALID_NODE_TYPE(n) \ 178 (((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \ 179 ((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \ 180 ((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE) || \ 181 ((n)->node_type == IBNEX_IOC_NODE) || \ 182 ((n)->node_type == IBNEX_PSEUDO_NODE)) 183 184 #define IBNEX_COMMSVC_NODE_TYPE(n) \ 185 (((n)->node_type == IBNEX_PORT_COMMSVC_NODE) || \ 186 ((n)->node_type == IBNEX_VPPA_COMMSVC_NODE) || \ 187 ((n)->node_type == IBNEX_HCASVC_COMMSVC_NODE)) 188 189 /* 190 * Definition for the IB nexus global per-instance structure. 191 * IB nexus supports only one instance. 192 */ 193 typedef struct ibnex_s { 194 dev_info_t *ibnex_dip; 195 kmutex_t ibnex_mutex; 196 int ibnex_num_comm_svcs; 197 char **ibnex_comm_svc_names; 198 int ibnex_nvppa_comm_svcs; 199 char **ibnex_vppa_comm_svc_names; 200 int ibnex_nhcasvc_comm_svcs; 201 char **ibnex_hcasvc_comm_svc_names; 202 ibnex_node_data_t *ibnex_port_node_head; 203 ibnex_node_data_t *ibnex_ioc_node_head; 204 ibnex_node_data_t *ibnex_pseudo_node_head; 205 206 /* 207 * NDI Event handle for -all- ibnexus events 208 * Event Cookie for IB_PROP_UPDATE_EVENT event 209 */ 210 ndi_event_hdl_t ibnex_ndi_event_hdl; 211 ddi_eventcookie_t ibnex_prop_update_evt_cookie; 212 213 /* Flags & condition variables for reprobe handling */ 214 int ibnex_reprobe_state; 215 kcondvar_t ibnex_reprobe_cv; 216 217 /* Count of disconnected IOCs still configured */ 218 int ibnex_num_disconnect_iocs; 219 220 /* Pseudo nodes inited from ibnex_get_snapshot? */ 221 int ibnex_pseudo_inited; 222 /* 223 * IOC list used by all HCAs. 224 */ 225 kcondvar_t ibnex_ioc_list_cv; 226 uint32_t ibnex_ioc_list_state; 227 ibdm_ioc_info_t *ibnex_ioc_list; 228 229 ddi_taskq_t *ibnex_taskq_id; 230 } ibnex_t; 231 232 /* 233 * States for ibnex_ioc_list_state 234 */ 235 #define IBNEX_IOC_LIST_READY 0x0 236 #define IBNEX_IOC_LIST_RENEW 0x1 237 #define IBNEX_IOC_LIST_ACCESS 0x2 238 239 /* 240 * States for ibnex_reprobe_state 241 * 0 to REPROBE_ALL_PROGRESS 242 * Reprobe all when no reprobes pending 243 * REPROBE_ALL_PROGRESS to REPROBE_ALL_WAIT 244 * Reprobe all request when another in progress 245 * 0 to REPROBE_IOC_WAIT 246 * Waiting for One or more reprobe_ioc to complete 247 * 248 * Reprobe logic will ensure : 249 * 1. A single reprobe all at any time. 250 * 2. No individual IOC reprobe overlaps with reprobe all. 251 * 3. Reprobe for multiple IOCs can be in parallel 252 * 4. Single reprobe for each IOC. 253 */ 254 #define IBNEX_REPROBE_ALL_PROGRESS 0x01 255 #define IBNEX_REPROBE_ALL_WAIT 0x02 256 #define IBNEX_REPROBE_IOC_WAIT 0x04 257 258 /* Defines for creating and binding device nodes. */ 259 #define IBNEX_MAX_COMPAT_NAMES 6 260 #define IBNEX_MAX_IBPORT_COMPAT_NAMES 3 261 #define IBNEX_MAX_COMPAT_LEN 48 262 #define IBNEX_MAX_COMPAT_PROP_SZ \ 263 IBNEX_MAX_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN 264 #define IBNEX_MAX_IBPORT_COMPAT_PROP_SZ \ 265 IBNEX_MAX_IBPORT_COMPAT_NAMES * IBNEX_MAX_COMPAT_LEN 266 #define IBNEX_DEVFS_ENUMERATE 0x1 /* enumerate via devfs(7fs) */ 267 #define IBNEX_CFGADM_ENUMERATE 0x2 /* enumerate via cfgadm */ 268 269 #define IBNEX_MAX_NODEADDR_SZ 35 270 271 /* Define for forming the unit address from GUID and class string */ 272 #define IBNEX_FORM_GUID(buf, size, guid) \ 273 (void) snprintf((buf), (size), "%llX", (longlong_t)guid); 274 275 #define IBNEX_INVALID_PKEY(pkey) \ 276 (((pkey) == IB_PKEY_INVALID_FULL) || \ 277 ((pkey) == IB_PKEY_INVALID_LIMITED)) 278 279 /* 280 * Defines for the tags of IB DDI events 281 */ 282 typedef enum { 283 IB_EVENT_TAG_PROP_UPDATE = 0 284 } ib_ddi_event_tag_t; 285 286 /* Definations for IB HW in device tree status */ 287 #define IBNEX_DEVTREE_NOT_CHECKED -1 288 #define IBNEX_HW_NOT_IN_DEVTREE 0 289 #define IBNEX_HW_IN_DEVTREE 1 290 291 #ifdef __cplusplus 292 } 293 #endif 294 295 #endif /* _SYS_IB_IBNEX_IBNEX_H */ 296