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 9 * http://www.opensource.org/licenses/cddl1.txt. 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 /* 23 * Copyright (c) 2004-2012 Emulex. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <emlxs.h> 28 29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 30 EMLXS_MSG_DEF(EMLXS_FCF_C); 31 32 /* 33 * STATE MACHINE RULES: 34 * 35 * - State change requests to an XXXX object when operating within 36 * an emlxs_XXXX state management function must be made 37 * using the emlxs_XXXX_state() call. 38 * 39 * - State change requests to an XXXX object when operating outside 40 * an emlxs_XXXX state management function must be made 41 * using the emlxs_XXXX_alloc(), emlxs_XXXX_free(), emlxs_XXXX_event() 42 * or emlxs_XXXX_..._notify() calls. 43 * 44 * - emlxs_XXXX_..._notify() calls are used by routines outside 45 * this fcf module to enter the state machine. 46 * 47 * - It is forbidden to make direct calls to emlxs_XXXX_...._action() 48 * functions. Only emlxs_XXXX_action() routines may make calls to 49 * emlxs_XXXX_...._action() functions. 50 * 51 * - Its is forbidden to make direct calls to emlxs_XXXX_action(). 52 * Only emlxs_XXXX_state() and emlxs_XXXX_event() routines may make 53 * calls to emlxs_XXXX_action(). 54 * 55 * - The EMLXS_FCF_LOCK must be held before calling: 56 * emlxs_XXXX_state(), emlxs_XXXX_event() and emlxs_XXXX_action(). 57 * 58 * - All other calls touching fcftab, fcfi, vfi, vpi, rpi objects 59 * must hold the EMLXS_FCF_LOCK to protect these objects. 60 */ 61 62 /* 63 * DEBUG MESSAGE TERMINATION RULES: 64 * 65 * - A message should end in ">" if a thread operating outside the 66 * XXXX state machine enters the XXXX state machine with a call to 67 * emlxs_XXXX_event() or emlxs_XXXX_state(). This includes calls made 68 * from emlxs_..._notify(), emlxs_..._mbcmpl() and emlxs_..._timer() 69 * routines since they represent the beginnning of new threads. 70 * 71 * - A message should end in "<" if the thread is about exit 72 * an emlxs_XXXX_..._action() without previously calling the 73 * next emlxs_XXXX_state(). This includes the emlxs_XXXX_action() 74 * and emlxs_XXXX_state() routines themselves since errors 75 * in these routines represent the termination of state change 76 * thread. 77 * 78 * - A message should end in "." if none of the previous 79 * conditions apply. 80 */ 81 82 /* ************************************************************************** */ 83 /* FCF Generic */ 84 /* ************************************************************************** */ 85 86 /* 87 * EVENT ARG1 88 * -------------------------------------------- 89 * FCF_EVENT_STATE_ENTER None 90 * 91 * FCF_EVENT_LINKUP None 92 * FCF_EVENT_LINKDOWN None 93 * FCF_EVENT_CVL vpi 94 * FCF_EVENT_FCFTAB_FULL None 95 * FCF_EVENT_FCF_FOUND fcf_index 96 * FCF_EVENT_FCF_LOST fcf_index 97 * FCF_EVENT_FCF_CHANGED fcf_index 98 * 99 * FCF_EVENT_FCFI_ONLINE FCFIobj_t* 100 * FCF_EVENT_FCFI_OFFLINE FCFIobj_t* 101 * FCF_EVENT_FCFI_PAUSE FCFIobj_t* 102 * 103 * FCF_EVENT_VFI_ONLINE VFIobj_t* 104 * FCF_EVENT_VFI_OFFLINE VFIobj_t* 105 * FCF_EVENT_VFI_PAUSE VFIobj_t* 106 * 107 * FCF_EVENT_VPI_ONLINE VPIobj_t* 108 * FCF_EVENT_VPI_OFFLINE VPIobj_t* 109 * FCF_EVENT_VPI_PAUSE VPIobj_t* 110 * 111 * FCF_EVENT_RPI_ONLINE RPIobj_t* 112 * FCF_EVENT_RPI_OFFLINE RPIobj_t* 113 * FCF_EVENT_RPI_PAUSE RPIobj_t* 114 * FCF_EVENT_RPI_RESUME RPIobj_t* 115 * FCF_EVENT_RPI_TIMEOUT RPIobj_t* 116 */ 117 118 /* Order does not matter */ 119 emlxs_table_t emlxs_fcf_event_table[] = 120 { 121 {FCF_EVENT_STATE_ENTER, "E_ENTER"}, 122 123 {FCF_EVENT_SHUTDOWN, "E_SHUTDOWN"}, 124 {FCF_EVENT_LINKUP, "E_LINKUP"}, 125 {FCF_EVENT_LINKDOWN, "E_LINKDOWN"}, 126 {FCF_EVENT_CVL, "E_CVL"}, 127 {FCF_EVENT_FCFTAB_FULL, "E_TABLE_FULL"}, 128 {FCF_EVENT_FCF_FOUND, "E_FCF_FOUND"}, 129 {FCF_EVENT_FCF_LOST, "E_FCF_LOST"}, 130 {FCF_EVENT_FCF_CHANGED, "E_FCF_CHANGED"}, 131 132 {FCF_EVENT_FCFI_ONLINE, "E_FCFI_ONLINE"}, 133 {FCF_EVENT_FCFI_OFFLINE, "E_FCFI_OFFLINE"}, 134 {FCF_EVENT_FCFI_PAUSE, "E_FCFI_PAUSE"}, 135 136 {FCF_EVENT_VFI_ONLINE, "E_VFI_ONLINE"}, 137 {FCF_EVENT_VFI_OFFLINE, "E_VFI_OFFLINE"}, 138 {FCF_EVENT_VFI_PAUSE, "E_VFI_PAUSE"}, 139 140 {FCF_EVENT_VPI_ONLINE, "E_VPI_ONLINE"}, 141 {FCF_EVENT_VPI_OFFLINE, "E_VPI_OFFLINE"}, 142 {FCF_EVENT_VPI_PAUSE, "E_VPI_PAUSE"}, 143 144 {FCF_EVENT_RPI_ONLINE, "E_RPI_ONLINE"}, 145 {FCF_EVENT_RPI_OFFLINE, "E_RPI_OFFLINE"}, 146 {FCF_EVENT_RPI_PAUSE, "E_RPI_PAUSE"}, 147 {FCF_EVENT_RPI_RESUME, "E_RPI_RESUME"}, 148 149 }; /* emlxs_fcf_event_table */ 150 151 152 /* Order does not matter */ 153 emlxs_table_t emlxs_fcf_reason_table[] = 154 { 155 {FCF_REASON_NONE, "R_NONE"}, 156 {FCF_REASON_REENTER, "R_REENTER"}, 157 {FCF_REASON_EVENT, "R_EVENT"}, 158 {FCF_REASON_REQUESTED, "R_REQUESTED"}, 159 {FCF_REASON_NO_MBOX, "R_NO_MBOX"}, 160 {FCF_REASON_NO_BUFFER, "R_NO_BUFFER"}, 161 {FCF_REASON_SEND_FAILED, "R_SEND_FAILED"}, 162 {FCF_REASON_MBOX_FAILED, "R_MBOX_FAILED"}, 163 {FCF_REASON_MBOX_BUSY, "R_MBOX_BUSY"}, 164 {FCF_REASON_NO_FCFI, "R_NO_FCFI"}, 165 {FCF_REASON_NO_VFI, "R_NO_VFI"}, 166 {FCF_REASON_ONLINE_FAILED, "R_ONLINE_FAILED"}, 167 {FCF_REASON_OFFLINE_FAILED, "R_OFFLINE_FAILED"}, 168 {FCF_REASON_OP_FAILED, "R_OP_FAILED"}, 169 {FCF_REASON_NO_PKT, "R_NO_PKT"}, 170 {FCF_REASON_NO_NODE, "R_NO_NODE"}, 171 {FCF_REASON_NOT_ALLOWED, "R_NOT_ALLOWED"}, 172 {FCF_REASON_UNUSED, "R_UNUSED"}, 173 {FCF_REASON_INVALID, "R_INVALID"}, 174 175 }; /* emlxs_fcf_reason_table */ 176 177 178 /* ********************************************************************** */ 179 /* FCFTAB Generic */ 180 /* ********************************************************************** */ 181 static char *emlxs_fcftab_state_xlate(emlxs_port_t *port, 182 uint32_t state); 183 static uint32_t emlxs_fcftab_event(emlxs_port_t *port, uint32_t evt, 184 void *arg1); 185 static uint32_t emlxs_fcftab_shutdown_action(emlxs_port_t *port, 186 uint32_t evt, void *arg1); 187 188 /* ********************************************************************** */ 189 /* FC FCFTAB */ 190 /* ********************************************************************** */ 191 192 /* Order does not matter */ 193 emlxs_table_t emlxs_fc_fcftab_state_table[] = 194 { 195 {FC_FCFTAB_STATE_SHUTDOWN, "FCFTAB_SHUTDOWN"}, 196 {FC_FCFTAB_STATE_OFFLINE, "FCFTAB_OFFLINE"}, 197 198 {FC_FCFTAB_STATE_TOPO, "FCFTAB_TOPO"}, 199 {FC_FCFTAB_STATE_TOPO_FAILED, "FCFTAB_TOPO_FAILED"}, 200 {FC_FCFTAB_STATE_TOPO_CMPL, "FCFTAB_TOPO_CMPL"}, 201 202 {FC_FCFTAB_STATE_CFGLINK, "FCFTAB_CFGLINK"}, 203 {FC_FCFTAB_STATE_CFGLINK_FAILED, "FCFTAB_CFGLINK_FAILED"}, 204 {FC_FCFTAB_STATE_CFGLINK_CMPL, "FCFTAB_CFGLINK_CMPL"}, 205 206 {FC_FCFTAB_STATE_SPARM, "FCFTAB_SPARM"}, 207 {FC_FCFTAB_STATE_SPARM_FAILED, "FCFTAB_SPARM_FAILED"}, 208 {FC_FCFTAB_STATE_SPARM_CMPL, "FCFTAB_SPARM_CMPL"}, 209 210 {FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL, 211 "FCFTAB_FCFI_OFFLINE_CMPL"}, 212 {FC_FCFTAB_STATE_FCFI_OFFLINE, "FCFTAB_FCFI_OFFLINE"}, 213 214 {FC_FCFTAB_STATE_FCFI_ONLINE, "FCFTAB_FCFI_ONLINE"}, 215 {FC_FCFTAB_STATE_FCFI_ONLINE_CMPL, "FCFTAB_FCFI_ONLINE_CMPL"}, 216 217 {FC_FCFTAB_STATE_ONLINE, "FCFTAB_ONLINE"}, 218 219 }; /* emlxs_fc_fcftab_state_table */ 220 221 static void emlxs_fc_fcftab_online_timer(emlxs_hba_t *hba); 222 223 static uint32_t emlxs_fc_fcftab_offline_action(emlxs_port_t *port, 224 uint32_t evt, void *arg1); 225 static uint32_t emlxs_fc_fcftab_online_action(emlxs_port_t *port, 226 uint32_t evt, void *arg1); 227 228 static uint32_t emlxs_fc_fcftab_topo_cmpl_action(emlxs_port_t *port, 229 uint32_t evt, void *arg1); 230 static uint32_t emlxs_fc_fcftab_topo_failed_action(emlxs_port_t *port, 231 uint32_t evt, void *arg1); 232 static uint32_t emlxs_fc_fcftab_topo_action(emlxs_port_t *port, 233 uint32_t evt, void *arg1); 234 235 static uint32_t emlxs_fc_fcftab_cfglink_cmpl_action(emlxs_port_t *port, 236 uint32_t evt, void *arg1); 237 static uint32_t emlxs_fc_fcftab_cfglink_failed_action(emlxs_port_t *port, 238 uint32_t evt, void *arg1); 239 static uint32_t emlxs_fc_fcftab_cfglink_action(emlxs_port_t *port, 240 uint32_t evt, void *arg1); 241 242 static uint32_t emlxs_fc_fcftab_sparm_cmpl_action(emlxs_port_t *port, 243 uint32_t evt, void *arg1); 244 static uint32_t emlxs_fc_fcftab_sparm_failed_action(emlxs_port_t *port, 245 uint32_t evt, void *arg1); 246 static uint32_t emlxs_fc_fcftab_sparm_action(emlxs_port_t *port, 247 uint32_t evt, void *arg1); 248 249 static uint32_t emlxs_fc_fcftab_linkup_evt_action(emlxs_port_t *port, 250 uint32_t evt, void *arg1); 251 static uint32_t emlxs_fc_fcftab_linkdown_evt_action(emlxs_port_t *port, 252 uint32_t evt, void *arg1); 253 254 static uint32_t emlxs_fc_fcftab_fcfi_online_evt_action(emlxs_port_t *port, 255 uint32_t evt, void *arg1); 256 static uint32_t emlxs_fc_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, 257 uint32_t evt, void *arg1); 258 259 static uint32_t emlxs_fc_fcftab_shutdown_evt_action(emlxs_port_t *port, 260 uint32_t evt, void *arg1); 261 static uint32_t emlxs_fc_fcftab_fcfi_offline_action(emlxs_port_t *port, 262 uint32_t evt, void *arg1); 263 static uint32_t emlxs_fc_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, 264 uint32_t evt, void *arg1); 265 static uint32_t emlxs_fc_fcftab_fcfi_online_action(emlxs_port_t *port, 266 uint32_t evt, void *arg1); 267 static uint32_t emlxs_fc_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, 268 uint32_t evt, void *arg1); 269 270 static char *emlxs_fc_fcftab_state_xlate(uint32_t state); 271 static uint32_t emlxs_fc_fcftab_event(emlxs_port_t *port, 272 uint32_t evt, void *arg1); 273 static uint32_t emlxs_fc_fcftab_req_handler(emlxs_port_t *port, void *arg1); 274 275 /* 276 * - Online sequencing can start from FC_FCFTAB_STATE_OFFLINE state 277 * 278 * - Offline sequencing can interrupt the online sequencing at the 279 * entry of the next wait state. 280 * 281 * NORMAL ONLINE SEQ 282 * --------------------------- 283 * LINK_UP event <-- Adapter 284 * FC_FCFTAB_STATE_OFFLINE 285 * FC_FCFTAB_STATE_TOPO 286 * FC_FCFTAB_STATE_TOPO_CMPL 287 * FC_FCFTAB_STATE_CFGLINK 288 * FC_FCFTAB_STATE_CFGLINK_CMPL 289 * FC_FCFTAB_STATE_SPARM 290 * FC_FCFTAB_STATE_SPARM_CMPL 291 * FC_FCFTAB_STATE_FCFI_ONLINE 292 * FC_FCFTAB_STATE_FCFI_ONLINE_CMPL 293 * FC_FCFTAB_STATE_ONLINE 294 * 295 * 296 * NORMAL OFFLINE SEQ 297 * --------------------------- 298 * LINK_DOWN event <-- Adapter 299 * FC_FCFTAB_STATE_ONLINE 300 * FC_FCFTAB_STATE_FCFI_OFFLINE 301 * FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL 302 * FC_FCFTAB_STATE_OFFLINE 303 * 304 */ 305 /* Order does matter */ 306 static void *emlxs_fc_fcftab_action_table[] = 307 { 308 /* Action routine Event */ 309 /* FC_FCFTAB_STATE_SHUTDOWN 0 (Requires adapter reset) */ 310 (void *) emlxs_fcftab_shutdown_action, /* STATE_ENTER */ 311 (void *) NULL, /* SHUTDOWN */ 312 (void *) NULL, /* LINK_UP */ 313 (void *) NULL, /* LINK_DOWN */ 314 (void *) NULL, /* FCFI_ONLINE */ 315 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 316 317 /* FC_FCFTAB_STATE_OFFLINE 1 (Wait for LINK_UP event) */ 318 (void *) emlxs_fc_fcftab_offline_action, /* STATE_ENTER */ 319 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 320 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 321 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 322 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 323 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 324 325 326 /* FC_FCFTAB_STATE_TOPO 2 (Wait for topo mbcmpl) */ 327 (void *) emlxs_fc_fcftab_topo_action, /* STATE_ENTER */ 328 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 329 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 330 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 331 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 332 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 333 334 /* FC_FCFTAB_STATE_TOPO_FAILED 3 (Transitional) */ 335 (void *) emlxs_fc_fcftab_topo_failed_action, /* STATE_ENTER */ 336 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 337 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 338 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 339 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 340 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 341 342 /* FC_FCFTAB_STATE_TOPO_CMPL 4 (Transitional) */ 343 (void *) emlxs_fc_fcftab_topo_cmpl_action, /* STATE_ENTER */ 344 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 345 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 346 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 347 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 348 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 349 350 351 /* FC_FCFTAB_STATE_CFGLINK 5 (Wait for cfglink mbcmpl) */ 352 (void *) emlxs_fc_fcftab_cfglink_action, /* STATE_ENTER */ 353 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 354 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 355 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 356 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 357 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 358 359 /* FC_FCFTAB_STATE_CFGLINK_FAILED 6 (Transitional) */ 360 (void *) emlxs_fc_fcftab_cfglink_failed_action, /* STATE_ENTER */ 361 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 362 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 363 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 364 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 365 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 366 367 /* FC_FCFTAB_STATE_CFGLINK_CMPL 7 (Transitional) */ 368 (void *) emlxs_fc_fcftab_cfglink_cmpl_action, /* STATE_ENTER */ 369 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 370 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 371 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 372 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 373 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 374 375 376 /* FC_FCFTAB_STATE_SPARM 8 (Wait for sparm mbcmpl) */ 377 (void *) emlxs_fc_fcftab_sparm_action, /* STATE_ENTER */ 378 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 379 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 380 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 381 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 382 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 383 384 /* FC_FCFTAB_STATE_SPARM_FAILED 9 (Transitional) */ 385 (void *) emlxs_fc_fcftab_sparm_failed_action, /* STATE_ENTER */ 386 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 387 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 388 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 389 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 390 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 391 392 /* FC_FCFTAB_STATE_SPARM_CMPL 10 (Transitional) */ 393 (void *) emlxs_fc_fcftab_sparm_cmpl_action, /* STATE_ENTER */ 394 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 395 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 396 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 397 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 398 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 399 400 401 /* FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL 11 (Transitional) */ 402 (void *) emlxs_fc_fcftab_fcfi_offline_cmpl_action, /* STATE_ENTER */ 403 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 404 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 405 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 406 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 407 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 408 409 /* FC_FCFTAB_STATE_FCFI_OFFLINE 12 (Wait for FCFI_OFFLINE event) */ 410 (void *) emlxs_fc_fcftab_fcfi_offline_action, /* STATE_ENTER */ 411 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 412 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 413 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 414 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 415 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 416 417 418 /* FC_FCFTAB_STATE_FCFI_ONLINE 13 (Wait for FCFI_ONLINE event) */ 419 (void *) emlxs_fc_fcftab_fcfi_online_action, /* STATE_ENTER */ 420 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 421 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 422 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 423 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 424 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 425 426 /* FC_FCFTAB_STATE_FCFI_ONLINE_CMPL 14 (Transitional) */ 427 (void *) emlxs_fc_fcftab_fcfi_online_cmpl_action, /* STATE_ENTER */ 428 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 429 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 430 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 431 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 432 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 433 434 435 /* FC_FCFTAB_STATE_ONLINE 15 (Wait for LINK_DOWN evt) */ 436 (void *) emlxs_fc_fcftab_online_action, /* STATE_ENTER */ 437 (void *) emlxs_fc_fcftab_shutdown_evt_action, /* SHUTDOWN */ 438 (void *) emlxs_fc_fcftab_linkup_evt_action, /* LINK_UP */ 439 (void *) emlxs_fc_fcftab_linkdown_evt_action, /* LINK_DOWN */ 440 (void *) emlxs_fc_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 441 (void *) emlxs_fc_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 442 443 }; /* emlxs_fc_fcftab_action_table[] */ 444 #define FC_FCFTAB_ACTION_EVENTS 6 445 #define FC_FCFTAB_ACTION_STATES \ 446 (sizeof (emlxs_fc_fcftab_action_table)/ \ 447 (FC_FCFTAB_ACTION_EVENTS * sizeof (void *))) 448 449 450 /* ********************************************************************** */ 451 /* FCOE FCFTAB */ 452 /* ********************************************************************** */ 453 454 /* Order does not matter */ 455 emlxs_table_t emlxs_fcoe_fcftab_state_table[] = 456 { 457 {FCOE_FCFTAB_STATE_SHUTDOWN, "FCFTAB_SHUTDOWN"}, 458 {FCOE_FCFTAB_STATE_OFFLINE, "FCFTAB_OFFLINE"}, 459 460 {FCOE_FCFTAB_STATE_SOLICIT, "FCFTAB_SOLICIT"}, 461 {FCOE_FCFTAB_STATE_SOLICIT_FAILED, "FCFTAB_SOLICIT_FAILED"}, 462 {FCOE_FCFTAB_STATE_SOLICIT_CMPL, "FCFTAB_SOLICIT_CMPL"}, 463 464 {FCOE_FCFTAB_STATE_READ, "FCFTAB_READ"}, 465 {FCOE_FCFTAB_STATE_READ_FAILED, "FCFTAB_READ_FAILED"}, 466 {FCOE_FCFTAB_STATE_READ_CMPL, "FCFTAB_READ_CMPL"}, 467 468 {FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL, 469 "FCFTAB_FCFI_OFFLINE_CMPL"}, 470 {FCOE_FCFTAB_STATE_FCFI_OFFLINE, "FCFTAB_FCFI_OFFLINE"}, 471 472 {FCOE_FCFTAB_STATE_FCFI_ONLINE, "FCFTAB_FCFI_ONLINE"}, 473 {FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL, 474 "FCFTAB_FCFI_ONLINE_CMPL"}, 475 476 {FCOE_FCFTAB_STATE_ONLINE, "FCFTAB_ONLINE"}, 477 478 }; /* emlxs_fcoe_fcftab_state_table */ 479 480 static uint32_t emlxs_fcoe_fcftab_sol_cmpl_action(emlxs_port_t *port, 481 uint32_t evt, void *arg1); 482 static uint32_t emlxs_fcoe_fcftab_sol_failed_action(emlxs_port_t *port, 483 uint32_t evt, void *arg1); 484 static uint32_t emlxs_fcoe_fcftab_sol_action(emlxs_port_t *port, 485 uint32_t evt, void *arg1); 486 static uint32_t emlxs_fcoe_fcftab_shutdown_evt_action(emlxs_port_t *port, 487 uint32_t evt, void *arg1); 488 static uint32_t emlxs_fcoe_fcftab_linkdown_evt_action(emlxs_port_t *port, 489 uint32_t evt, void *arg1); 490 static uint32_t emlxs_fcoe_fcftab_read_action(emlxs_port_t *port, 491 uint32_t evt, void *arg1); 492 static uint32_t emlxs_fcoe_fcftab_read_failed_action(emlxs_port_t *port, 493 uint32_t evt, void *arg1); 494 static uint32_t emlxs_fcoe_fcftab_read_cmpl_action(emlxs_port_t *port, 495 uint32_t evt, void *arg1); 496 static uint32_t emlxs_fcoe_fcftab_fcfi_online_action(emlxs_port_t *port, 497 uint32_t evt, void *arg1); 498 static uint32_t emlxs_fcoe_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, 499 uint32_t evt, void *arg1); 500 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_action(emlxs_port_t *port, 501 uint32_t evt, void *arg1); 502 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, 503 uint32_t evt, void *arg1); 504 static uint32_t emlxs_fcoe_fcftab_found_evt_action(emlxs_port_t *port, 505 uint32_t evt, void *arg1); 506 static uint32_t emlxs_fcoe_fcftab_lost_evt_action(emlxs_port_t *port, 507 uint32_t evt, void *arg1); 508 static uint32_t emlxs_fcoe_fcftab_changed_evt_action(emlxs_port_t *port, 509 uint32_t evt, void *arg1); 510 static uint32_t emlxs_fcoe_fcftab_full_evt_action(emlxs_port_t *port, 511 uint32_t evt, void *arg1); 512 static uint32_t emlxs_fcoe_fcftab_linkup_evt_action(emlxs_port_t *port, 513 uint32_t evt, void *arg1); 514 static uint32_t emlxs_fcoe_fcftab_cvl_evt_action(emlxs_port_t *port, 515 uint32_t evt, void *arg1); 516 static uint32_t emlxs_fcoe_fcftab_online_action(emlxs_port_t *port, 517 uint32_t evt, void *arg1); 518 static uint32_t emlxs_fcoe_fcftab_offline_action(emlxs_port_t *port, 519 uint32_t evt, void *arg1); 520 static uint32_t emlxs_fcoe_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, 521 uint32_t evt, void *arg1); 522 static uint32_t emlxs_fcoe_fcftab_fcfi_online_evt_action(emlxs_port_t *port, 523 uint32_t evt, void *arg1); 524 525 static void emlxs_fcoe_fcftab_read_timer(emlxs_hba_t *hba); 526 static void emlxs_fcoe_fcftab_sol_timer(emlxs_hba_t *hba); 527 static void emlxs_fcoe_fcftab_offline_timer(emlxs_hba_t *hba); 528 static char *emlxs_fcoe_fcftab_state_xlate(uint32_t state); 529 static uint32_t emlxs_fcoe_fcftab_event(emlxs_port_t *port, 530 uint32_t evt, void *arg1); 531 static uint32_t emlxs_fcoe_fcftab_state(emlxs_port_t *port, uint16_t state, 532 uint16_t reason, uint32_t explain, void *arg1); 533 534 /* 535 * - Online sequencing can start from FCOE_FCFTAB_STATE_OFFLINE state 536 * 537 * - Offline sequencing can interrupt the online sequencing at the 538 * entry of the next wait state. 539 * 540 * NORMAL ONLINE SEQ 541 * --------------------------- 542 * LINK_UP event <-- Adapter 543 * FCOE_FCFTAB_STATE_OFFLINE 544 * FCOE_FCFTAB_STATE_SOLICIT 545 * FCOE_FCFTAB_STATE_SOLICIT_CMPL 546 * FCOE_FCFTAB_STATE_READ 547 * FCOE_FCFTAB_STATE_READ_CMPL 548 * FCOE_FCFTAB_STATE_FCFI_OFFLINE 549 * FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL 550 * FCOE_FCFTAB_STATE_FCFI_ONLINE 551 * FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL 552 * FCOE_FCFTAB_STATE_ONLINE 553 * 554 * 555 * NORMAL OFFLINE SEQ 556 * --------------------------- 557 * LINK_DOWN event <-- Adapter 558 * FCOE_FCFTAB_STATE_ONLINE 559 * FCOE_FCFTAB_STATE_FCFI_OFFLINE 560 * FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL 561 * FCOE_FCFTAB_STATE_OFFLINE 562 * 563 */ 564 /* Order does matter */ 565 static void *emlxs_fcoe_fcftab_action_table[] = 566 { 567 /* Action routine Event */ 568 /* FCOE_FCFTAB_STATE_SHUTDOWN 0 (Requires adapter reset) */ 569 (void *) emlxs_fcftab_shutdown_action, /* STATE_ENTER */ 570 (void *) NULL, /* SHUTDOWN */ 571 (void *) NULL, /* LINK_UP */ 572 (void *) NULL, /* LINK_DOWN */ 573 (void *) NULL, /* CVL_RECD */ 574 (void *) NULL, /* FCF_FOUND */ 575 (void *) NULL, /* FCF_LOST */ 576 (void *) NULL, /* FCF_CHANGED */ 577 (void *) NULL, /* TABLE_FULL */ 578 (void *) NULL, /* FCFI_ONLINE */ 579 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 580 581 /* FCOE_FCFTAB_STATE_OFFLINE 1 (Wait for LINK_UP event) */ 582 (void *) emlxs_fcoe_fcftab_offline_action, /* STATE_ENTER */ 583 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 584 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 585 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 586 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 587 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 588 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 589 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 590 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 591 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 592 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 593 594 595 /* FCOE_FCFTAB_STATE_SOLICIT 2 (Wait on fcf_solicit cmpl) */ 596 (void *) emlxs_fcoe_fcftab_sol_action, /* STATE_ENTER */ 597 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 598 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 599 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 600 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 601 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 602 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 603 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 604 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 605 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 606 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 607 608 /* FCOE_FCFTAB_STATE_SOLICIT_FAILED 3 (Transitional) */ 609 (void *) emlxs_fcoe_fcftab_sol_failed_action, /* STATE_ENTER */ 610 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 611 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 612 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 613 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 614 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 615 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 616 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 617 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 618 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 619 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 620 621 /* FCOE_FCFTAB_STATE_SOLICIT_CMPL 4 (Wait on fcf timer cmpl) */ 622 (void *) emlxs_fcoe_fcftab_sol_cmpl_action, /* STATE_ENTER */ 623 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 624 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 625 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 626 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 627 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 628 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 629 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 630 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 631 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 632 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 633 634 635 /* FCOE_FCFTAB_STATE_READ 5 (Wait on fcf_read cmpl) */ 636 (void *) emlxs_fcoe_fcftab_read_action, /* STATE_ENTER */ 637 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 638 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 639 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 640 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 641 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 642 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 643 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 644 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 645 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 646 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 647 648 /* FCOE_FCFTAB_STATE_READ_FAILED 6 (Transitional) */ 649 (void *) emlxs_fcoe_fcftab_read_failed_action, /* STATE_ENTER */ 650 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 651 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 652 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 653 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 654 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 655 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 656 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 657 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 658 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 659 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 660 661 /* FCOE_FCFTAB_STATE_READ_CMPL 7 (Transitional) */ 662 (void *) emlxs_fcoe_fcftab_read_cmpl_action, /* STATE_ENTER */ 663 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 664 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 665 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 666 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 667 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 668 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 669 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 670 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 671 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 672 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 673 674 675 /* FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL 8 (Transitional) */ 676 (void *) emlxs_fcoe_fcftab_fcfi_offline_cmpl_action, /* STATE_ENTER */ 677 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 678 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 679 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 680 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 681 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 682 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 683 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 684 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 685 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 686 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 687 688 /* FCOE_FCFTAB_STATE_FCFI_OFFLINE 9 (Wait for FCFI_OFFLINE event) */ 689 (void *) emlxs_fcoe_fcftab_fcfi_offline_action, /* STATE_ENTER */ 690 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 691 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 692 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 693 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 694 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 695 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 696 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 697 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 698 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 699 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 700 701 702 /* FCOE_FCFTAB_STATE_FCFI_ONLINE 10 (Wait on FCFI_ONLINE event) */ 703 (void *) emlxs_fcoe_fcftab_fcfi_online_action, /* STATE_ENTER */ 704 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 705 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 706 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 707 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 708 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 709 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 710 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 711 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 712 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 713 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 714 715 /* FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL 11 (Transitional) */ 716 (void *) emlxs_fcoe_fcftab_fcfi_online_cmpl_action, /* STATE_ENTER */ 717 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 718 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 719 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 720 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 721 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 722 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 723 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 724 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 725 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 726 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 727 728 729 /* FCOE_FCFTAB_STATE_ONLINE 12 (Wait for LINK_DOWN event) */ 730 (void *) emlxs_fcoe_fcftab_online_action, /* STATE_ENTER */ 731 (void *) emlxs_fcoe_fcftab_shutdown_evt_action, /* SHUTDOWN */ 732 (void *) emlxs_fcoe_fcftab_linkup_evt_action, /* LINK_UP */ 733 (void *) emlxs_fcoe_fcftab_linkdown_evt_action, /* LINK_DOWN */ 734 (void *) emlxs_fcoe_fcftab_cvl_evt_action, /* CVL_RECD */ 735 (void *) emlxs_fcoe_fcftab_found_evt_action, /* FCF_FOUND */ 736 (void *) emlxs_fcoe_fcftab_lost_evt_action, /* FCF_LOST */ 737 (void *) emlxs_fcoe_fcftab_changed_evt_action, /* FCF_CHANGED */ 738 (void *) emlxs_fcoe_fcftab_full_evt_action, /* TABLE_FULL */ 739 (void *) emlxs_fcoe_fcftab_fcfi_online_evt_action, /* FCFI_ONLINE */ 740 (void *) emlxs_fcoe_fcftab_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 741 742 }; /* emlxs_fcoe_fcftab_action_table[] */ 743 #define FCOE_FCFTAB_ACTION_EVENTS 11 744 #define FCOE_FCFTAB_ACTION_STATES \ 745 (sizeof (emlxs_fcoe_fcftab_action_table)/ \ 746 (FCOE_FCFTAB_ACTION_EVENTS * sizeof (void *))) 747 748 749 750 751 /* ********************************************************************** */ 752 /* FCFI */ 753 /* ********************************************************************** */ 754 755 /* Order does not matter */ 756 emlxs_table_t emlxs_fcfi_state_table[] = 757 { 758 {FCFI_STATE_FREE, "FCFI_FREE"}, 759 760 {FCFI_STATE_OFFLINE, "FCFI_OFFLINE"}, 761 762 {FCFI_STATE_UNREG_CMPL, "FCFI_UNREG_CMPL"}, 763 {FCFI_STATE_UNREG_FAILED, "FCFI_UNREG_FAILED"}, 764 {FCFI_STATE_UNREG, "FCFI_UNREG"}, 765 766 {FCFI_STATE_REG, "FCFI_REG"}, 767 {FCFI_STATE_REG_FAILED, "FCFI_REG_FAILED"}, 768 {FCFI_STATE_REG_CMPL, "FCFI_REG_CMPL"}, 769 770 {FCFI_STATE_VFI_OFFLINE_CMPL, "FCFI_VFI_OFFLINE_CMPL"}, 771 {FCFI_STATE_VFI_OFFLINE, "FCFI_VFI_OFFLINE"}, 772 773 {FCFI_STATE_VFI_ONLINE, "FCFI_VFI_ONLINE"}, 774 {FCFI_STATE_VFI_ONLINE_CMPL, "FCFI_VFI_ONLINE_CMPL"}, 775 776 {FCFI_STATE_PAUSED, "FCFI_PAUSED"}, 777 {FCFI_STATE_ONLINE, "FCFI_ONLINE"}, 778 779 }; /* emlxs_fcfi_state_table */ 780 781 782 static uint32_t emlxs_fcfi_free_action(emlxs_port_t *port, 783 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 784 static uint32_t emlxs_fcfi_online_evt_action(emlxs_port_t *port, 785 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 786 static uint32_t emlxs_fcfi_offline_evt_action(emlxs_port_t *port, 787 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 788 static uint32_t emlxs_fcfi_pause_evt_action(emlxs_port_t *port, 789 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 790 static uint32_t emlxs_fcfi_reg_action(emlxs_port_t *port, 791 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 792 static uint32_t emlxs_fcfi_unreg_action(emlxs_port_t *port, 793 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 794 static uint32_t emlxs_fcfi_reg_cmpl_action(emlxs_port_t *port, 795 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 796 static uint32_t emlxs_fcfi_unreg_cmpl_action(emlxs_port_t *port, 797 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 798 static uint32_t emlxs_fcfi_vfi_online_action(emlxs_port_t *port, 799 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 800 static uint32_t emlxs_fcfi_vfi_online_cmpl_action(emlxs_port_t *port, 801 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 802 static uint32_t emlxs_fcfi_reg_failed_action(emlxs_port_t *port, 803 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 804 static uint32_t emlxs_fcfi_unreg_failed_action(emlxs_port_t *port, 805 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 806 static uint32_t emlxs_fcfi_vfi_offline_action(emlxs_port_t *port, 807 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 808 static uint32_t emlxs_fcfi_vfi_offline_cmpl_action(emlxs_port_t *port, 809 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 810 static uint32_t emlxs_fcfi_online_action(emlxs_port_t *port, 811 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 812 static uint32_t emlxs_fcfi_paused_action(emlxs_port_t *port, 813 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 814 static uint32_t emlxs_fcfi_offline_action(emlxs_port_t *port, 815 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 816 static uint32_t emlxs_fcfi_vfi_online_evt_action(emlxs_port_t *port, 817 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 818 static uint32_t emlxs_fcfi_vfi_offline_evt_action(emlxs_port_t *port, 819 FCFIobj_t *fcfp, uint32_t evt, void *arg1); 820 821 static uint32_t emlxs_fcfi_event(emlxs_port_t *port, 822 uint32_t evt, void *arg1); 823 static FCFIobj_t *emlxs_fcfi_find(emlxs_port_t *port, FCF_RECORD_t *fcfrec, 824 uint32_t *fcf_index); 825 static FCFIobj_t *emlxs_fcfi_alloc(emlxs_port_t *port); 826 static uint32_t emlxs_fcfi_free(emlxs_port_t *port, FCFIobj_t *fcfp); 827 static void emlxs_fcfi_update(emlxs_port_t *port, FCFIobj_t *fcfp, 828 FCF_RECORD_t *fcf_rec, uint32_t event_tag); 829 static char *emlxs_fcfi_state_xlate(uint32_t state); 830 831 /* 832 * - Online sequencing can start from FCFI_STATE_OFFLINE state or 833 * the FCFI_STATE_VFI_OFFLINE state. 834 * 835 * - Offline sequencing can interrupt the online sequencing at the 836 * entry of the next wait state. 837 * 838 * NORMAL ONLINE SEQ 839 * --------------------------- 840 * FCFI_ONLINE event <-- FCFTAB 841 * FCFI_STATE_OFFLINE 842 * FCFI_STATE_REG 843 * FCFI_STATE_REG_CMPL 844 * FCFI_STATE_VFI_ONLINE 845 * FCFI_STATE_VFI_ONLINE_CMPL 846 * FCFI_STATE_ONLINE 847 * FCFI_ONLINE event-->FCFTAB 848 * 849 * 850 * NORMAL OFFLINE SEQ 851 * --------------------------- 852 * FCFI_OFFLINE event <-- FCFTAB 853 * FCFI_STATE_ONLINE 854 * FCFI_STATE_VFI_OFFLINE 855 * FCFI_STATE_VFI_OFFLINE_CMPL 856 * FCFI_STATE_UNREG 857 * FCFI_STATE_UNREG_CMPL 858 * FCFI_STATE_OFFLINE 859 * FCFI_OFFLINE event-->FCFTAB 860 * 861 * 862 * NORMAL PAUSE SEQ 863 * --------------------------- 864 * FCFI_PAUSE event <-- FCFTAB 865 * FCFI_STATE_ONLINE 866 * FCFI_STATE_PAUSED 867 * 868 */ 869 /* Order does matter */ 870 static void *emlxs_fcfi_action_table[] = 871 { 872 /* Action routine Event */ 873 /* FCFI_STATE_FREE 0 (Wait for allocation) */ 874 (void *) emlxs_fcfi_free_action, /* STATE_ENTER */ 875 (void *) NULL, /* FCFI_ONLINE */ 876 (void *) NULL, /* FCFI_OFFLINE */ 877 (void *) NULL, /* FCFI_PAUSE */ 878 (void *) NULL, /* VFI_ONLINE */ 879 (void *) NULL, /* VFI_OFFLINE */ 880 881 /* FCFI_STATE_OFFLINE 1 (Wait for FCFI_ONLINE event) */ 882 (void *) emlxs_fcfi_offline_action, /* STATE_ENTER */ 883 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 884 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 885 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 886 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 887 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 888 889 /* FCFI_STATE_UNREG_CMPL 2 (Transitional) */ 890 (void *) emlxs_fcfi_unreg_cmpl_action, /* STATE_ENTER */ 891 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 892 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 893 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 894 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 895 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 896 897 /* FCFI_STATE_UNREG_FAILED 3 (Transitional) */ 898 (void *) emlxs_fcfi_unreg_failed_action, /* STATE_ENTER */ 899 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 900 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 901 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 902 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 903 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 904 905 /* FCFI_STATE_UNREG 4 (Wait for unreg_fcfi cmpl) */ 906 (void *) emlxs_fcfi_unreg_action, /* STATE_ENTER */ 907 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 908 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 909 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 910 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 911 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 912 913 /* FCFI_STATE_REG 5 (Wait for reg_fcfi cmpl) */ 914 (void *) emlxs_fcfi_reg_action, /* STATE_ENTER */ 915 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 916 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 917 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 918 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 919 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 920 921 /* FCFI_STATE_REG_FAILED 6 (Transitional) */ 922 (void *) emlxs_fcfi_reg_failed_action, /* STATE_ENTER */ 923 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 924 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 925 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 926 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 927 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 928 929 /* FCFI_STATE_REG_CMPL 7 (Transitional) */ 930 (void *) emlxs_fcfi_reg_cmpl_action, /* STATE_ENTER */ 931 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 932 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 933 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 934 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 935 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 936 937 /* FCFI_STATE_VFI_OFFLINE_CMPL 8 (Transitional) */ 938 (void *) emlxs_fcfi_vfi_offline_cmpl_action, /* STATE_ENTER */ 939 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 940 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 941 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 942 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 943 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 944 945 /* FCFI_STATE_VFI_OFFLINE 9 (Wait for VFI_OFFLINE event) */ 946 (void *) emlxs_fcfi_vfi_offline_action, /* STATE_ENTER */ 947 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 948 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 949 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 950 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 951 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE * */ 952 953 /* FCFI_STATE_VFI_ONLINE 10 (Wait for VFI_ONLINE event) */ 954 (void *) emlxs_fcfi_vfi_online_action, /* STATE_ENTER */ 955 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 956 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 957 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 958 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 959 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 960 961 /* FCFI_STATE_VFI_ONLINE_CMPL 11 (Transitional) */ 962 (void *) emlxs_fcfi_vfi_online_cmpl_action, /* STATE_ENTER */ 963 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 964 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 965 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 966 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 967 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 968 969 970 /* FCFI_STATE_PAUSED 12 (Wait for FCFI_ONLINE event) */ 971 (void *) emlxs_fcfi_paused_action, /* STATE_ENTER */ 972 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 973 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 974 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 975 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 976 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 977 978 /* FCFI_STATE_ONLINE 13 (Wait for FCFI_OFFLINE event) */ 979 (void *) emlxs_fcfi_online_action, /* STATE_ENTER */ 980 (void *) emlxs_fcfi_online_evt_action, /* FCFI_ONLINE */ 981 (void *) emlxs_fcfi_offline_evt_action, /* FCFI_OFFLINE */ 982 (void *) emlxs_fcfi_pause_evt_action, /* FCFI_PAUSE */ 983 (void *) emlxs_fcfi_vfi_online_evt_action, /* VFI_ONLINE */ 984 (void *) emlxs_fcfi_vfi_offline_evt_action, /* VFI_OFFLINE */ 985 986 }; /* emlxs_fcfi_action_table[] */ 987 #define FCFI_ACTION_EVENTS 6 988 #define FCFI_ACTION_STATES \ 989 (sizeof (emlxs_fcfi_action_table)/ \ 990 (FCFI_ACTION_EVENTS * sizeof (void *))) 991 992 993 /* ********************************************************************** */ 994 /* VFI */ 995 /* ********************************************************************** */ 996 997 /* Order does not matter */ 998 emlxs_table_t emlxs_vfi_state_table[] = 999 { 1000 {VFI_STATE_OFFLINE, "VFI_OFFLINE"}, 1001 1002 {VFI_STATE_INIT, "VFI_INIT"}, 1003 {VFI_STATE_INIT_FAILED, "VFI_INIT_FAILED"}, 1004 {VFI_STATE_INIT_CMPL, "VFI_INIT_CMPL"}, 1005 1006 {VFI_STATE_VPI_OFFLINE_CMPL, "VFI_VPI_OFFLINE_CMPL"}, 1007 {VFI_STATE_VPI_OFFLINE, "VFI_VPI_OFFLINE"}, 1008 1009 {VFI_STATE_VPI_ONLINE, "VFI_VPI_ONLINE"}, 1010 {VFI_STATE_VPI_ONLINE_CMPL, "VFI_VPI_ONLINE_CMPL"}, 1011 1012 {VFI_STATE_UNREG_CMPL, "VFI_UNREG_CMPL"}, 1013 {VFI_STATE_UNREG_FAILED, "VFI_UNREG_FAILED"}, 1014 {VFI_STATE_UNREG, "VFI_UNREG"}, 1015 1016 {VFI_STATE_REG, "VFI_REG"}, 1017 {VFI_STATE_REG_FAILED, "VFI_REG_FAILED"}, 1018 {VFI_STATE_REG_CMPL, "VFI_REG_CMPL"}, 1019 1020 {VFI_STATE_PAUSED, "VFI_PAUSED"}, 1021 {VFI_STATE_ONLINE, "VFI_ONLINE"}, 1022 1023 }; /* emlxs_vfi_state_table */ 1024 1025 1026 static uint32_t emlxs_vfi_pause_evt_action(emlxs_port_t *port, 1027 VFIobj_t *vfip, uint32_t evt, void *arg1); 1028 static uint32_t emlxs_vfi_online_evt_action(emlxs_port_t *port, 1029 VFIobj_t *vfip, uint32_t evt, void *arg1); 1030 static uint32_t emlxs_vfi_offline_evt_action(emlxs_port_t *port, 1031 VFIobj_t *vfip, uint32_t evt, void *arg1); 1032 static uint32_t emlxs_vfi_init_action(emlxs_port_t *port, 1033 VFIobj_t *vfip, uint32_t evt, void *arg1); 1034 static uint32_t emlxs_vfi_init_failed_action(emlxs_port_t *port, 1035 VFIobj_t *vfip, uint32_t evt, void *arg1); 1036 static uint32_t emlxs_vfi_init_cmpl_action(emlxs_port_t *port, 1037 VFIobj_t *vfip, uint32_t evt, void *arg1); 1038 static uint32_t emlxs_vfi_offline_action(emlxs_port_t *port, 1039 VFIobj_t *vfip, uint32_t evt, void *arg1); 1040 static uint32_t emlxs_vfi_online_action(emlxs_port_t *port, 1041 VFIobj_t *vfip, uint32_t evt, void *arg1); 1042 static uint32_t emlxs_vfi_paused_action(emlxs_port_t *port, 1043 VFIobj_t *vfip, uint32_t evt, void *arg1); 1044 static uint32_t emlxs_vfi_vpi_online_action(emlxs_port_t *port, 1045 VFIobj_t *vfip, uint32_t evt, void *arg1); 1046 static uint32_t emlxs_vfi_vpi_online_cmpl_action(emlxs_port_t *port, 1047 VFIobj_t *vfip, uint32_t evt, void *arg1); 1048 static uint32_t emlxs_vfi_vpi_offline_action(emlxs_port_t *port, 1049 VFIobj_t *vfip, uint32_t evt, void *arg1); 1050 static uint32_t emlxs_vfi_vpi_offline_cmpl_action(emlxs_port_t *port, 1051 VFIobj_t *vfip, uint32_t evt, void *arg1); 1052 static uint32_t emlxs_vfi_reg_action(emlxs_port_t *port, 1053 VFIobj_t *vfip, uint32_t evt, void *arg1); 1054 static uint32_t emlxs_vfi_reg_failed_action(emlxs_port_t *port, 1055 VFIobj_t *vfip, uint32_t evt, void *arg1); 1056 static uint32_t emlxs_vfi_reg_cmpl_action(emlxs_port_t *port, 1057 VFIobj_t *vfip, uint32_t evt, void *arg1); 1058 static uint32_t emlxs_vfi_unreg_action(emlxs_port_t *port, 1059 VFIobj_t *vfip, uint32_t evt, void *arg1); 1060 static uint32_t emlxs_vfi_unreg_failed_action(emlxs_port_t *port, 1061 VFIobj_t *vfip, uint32_t evt, void *arg1); 1062 static uint32_t emlxs_vfi_unreg_cmpl_action(emlxs_port_t *port, 1063 VFIobj_t *vfip, uint32_t evt, void *arg1); 1064 static uint32_t emlxs_vfi_vpi_online_evt_action(emlxs_port_t *port, 1065 VFIobj_t *vfip, uint32_t evt, void *arg1); 1066 static uint32_t emlxs_vfi_vpi_offline_evt_action(emlxs_port_t *port, 1067 VFIobj_t *vfip, uint32_t evt, void *arg1); 1068 1069 static uint32_t emlxs_vfi_event(emlxs_port_t *port, 1070 uint32_t evt, void *arg1); 1071 1072 1073 /* 1074 * - Online sequencing can start from VFI_STATE_OFFLINE state or 1075 * the VFI_STATE_VPI_OFFLINE state. 1076 * 1077 * - Offline sequencing can interrupt the online sequencing at the 1078 * entry of the next wait state. 1079 * 1080 * NORMAL ONLINE SEQ 1081 * --------------------------- 1082 * VFI_ONLINE event <-- FCFI 1083 * VFI_STATE_OFFLINE 1084 * VFI_STATE_INIT 1085 * VFI_STATE_INIT_CMPL 1086 * VFI_STATE_VPI_ONLINE 1087 * VFI_STATE_VPI_ONLINE_CMPL 1088 * VFI_STATE_REG 1089 * VFI_STATE_REG_CMPL 1090 * VFI_STATE_ONLINE 1091 * VFI_ONLINE event-->FCFI 1092 * 1093 * 1094 * NORMAL OFFLINE SEQ 1095 * --------------------------- 1096 * VFI_OFFLINE event <-- FCFI 1097 * VFI_STATE_ONLINE 1098 * VFI_STATE_VPI_OFFLINE 1099 * VFI_STATE_VPI_OFFLINE_CMPL 1100 * VFI_STATE_UNREG 1101 * VFI_STATE_UNREG_CMPL 1102 * VFI_STATE_OFFLINE 1103 * VFI_OFFLINE event-->FCFI 1104 * 1105 * 1106 * NORMAL PAUSE SEQ 1107 * --------------------------- 1108 * VFI_PAUSE event <-- FCFI 1109 * VFI_STATE_ONLINE 1110 * VFI_STATE_PAUSED 1111 * 1112 */ 1113 /* Order does matter */ 1114 static void *emlxs_vfi_action_table[] = 1115 { 1116 /* Action routine Event */ 1117 /* VFI_STATE_OFFLINE 0 (Wait for VFI_ONLINE event) */ 1118 (void *) emlxs_vfi_offline_action, /* STATE_ENTER */ 1119 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1120 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1121 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1122 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1123 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1124 1125 1126 /* VFI_STATE_INIT 1 (Wait for init_vfi cmpl) */ 1127 (void *) emlxs_vfi_init_action, /* STATE_ENTER */ 1128 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1129 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1130 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1131 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1132 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1133 1134 /* VFI_STATE_INIT_FAILED 2 (Transitional) */ 1135 (void *) emlxs_vfi_init_failed_action, /* STATE_ENTER */ 1136 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1137 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1138 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1139 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1140 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1141 1142 /* VFI_STATE_INIT_CMPL 3 (Transitional) */ 1143 (void *) emlxs_vfi_init_cmpl_action, /* STATE_ENTER */ 1144 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1145 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1146 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1147 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1148 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1149 1150 1151 /* VFI_STATE_VPI_OFFLINE_CMPL 4 (Wait for VPI_OFFLINE event) */ 1152 (void *) emlxs_vfi_vpi_offline_cmpl_action, /* STATE_ENTER */ 1153 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1154 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1155 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1156 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1157 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1158 1159 /* VFI_STATE_VPI_OFFLINE 5 (Wait for VPI_OFFLINE event) */ 1160 (void *) emlxs_vfi_vpi_offline_action, /* STATE_ENTER */ 1161 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1162 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1163 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1164 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1165 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1166 1167 1168 /* VFI_STATE_VPI_ONLINE 6 (Wait for VPI_ONLINE event) */ 1169 (void *) emlxs_vfi_vpi_online_action, /* STATE_ENTER */ 1170 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1171 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1172 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1173 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1174 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1175 1176 /* VFI_STATE_VPI_ONLINE_CMPL 7 (Transitional) */ 1177 (void *) emlxs_vfi_vpi_online_cmpl_action, /* STATE_ENTER */ 1178 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1179 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1180 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1181 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1182 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1183 1184 1185 /* VFI_STATE_UNREG_CMPL 8 (Transitional) */ 1186 (void *) emlxs_vfi_unreg_cmpl_action, /* STATE_ENTER */ 1187 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1188 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1189 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1190 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1191 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1192 1193 /* VFI_STATE_UNREG_FAILED 9 (Transitional) */ 1194 (void *) emlxs_vfi_unreg_failed_action, /* STATE_ENTER */ 1195 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1196 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1197 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1198 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1199 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1200 1201 /* VFI_STATE_UNREG 10 (Wait for unreg_vfi cmpl) */ 1202 (void *) emlxs_vfi_unreg_action, /* STATE_ENTER */ 1203 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1204 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1205 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1206 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1207 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1208 1209 1210 /* VFI_STATE_REG 11 (Wait for reg_vfi cmpl) */ 1211 (void *) emlxs_vfi_reg_action, /* STATE_ENTER */ 1212 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1213 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1214 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1215 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1216 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1217 1218 /* VFI_STATE_REG_FAILED 12 (Transitional) */ 1219 (void *) emlxs_vfi_reg_failed_action, /* STATE_ENTER */ 1220 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1221 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1222 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1223 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1224 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1225 1226 /* VFI_STATE_REG_CMPL 13 (Transitional) */ 1227 (void *) emlxs_vfi_reg_cmpl_action, /* STATE_ENTER */ 1228 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1229 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1230 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1231 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1232 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1233 1234 1235 /* VFI_STATE_PAUSED 14 (Wait for VFI_OFFLINE event) */ 1236 (void *) emlxs_vfi_paused_action, /* STATE_ENTER */ 1237 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1238 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1239 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1240 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1241 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1242 1243 /* VFI_STATE_ONLINE 14 (Wait for VFI_OFFLINE event) */ 1244 (void *) emlxs_vfi_online_action, /* STATE_ENTER */ 1245 (void *) emlxs_vfi_online_evt_action, /* VFI_ONLINE */ 1246 (void *) emlxs_vfi_offline_evt_action, /* VFI_OFFLINE */ 1247 (void *) emlxs_vfi_pause_evt_action, /* VFI_PAUSE */ 1248 (void *) emlxs_vfi_vpi_online_evt_action, /* VPI_ONLINE */ 1249 (void *) emlxs_vfi_vpi_offline_evt_action, /* VPI_OFFLINE */ 1250 1251 }; /* emlxs_vfi_action_table[] */ 1252 #define VFI_ACTION_EVENTS 6 1253 #define VFI_ACTION_STATES \ 1254 (sizeof (emlxs_vfi_action_table)/ \ 1255 (VFI_ACTION_EVENTS * sizeof (void *))) 1256 1257 1258 /* ********************************************************************** */ 1259 /* VPI */ 1260 /* ********************************************************************** */ 1261 1262 /* Order does not matter */ 1263 emlxs_table_t emlxs_vpi_state_table[] = 1264 { 1265 {VPI_STATE_OFFLINE, "VPI_OFFLINE"}, 1266 1267 {VPI_STATE_INIT, "VPI_INIT"}, 1268 {VPI_STATE_INIT_FAILED, "VPI_INIT_FAILED"}, 1269 {VPI_STATE_INIT_CMPL, "VPI_INIT_CMPL"}, 1270 1271 {VPI_STATE_UNREG_CMPL, "VPI_UNREG_CMPL"}, 1272 {VPI_STATE_UNREG_FAILED, "VPI_UNREG_FAILED"}, 1273 {VPI_STATE_UNREG, "VPI_UNREG"}, 1274 1275 {VPI_STATE_LOGO_CMPL, "VPI_LOGO_CMPL"}, 1276 {VPI_STATE_LOGO_FAILED, "VPI_LOGO_FAILED"}, 1277 {VPI_STATE_LOGO, "VPI_LOGO"}, 1278 1279 {VPI_STATE_PORT_OFFLINE, "VPI_PORT_OFFLINE"}, 1280 {VPI_STATE_PORT_ONLINE, "VPI_PORT_ONLINE"}, 1281 1282 {VPI_STATE_LOGI, "VPI_LOGI"}, 1283 {VPI_STATE_LOGI_FAILED, "VPI_LOGI_FAILED"}, 1284 {VPI_STATE_LOGI_CMPL, "VPI_LOGI_CMPL"}, 1285 1286 {VPI_STATE_REG, "VPI_REG"}, 1287 {VPI_STATE_REG_FAILED, "VPI_REG_FAILED"}, 1288 {VPI_STATE_REG_CMPL, "VPI_REG_CMPL"}, 1289 1290 {VPI_STATE_PAUSED, "VPI_PAUSED"}, 1291 {VPI_STATE_ONLINE, "VPI_ONLINE"}, 1292 1293 }; /* emlxs_vpi_state_table */ 1294 1295 1296 static uint32_t emlxs_vpi_online_evt_action(emlxs_port_t *port, 1297 VPIobj_t *vpip, uint32_t evt, void *arg1); 1298 static uint32_t emlxs_vpi_offline_evt_action(emlxs_port_t *port, 1299 VPIobj_t *vpip, uint32_t evt, void *arg1); 1300 static uint32_t emlxs_vpi_pause_evt_action(emlxs_port_t *port, 1301 VPIobj_t *vpip, uint32_t evt, void *arg1); 1302 static uint32_t emlxs_vpi_rpi_online_evt_action(emlxs_port_t *port, 1303 VPIobj_t *vpip, uint32_t evt, void *arg1); 1304 static uint32_t emlxs_vpi_rpi_offline_evt_action(emlxs_port_t *port, 1305 VPIobj_t *vpip, uint32_t evt, void *arg1); 1306 static uint32_t emlxs_vpi_rpi_pause_evt_action(emlxs_port_t *port, 1307 VPIobj_t *vpip, uint32_t evt, void *arg1); 1308 1309 static uint32_t emlxs_vpi_init_action(emlxs_port_t *port, 1310 VPIobj_t *vpip, uint32_t evt, void *arg1); 1311 static uint32_t emlxs_vpi_init_failed_action(emlxs_port_t *port, 1312 VPIobj_t *vpip, uint32_t evt, void *arg1); 1313 static uint32_t emlxs_vpi_init_cmpl_action(emlxs_port_t *port, 1314 VPIobj_t *vpip, uint32_t evt, void *arg1); 1315 1316 static uint32_t emlxs_vpi_offline_action(emlxs_port_t *port, 1317 VPIobj_t *vpip, uint32_t evt, void *arg1); 1318 static uint32_t emlxs_vpi_online_action(emlxs_port_t *port, 1319 VPIobj_t *vpip, uint32_t evt, void *arg1); 1320 static uint32_t emlxs_vpi_paused_action(emlxs_port_t *port, 1321 VPIobj_t *vpip, uint32_t evt, void *arg1); 1322 1323 static uint32_t emlxs_vpi_port_online_action(emlxs_port_t *port, 1324 VPIobj_t *vpip, uint32_t evt, void *arg1); 1325 static uint32_t emlxs_vpi_port_offline_action(emlxs_port_t *port, 1326 VPIobj_t *vpip, uint32_t evt, void *arg1); 1327 1328 static uint32_t emlxs_vpi_logi_cmpl_action(emlxs_port_t *port, 1329 VPIobj_t *vpip, uint32_t evt, void *arg1); 1330 static uint32_t emlxs_vpi_logi_failed_action(emlxs_port_t *port, 1331 VPIobj_t *vpip, uint32_t evt, void *arg1); 1332 static uint32_t emlxs_vpi_logi_action(emlxs_port_t *port, 1333 VPIobj_t *vpip, uint32_t evt, void *arg1); 1334 1335 static uint32_t emlxs_vpi_reg_action(emlxs_port_t *port, 1336 VPIobj_t *vpip, uint32_t evt, void *arg1); 1337 static uint32_t emlxs_vpi_reg_failed_action(emlxs_port_t *port, 1338 VPIobj_t *vpip, uint32_t evt, void *arg1); 1339 static uint32_t emlxs_vpi_reg_cmpl_action(emlxs_port_t *port, 1340 VPIobj_t *vpip, uint32_t evt, void *arg1); 1341 1342 static uint32_t emlxs_vpi_unreg_action(emlxs_port_t *port, 1343 VPIobj_t *vpip, uint32_t evt, void *arg1); 1344 static uint32_t emlxs_vpi_unreg_failed_action(emlxs_port_t *port, 1345 VPIobj_t *vpip, uint32_t evt, void *arg1); 1346 static uint32_t emlxs_vpi_unreg_cmpl_action(emlxs_port_t *port, 1347 VPIobj_t *vpip, uint32_t evt, void *arg1); 1348 1349 static uint32_t emlxs_vpi_logo_action(emlxs_port_t *port, 1350 VPIobj_t *vpip, uint32_t evt, void *arg1); 1351 static uint32_t emlxs_vpi_logo_failed_action(emlxs_port_t *port, 1352 VPIobj_t *vpip, uint32_t evt, void *arg1); 1353 static uint32_t emlxs_vpi_logo_cmpl_action(emlxs_port_t *port, 1354 VPIobj_t *vpip, uint32_t evt, void *arg1); 1355 1356 static uint32_t emlxs_vpi_event(emlxs_port_t *port, 1357 uint32_t evt, void *arg1); 1358 static uint32_t emlxs_vpi_logi_cmpl_notify(emlxs_port_t *port, 1359 RPIobj_t *rpip); 1360 static void emlxs_vpi_logo_handler(emlxs_port_t *port, 1361 VPIobj_t *vpip); 1362 1363 /* 1364 * - Online sequencing can only start from VPI_STATE_OFFLINE or 1365 * VPI_STATE_PORT_OFFLINE state. 1366 * 1367 * - Offline sequencing can interrupt the online sequencing at the 1368 * entry of the next wait state. 1369 * 1370 * NORMAL ONLINE SEQ 1371 * --------------------------- 1372 * VPI_ONLINE event <-- VFI 1373 * VPI_STATE_OFFLINE 1374 * VPI_STATE_INIT 1375 * VPI_STATE_INIT_CMPL 1376 * VPI_STATE_PORT_ONLINE 1377 * VPI_STATE_LOGI 1378 * VPI_STATE_LOGI_CMPL 1379 * VPI_STATE_REG 1380 * VPI_STATE_REG_CMPL 1381 * VPI_STATE_ONLINE 1382 * VPI_ONLINE event-->VFI 1383 * 1384 * 1385 * NORMAL OFFLINE SEQ 1386 * --------------------------- 1387 * VPI_OFFLINE event <-- VFI 1388 * VPI_STATE_ONLINE 1389 * VPI_STATE_PORT_OFFLINE 1390 * VPI_STATE_LOGO 1391 * VPI_STATE_LOGO_CMPL 1392 * VPI_STATE_UNREG 1393 * VPI_STATE_UNREG_CMPL 1394 * VPI_STATE_OFFLINE 1395 * VPI_OFFLINE event-->VFI 1396 * 1397 * 1398 * NORMAL PAUSE SEQ 1399 * --------------------------- 1400 * VPI_PAUSE event <-- VFI 1401 * VPI_STATE_ONLINE 1402 * VPI_STATE_PORT_OFFLINE 1403 * VPI_STATE_PAUSED 1404 * 1405 */ 1406 /* Order does matter */ 1407 static void *emlxs_vpi_action_table[] = 1408 { 1409 /* Action routine Event */ 1410 /* VPI_STATE_OFFLINE 0 (Wait for VPI_ONLINE event) */ 1411 (void *) emlxs_vpi_offline_action, /* STATE_ENTER */ 1412 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1413 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1414 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1415 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1416 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1417 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1418 1419 1420 /* VPI_STATE_INIT 1 (Wait for init_vpi cmpl) */ 1421 (void *) emlxs_vpi_init_action, /* STATE_ENTER */ 1422 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1423 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1424 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1425 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1426 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1427 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1428 1429 /* VPI_STATE_INIT_FAILED 2 (Transitional) */ 1430 (void *) emlxs_vpi_init_failed_action, /* STATE_ENTER */ 1431 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1432 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1433 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1434 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1435 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1436 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1437 1438 /* VPI_STATE_INIT_CMPL 3 (Transitional) */ 1439 (void *) emlxs_vpi_init_cmpl_action, /* STATE_ENTER */ 1440 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1441 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1442 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1443 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1444 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1445 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1446 1447 1448 /* VPI_STATE_UNREG_CMPL 4 (Transitional) */ 1449 (void *) emlxs_vpi_unreg_cmpl_action, /* STATE_ENTER */ 1450 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1451 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1452 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1453 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1454 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1455 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1456 1457 /* VPI_STATE_UNREG_FAILED 5 (Transitional) */ 1458 (void *) emlxs_vpi_unreg_failed_action, /* STATE_ENTER */ 1459 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1460 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1461 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1462 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1463 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1464 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1465 1466 /* VPI_STATE_UNREG 6 (Wait for unreg_vpi cmpl) */ 1467 (void *) emlxs_vpi_unreg_action, /* STATE_ENTER */ 1468 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1469 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1470 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1471 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1472 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1473 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1474 1475 1476 /* VPI_STATE_LOGO_CMPL 7 (Transitional) */ 1477 (void *) emlxs_vpi_logo_cmpl_action, /* STATE_ENTER */ 1478 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1479 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1480 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1481 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1482 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1483 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1484 1485 /* VPI_STATE_LOGO_FAILED 8 (Transitional) */ 1486 (void *) emlxs_vpi_logo_failed_action, /* STATE_ENTER */ 1487 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1488 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1489 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1490 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1491 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1492 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1493 1494 /* VPI_STATE_LOGO 9 (Transitional) */ 1495 (void *) emlxs_vpi_logo_action, /* STATE_ENTER */ 1496 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1497 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1498 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1499 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1500 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1501 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1502 1503 1504 /* VPI_STATE_PORT_OFFLINE 10 (Wait for RPI_OFFLINE or VPI_ONLINE) */ 1505 (void *) emlxs_vpi_port_offline_action, /* STATE_ENTER */ 1506 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1507 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1508 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1509 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1510 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1511 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1512 1513 /* VPI_STATE_PORT_ONLINE 11 (Wait for emlxs_vpi_logi_notify() ) */ 1514 (void *) emlxs_vpi_port_online_action, /* STATE_ENTER */ 1515 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1516 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1517 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1518 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1519 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1520 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1521 1522 1523 /* VPI_STATE_LOGI 12 (Wait for emlxs_vpi_logi_cmpl_notify() ) */ 1524 (void *) emlxs_vpi_logi_action, /* STATE_ENTER */ 1525 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1526 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1527 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1528 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1529 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1530 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1531 1532 /* VPI_STATE_LOGI_FAILED 13 (Transitional) */ 1533 (void *) emlxs_vpi_logi_failed_action, /* STATE_ENTER */ 1534 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1535 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1536 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1537 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1538 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1539 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1540 1541 /* VPI_STATE_LOGI_CMPL 14 (Transitional) */ 1542 (void *) emlxs_vpi_logi_cmpl_action, /* STATE_ENTER */ 1543 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1544 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1545 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1546 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1547 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1548 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1549 1550 1551 /* VPI_STATE_REG 15 (Wait for reg_vpi cmpl) */ 1552 (void *) emlxs_vpi_reg_action, /* STATE_ENTER */ 1553 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1554 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1555 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1556 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1557 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1558 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1559 1560 /* VPI_STATE_REG_FAILED 16 (Transitional) */ 1561 (void *) emlxs_vpi_reg_failed_action, /* STATE_ENTER */ 1562 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1563 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1564 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1565 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1566 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1567 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1568 1569 /* VPI_STATE_REG_CMPL 17 (Transitional) */ 1570 (void *) emlxs_vpi_reg_cmpl_action, /* STATE_ENTER */ 1571 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1572 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1573 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1574 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1575 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1576 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1577 1578 1579 /* VPI_STATE_PAUSED 18 (Wait for VPI_ONLINE() ) */ 1580 (void *) emlxs_vpi_paused_action, /* STATE_ENTER */ 1581 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1582 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1583 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1584 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1585 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1586 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1587 1588 /* VPI_STATE_ONLINE 19 (Wait for VPI_OFFLINE event) */ 1589 (void *) emlxs_vpi_online_action, /* STATE_ENTER */ 1590 (void *) emlxs_vpi_online_evt_action, /* VPI_ONLINE */ 1591 (void *) emlxs_vpi_offline_evt_action, /* VPI_OFFLINE */ 1592 (void *) emlxs_vpi_pause_evt_action, /* VPI_PAUSE */ 1593 (void *) emlxs_vpi_rpi_online_evt_action, /* RPI_ONLINE */ 1594 (void *) emlxs_vpi_rpi_offline_evt_action, /* RPI_OFFLINE */ 1595 (void *) emlxs_vpi_rpi_pause_evt_action, /* RPI_PAUSE */ 1596 1597 }; /* emlxs_vpi_action_table() */ 1598 #define VPI_ACTION_EVENTS 7 1599 #define VPI_ACTION_STATES \ 1600 (sizeof (emlxs_vpi_action_table)/ \ 1601 (VPI_ACTION_EVENTS * sizeof (void *))) 1602 1603 1604 /* ********************************************************************** */ 1605 /* RPI */ 1606 /* ********************************************************************** */ 1607 1608 /* Order does not matter */ 1609 emlxs_table_t emlxs_rpi_state_table[] = 1610 { 1611 {RPI_STATE_FREE, "RPI_FREE"}, 1612 1613 {RPI_STATE_RESERVED, "RPI_RESERVED"}, 1614 {RPI_STATE_OFFLINE, "RPI_OFFLINE"}, 1615 1616 {RPI_STATE_UNREG_CMPL, "RPI_UNREG_CMPL"}, 1617 {RPI_STATE_UNREG_FAILED, "RPI_UNREG_FAILED"}, 1618 {RPI_STATE_UNREG, "RPI_UNREG"}, 1619 1620 {RPI_STATE_REG, "RPI_REG"}, 1621 {RPI_STATE_REG_FAILED, "RPI_REG_FAILED"}, 1622 {RPI_STATE_REG_CMPL, "RPI_REG_CMPL"}, 1623 1624 {RPI_STATE_PAUSED, "RPI_PAUSED"}, 1625 1626 {RPI_STATE_RESUME, "RPI_RESUME"}, 1627 {RPI_STATE_RESUME_FAILED, "RPI_RESUME_FAILED"}, 1628 {RPI_STATE_RESUME_CMPL, "RPI_RESUME_CMPL"}, 1629 1630 {RPI_STATE_ONLINE, "RPI_ONLINE"}, 1631 1632 }; /* emlxs_rpi_state_table */ 1633 1634 static uint32_t emlxs_rpi_free_action(emlxs_port_t *port, 1635 RPIobj_t *rpip, uint32_t evt, void *arg1); 1636 1637 static uint32_t emlxs_rpi_online_evt_action(emlxs_port_t *port, 1638 RPIobj_t *rpip, uint32_t evt, void *arg1); 1639 static uint32_t emlxs_rpi_offline_evt_action(emlxs_port_t *port, 1640 RPIobj_t *rpip, uint32_t evt, void *arg1); 1641 static uint32_t emlxs_rpi_pause_evt_action(emlxs_port_t *port, 1642 RPIobj_t *rpip, uint32_t evt, void *arg1); 1643 static uint32_t emlxs_rpi_resume_evt_action(emlxs_port_t *port, 1644 RPIobj_t *rpip, uint32_t evt, void *arg1); 1645 1646 static uint32_t emlxs_rpi_reg_action(emlxs_port_t *port, 1647 RPIobj_t *rpip, uint32_t evt, void *arg1); 1648 static uint32_t emlxs_rpi_reg_cmpl_action(emlxs_port_t *port, 1649 RPIobj_t *rpip, uint32_t evt, void *arg1); 1650 static uint32_t emlxs_rpi_reg_failed_action(emlxs_port_t *port, 1651 RPIobj_t *rpip, uint32_t evt, void *arg1); 1652 1653 static uint32_t emlxs_rpi_unreg_action(emlxs_port_t *port, 1654 RPIobj_t *rpip, uint32_t evt, void *arg1); 1655 static uint32_t emlxs_rpi_unreg_cmpl_action(emlxs_port_t *port, 1656 RPIobj_t *rpip, uint32_t evt, void *arg1); 1657 static uint32_t emlxs_rpi_unreg_failed_action(emlxs_port_t *port, 1658 RPIobj_t *rpip, uint32_t evt, void *arg1); 1659 1660 static uint32_t emlxs_rpi_online_action(emlxs_port_t *port, 1661 RPIobj_t *rpip, uint32_t evt, void *arg1); 1662 static uint32_t emlxs_rpi_paused_action(emlxs_port_t *port, 1663 RPIobj_t *rpip, uint32_t evt, void *arg1); 1664 static uint32_t emlxs_rpi_offline_action(emlxs_port_t *port, 1665 RPIobj_t *rpip, uint32_t evt, void *arg1); 1666 static uint32_t emlxs_rpi_reserved_action(emlxs_port_t *port, 1667 RPIobj_t *rpip, uint32_t evt, void *arg1); 1668 1669 static uint32_t emlxs_rpi_resume_failed_action(emlxs_port_t *port, 1670 RPIobj_t *rpip, uint32_t evt, void *arg1); 1671 static uint32_t emlxs_rpi_resume_cmpl_action(emlxs_port_t *port, 1672 RPIobj_t *rpip, uint32_t evt, void *arg1); 1673 static uint32_t emlxs_rpi_resume_action(emlxs_port_t *port, 1674 RPIobj_t *rpip, uint32_t evt, void *arg1); 1675 1676 static uint32_t emlxs_rpi_event(emlxs_port_t *port, 1677 uint32_t evt, void *arg1); 1678 static RPIobj_t *emlxs_rpi_alloc(emlxs_port_t *port, uint32_t did); 1679 static uint32_t emlxs_rpi_free(emlxs_port_t *port, RPIobj_t *rpip); 1680 static RPIobj_t *emlxs_rpi_find_did(emlxs_port_t *port, uint32_t did); 1681 1682 static void emlxs_rpi_resume_handler(emlxs_port_t *port, 1683 RPIobj_t *rpip); 1684 static void emlxs_rpi_unreg_handler(emlxs_port_t *port, 1685 RPIobj_t *rpip); 1686 static uint32_t emlxs_rpi_reg_handler(emlxs_port_t *port, 1687 RPIobj_t *rpip); 1688 1689 static void emlxs_rpi_idle_timer(emlxs_hba_t *hba); 1690 1691 static uint32_t emlxs_rpi_state(emlxs_port_t *port, RPIobj_t *rpip, 1692 uint16_t state, uint16_t reason, uint32_t explain, 1693 void *arg1); 1694 1695 static void emlxs_rpi_alloc_fabric_rpi(emlxs_port_t *port); 1696 1697 static void emlxs_rpi_deferred_cmpl(emlxs_port_t *port, RPIobj_t *rpip, 1698 uint32_t status); 1699 1700 /* 1701 * - Online sequencing can start from RPI_STATE_RESERVED state or 1702 * the RPI_STATE_PAUSED state. 1703 * 1704 * - Offline sequencing can interrupt the online sequencing at the 1705 * entry of the next wait state. 1706 * 1707 * NORMAL ONLINE SEQ 1708 * --------------------------- 1709 * RPI_ONLINE event <-- VPI 1710 * RPI_STATE_RESERVED 1711 * RPI_STATE_REG 1712 * RPI_STATE_REG_CMPL 1713 * RPI_STATE_ONLINE 1714 * RPI_ONLINE event-->VPI 1715 * 1716 * 1717 * NORMAL OFFLINE SEQ 1718 * --------------------------- 1719 * RPI_OFFLINE event <-- VPI 1720 * RPI_STATE_ONLINE 1721 * RPI_STATE_UNREG 1722 * RPI_STATE_UNREG_CMPL 1723 * RPI_STATE_OFFLINE 1724 * RPI_OFFLINE event-->VPI 1725 * 1726 * 1727 * NORMAL PAUSE SEQ 1728 * --------------------------- 1729 * RPI_PAUSE event <-- VPI 1730 * RPI_STATE_ONLINE 1731 * RPI_STATE_PAUSED 1732 * 1733 */ 1734 /* Order does matter */ 1735 static void *emlxs_rpi_action_table[] = 1736 { 1737 /* Action routine Event */ 1738 /* RPI_STATE_FREE 0 (Wait for allocation) */ 1739 (void *) emlxs_rpi_free_action, /* STATE_ENTER */ 1740 (void *) NULL, /* RPI_ONLINE */ 1741 (void *) NULL, /* RPI_OFFLINE */ 1742 (void *) NULL, /* RPI_PAUSE */ 1743 (void *) NULL, /* RPI_RESUME */ 1744 1745 /* RPI_STATE_RESERVED 1 (Wait for RPI_ONLINE event) */ 1746 (void *) emlxs_rpi_reserved_action, /* STATE_ENTER */ 1747 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1748 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1749 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1750 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1751 1752 /* RPI_STATE_OFFLINE 2 (Transitional) */ 1753 (void *) emlxs_rpi_offline_action, /* STATE_ENTER */ 1754 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1755 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1756 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1757 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1758 1759 /* RPI_STATE_UNREG_CMPL 3 (Transitional) */ 1760 (void *) emlxs_rpi_unreg_cmpl_action, /* STATE_ENTER */ 1761 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1762 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1763 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1764 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1765 1766 /* RPI_STATE_UNREG_FAILED 4 (Transitional) */ 1767 (void *) emlxs_rpi_unreg_failed_action, /* STATE_ENTER */ 1768 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1769 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1770 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1771 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1772 1773 /* RPI_STATE_UNREG 5 (Wait for unreg_rpi cmpl) */ 1774 (void *) emlxs_rpi_unreg_action, /* STATE_ENTER */ 1775 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1776 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1777 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1778 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1779 1780 1781 /* RPI_STATE_REG 6 (Wait for reg_rpi cmpl) */ 1782 (void *) emlxs_rpi_reg_action, /* STATE_ENTER */ 1783 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1784 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1785 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1786 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1787 1788 /* RPI_STATE_REG_FAILED 7 (Transitional) */ 1789 (void *) emlxs_rpi_reg_failed_action, /* STATE_ENTER */ 1790 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1791 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1792 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1793 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1794 1795 /* RPI_STATE_REG_CMPL 8 (Transitional) */ 1796 (void *) emlxs_rpi_reg_cmpl_action, /* STATE_ENTER */ 1797 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1798 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1799 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1800 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1801 1802 1803 /* RPI_STATE_PAUSED 9 (Wait for RPI_ONLINE) */ 1804 (void *) emlxs_rpi_paused_action, /* STATE_ENTER */ 1805 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1806 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1807 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1808 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1809 1810 1811 /* RPI_STATE_RESUME 10 (Wait for resume_rpi mbcmpl) */ 1812 (void *) emlxs_rpi_resume_action, /* STATE_ENTER */ 1813 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1814 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1815 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1816 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1817 1818 /* RPI_STATE_RESUME_FAILED 11 (Transitional) */ 1819 (void *) emlxs_rpi_resume_failed_action, /* STATE_ENTER */ 1820 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1821 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1822 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1823 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1824 1825 /* RPI_STATE_RESUME_CMPL 12 (Transitional) */ 1826 (void *) emlxs_rpi_resume_cmpl_action, /* STATE_ENTER */ 1827 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1828 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1829 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1830 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1831 1832 1833 /* RPI_STATE_ONLINE 13 (Wait for RPI_OFFLINE event) */ 1834 (void *) emlxs_rpi_online_action, /* STATE_ENTER */ 1835 (void *) emlxs_rpi_online_evt_action, /* RPI_ONLINE */ 1836 (void *) emlxs_rpi_offline_evt_action, /* RPI_OFFLINE */ 1837 (void *) emlxs_rpi_pause_evt_action, /* RPI_PAUSE */ 1838 (void *) emlxs_rpi_resume_evt_action, /* RPI_RESUME */ 1839 1840 }; /* emlxs_rpi_action_table[] */ 1841 #define RPI_ACTION_EVENTS 5 1842 #define RPI_ACTION_STATES \ 1843 (sizeof (emlxs_rpi_action_table)/ \ 1844 (RPI_ACTION_EVENTS * sizeof (void *))) 1845 1846 1847 /* ************************************************************************** */ 1848 /* FCF Generic */ 1849 /* ************************************************************************** */ 1850 static void 1851 emlxs_fcf_linkdown(emlxs_port_t *port) 1852 { 1853 emlxs_hba_t *hba = HBA; 1854 1855 if (hba->state <= FC_LINK_DOWN) { 1856 return; 1857 } 1858 1859 mutex_enter(&EMLXS_PORT_LOCK); 1860 1861 if (hba->state <= FC_LINK_DOWN) { 1862 mutex_exit(&EMLXS_PORT_LOCK); 1863 return; 1864 } 1865 1866 HBASTATS.LinkDown++; 1867 EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_DOWN); 1868 1869 hba->flag &= FC_LINKDOWN_MASK; 1870 hba->discovery_timer = 0; 1871 hba->linkup_timer = 0; 1872 1873 mutex_exit(&EMLXS_PORT_LOCK); 1874 1875 emlxs_log_link_event(port); 1876 1877 return; 1878 1879 } /* emlxs_fcf_linkdown() */ 1880 1881 1882 static void 1883 emlxs_fcf_linkup(emlxs_port_t *port) 1884 { 1885 emlxs_hba_t *hba = HBA; 1886 emlxs_config_t *cfg = &CFG; 1887 1888 if (hba->state >= FC_LINK_UP) { 1889 return; 1890 } 1891 1892 mutex_enter(&EMLXS_PORT_LOCK); 1893 1894 if (hba->state >= FC_LINK_UP) { 1895 mutex_exit(&EMLXS_PORT_LOCK); 1896 return; 1897 } 1898 1899 /* Check for any mode changes */ 1900 emlxs_mode_set(hba); 1901 1902 HBASTATS.LinkUp++; 1903 EMLXS_STATE_CHANGE_LOCKED(hba, FC_LINK_UP); 1904 1905 hba->discovery_timer = hba->timer_tics + 1906 cfg[CFG_LINKUP_TIMEOUT].current + 1907 cfg[CFG_DISC_TIMEOUT].current; 1908 1909 mutex_exit(&EMLXS_PORT_LOCK); 1910 1911 emlxs_log_link_event(port); 1912 1913 return; 1914 1915 } /* emlxs_fcf_linkup() */ 1916 1917 1918 extern void 1919 emlxs_fcf_fini(emlxs_hba_t *hba) 1920 { 1921 emlxs_port_t *port = &PPORT; 1922 emlxs_port_t *vport; 1923 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 1924 uint32_t i; 1925 RPIobj_t *rpip; 1926 1927 if (!(hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT)) { 1928 return; 1929 } 1930 1931 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 1932 "fcf_fini: %s flag=%x fcfi_online=%d.", 1933 emlxs_fcftab_state_xlate(port, fcftab->state), 1934 fcftab->flag, fcftab->fcfi_online); 1935 1936 if (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN)) { 1937 (void) emlxs_fcf_shutdown_notify(port, 1); 1938 } 1939 1940 mutex_enter(&EMLXS_FCF_LOCK); 1941 hba->sli.sli4.flag &= ~EMLXS_SLI4_FCF_INIT; 1942 1943 /* Free the FCF memory */ 1944 1945 kmem_free(fcftab->table, 1946 (sizeof (FCFIobj_t) * fcftab->table_count)); 1947 1948 fcftab->table = NULL; 1949 fcftab->table_count = 0; 1950 1951 /* Free the VFI memory */ 1952 1953 kmem_free(hba->sli.sli4.VFI_table, 1954 (sizeof (VFIobj_t) * hba->sli.sli4.VFICount)); 1955 1956 hba->sli.sli4.VFI_table = NULL; 1957 hba->sli.sli4.VFICount = 0; 1958 1959 /* Free the VPI Fabric RPI's */ 1960 1961 for (i = 0; i < MAX_VPORTS; i++) { 1962 vport = &VPORT(i); 1963 rpip = vport->vpip->fabric_rpip; 1964 1965 if (rpip->state == RPI_STATE_FREE) { 1966 continue; 1967 } 1968 1969 (void) emlxs_rpi_free(port, rpip); 1970 } 1971 1972 /* Free the RPI memory */ 1973 1974 rpip = hba->sli.sli4.RPIp; 1975 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 1976 if (rpip->state == RPI_STATE_FREE) { 1977 continue; 1978 } 1979 1980 (void) emlxs_rpi_free(port, rpip); 1981 } 1982 1983 kmem_free(hba->sli.sli4.RPIp, 1984 (sizeof (RPIobj_t) * hba->sli.sli4.RPICount)); 1985 1986 hba->sli.sli4.RPIp = NULL; 1987 hba->sli.sli4.RPICount = 0; 1988 1989 /* Free the mutex */ 1990 mutex_exit(&EMLXS_FCF_LOCK); 1991 mutex_destroy(&EMLXS_FCF_LOCK); 1992 1993 return; 1994 1995 } /* emlxs_fcf_fini() */ 1996 1997 1998 extern void 1999 emlxs_fcf_init(emlxs_hba_t *hba) 2000 { 2001 emlxs_port_t *port = &PPORT; 2002 emlxs_port_t *vport; 2003 uint16_t i; 2004 FCFIobj_t *fcfp; 2005 VPIobj_t *vpip; 2006 VFIobj_t *vfip; 2007 RPIobj_t *rpip; 2008 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2009 2010 if (hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT) { 2011 return; 2012 } 2013 2014 mutex_init(&EMLXS_FCF_LOCK, NULL, MUTEX_DRIVER, NULL); 2015 mutex_enter(&EMLXS_FCF_LOCK); 2016 2017 /* FCFTAB */ 2018 2019 bzero(fcftab, sizeof (FCFTable_t)); 2020 fcftab->state = FCFTAB_STATE_OFFLINE; 2021 2022 /* FCFI */ 2023 2024 fcftab->table_count = hba->sli.sli4.FCFICount; 2025 fcftab->table = (FCFIobj_t *)kmem_zalloc( 2026 (sizeof (FCFIobj_t) * fcftab->table_count), KM_SLEEP); 2027 2028 fcfp = fcftab->table; 2029 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 2030 fcfp->index = i; 2031 fcfp->FCFI = 0xFFFF; 2032 fcfp->state = FCFI_STATE_FREE; 2033 } 2034 2035 /* VFI */ 2036 2037 hba->sli.sli4.VFI_table = (VFIobj_t *)kmem_zalloc( 2038 (sizeof (VFIobj_t) * hba->sli.sli4.VFICount), KM_SLEEP); 2039 2040 vfip = hba->sli.sli4.VFI_table; 2041 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) { 2042 vfip->VFI = emlxs_sli4_index_to_vfi(hba, i); 2043 vfip->index = i; 2044 vfip->state = VFI_STATE_OFFLINE; 2045 } 2046 2047 /* VPI */ 2048 2049 for (i = 0; i < MAX_VPORTS; i++) { 2050 vport = &VPORT(i); 2051 vpip = &vport->VPIobj; 2052 2053 bzero(vpip, sizeof (VPIobj_t)); 2054 vpip->index = i; 2055 vpip->VPI = emlxs_sli4_index_to_vpi(hba, i); 2056 vpip->port = vport; 2057 vpip->state = VPI_STATE_OFFLINE; 2058 vport->vpip = vpip; 2059 2060 /* Init the Fabric RPI's */ 2061 rpip = &vpip->fabric_rpi; 2062 rpip->state = RPI_STATE_FREE; 2063 rpip->index = 0xffff; 2064 rpip->RPI = FABRIC_RPI; 2065 rpip->did = FABRIC_DID; 2066 rpip->vpip = vpip; 2067 vpip->fabric_rpip = rpip; 2068 } 2069 2070 /* RPI */ 2071 2072 hba->sli.sli4.RPIp = (RPIobj_t *)kmem_zalloc( 2073 (sizeof (RPIobj_t) * hba->sli.sli4.RPICount), KM_SLEEP); 2074 2075 rpip = hba->sli.sli4.RPIp; 2076 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 2077 rpip->state = RPI_STATE_FREE; 2078 rpip->RPI = emlxs_sli4_index_to_rpi(hba, i); 2079 rpip->index = i; 2080 } 2081 2082 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2083 "fcf_init: %s flag=%x fcfi=%d vfi=%d vpi=%d rpi=%d.", 2084 emlxs_fcftab_state_xlate(port, fcftab->state), 2085 fcftab->flag, 2086 fcftab->table_count, 2087 hba->sli.sli4.VFICount, 2088 MAX_VPORTS, 2089 hba->sli.sli4.RPICount); 2090 2091 hba->sli.sli4.flag |= EMLXS_SLI4_FCF_INIT; 2092 mutex_exit(&EMLXS_FCF_LOCK); 2093 2094 return; 2095 2096 } /* emlxs_fcf_init() */ 2097 2098 2099 static char * 2100 emlxs_fcf_event_xlate(uint32_t state) 2101 { 2102 static char buffer[32]; 2103 uint32_t i; 2104 uint32_t count; 2105 2106 count = sizeof (emlxs_fcf_event_table) / sizeof (emlxs_table_t); 2107 for (i = 0; i < count; i++) { 2108 if (state == emlxs_fcf_event_table[i].code) { 2109 return (emlxs_fcf_event_table[i].string); 2110 } 2111 } 2112 2113 (void) snprintf(buffer, sizeof (buffer), "event=0x%x", state); 2114 return (buffer); 2115 2116 } /* emlxs_fcf_event_xlate() */ 2117 2118 2119 static char * 2120 emlxs_fcf_reason_xlate(uint32_t reason) 2121 { 2122 static char buffer[32]; 2123 uint32_t i; 2124 uint32_t count; 2125 2126 count = sizeof (emlxs_fcf_reason_table) / sizeof (emlxs_table_t); 2127 for (i = 0; i < count; i++) { 2128 if (reason == emlxs_fcf_reason_table[i].code) { 2129 return (emlxs_fcf_reason_table[i].string); 2130 } 2131 } 2132 2133 (void) snprintf(buffer, sizeof (buffer), "reason=0x%x", reason); 2134 return (buffer); 2135 2136 } /* emlxs_fcf_reason_xlate() */ 2137 2138 2139 extern void 2140 emlxs_fcf_timer_notify(emlxs_hba_t *hba) 2141 { 2142 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2143 2144 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2145 return; 2146 } 2147 2148 if (fcftab->table == 0) { 2149 return; 2150 } 2151 2152 mutex_enter(&EMLXS_FCF_LOCK); 2153 2154 if (SLI4_FCOE_MODE) { 2155 emlxs_fcoe_fcftab_sol_timer(hba); 2156 2157 emlxs_fcoe_fcftab_read_timer(hba); 2158 2159 emlxs_fcoe_fcftab_offline_timer(hba); 2160 } else { 2161 emlxs_fc_fcftab_online_timer(hba); 2162 } 2163 2164 emlxs_rpi_idle_timer(hba); 2165 2166 mutex_exit(&EMLXS_FCF_LOCK); 2167 2168 return; 2169 2170 } /* emlxs_fcf_timer_notify() */ 2171 2172 2173 extern uint32_t 2174 emlxs_fcf_shutdown_notify(emlxs_port_t *port, uint32_t wait) 2175 { 2176 emlxs_hba_t *hba = HBA; 2177 emlxs_port_t *pport = &PPORT; 2178 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2179 uint32_t rval = 0; 2180 uint32_t i; 2181 2182 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2183 return (1); 2184 } 2185 2186 if (!(pport->flag & EMLXS_PORT_BOUND) || 2187 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2188 return (1); 2189 } 2190 2191 if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) { 2192 return (0); 2193 } 2194 2195 mutex_enter(&EMLXS_FCF_LOCK); 2196 2197 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2198 "fcf_shutdown_notify: %s flag=%x " 2199 "fcfi_online=%d. Shutting down FCFTAB. >", 2200 emlxs_fcftab_state_xlate(port, fcftab->state), 2201 fcftab->flag, fcftab->fcfi_online); 2202 2203 rval = emlxs_fcftab_event(port, FCF_EVENT_SHUTDOWN, 0); 2204 2205 if (wait && (rval == 0)) { 2206 /* Wait for shutdown flag */ 2207 i = 0; 2208 while (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) && (i++ < 120)) { 2209 mutex_exit(&EMLXS_FCF_LOCK); 2210 BUSYWAIT_MS(1000); 2211 mutex_enter(&EMLXS_FCF_LOCK); 2212 } 2213 2214 if (!(fcftab->flag & EMLXS_FCFTAB_SHUTDOWN)) { 2215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 2216 "fcf_shutdown_notify: %s flag=%x " 2217 "fcfi_online=%d. Shutdown timeout.", 2218 emlxs_fcftab_state_xlate(port, fcftab->state), 2219 fcftab->flag, fcftab->fcfi_online); 2220 rval = 1; 2221 } 2222 } 2223 2224 mutex_exit(&EMLXS_FCF_LOCK); 2225 2226 return (rval); 2227 2228 } /* emlxs_fcf_shutdown_notify() */ 2229 2230 2231 extern uint32_t 2232 emlxs_fcf_linkup_notify(emlxs_port_t *port) 2233 { 2234 emlxs_hba_t *hba = HBA; 2235 emlxs_port_t *pport = &PPORT; 2236 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2237 uint32_t rval = 0; 2238 2239 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2240 return (1); 2241 } 2242 2243 if (!(pport->flag & EMLXS_PORT_BOUND) || 2244 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2245 return (1); 2246 } 2247 2248 mutex_enter(&EMLXS_FCF_LOCK); 2249 2250 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2251 "fcf_linkup_notify: %s flag=%x " 2252 "fcfi_online=%d. FCFTAB Link up. >", 2253 emlxs_fcftab_state_xlate(port, fcftab->state), 2254 fcftab->flag, fcftab->fcfi_online); 2255 2256 rval = emlxs_fcftab_event(port, FCF_EVENT_LINKUP, 0); 2257 2258 mutex_exit(&EMLXS_FCF_LOCK); 2259 2260 return (rval); 2261 2262 } /* emlxs_fcf_linkup_notify() */ 2263 2264 2265 extern uint32_t 2266 emlxs_fcf_linkdown_notify(emlxs_port_t *port) 2267 { 2268 emlxs_hba_t *hba = HBA; 2269 emlxs_port_t *pport = &PPORT; 2270 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2271 uint32_t rval = 0; 2272 2273 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2274 return (1); 2275 } 2276 2277 if (!(pport->flag & EMLXS_PORT_BOUND) || 2278 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2279 return (1); 2280 } 2281 2282 mutex_enter(&EMLXS_FCF_LOCK); 2283 2284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2285 "fcf_linkdown_notify: %s flag=%x " 2286 "fcfi_online=%d. FCFTAB Link down. >", 2287 emlxs_fcftab_state_xlate(port, fcftab->state), 2288 fcftab->flag, fcftab->fcfi_online); 2289 2290 rval = emlxs_fcftab_event(port, FCF_EVENT_LINKDOWN, 0); 2291 2292 mutex_exit(&EMLXS_FCF_LOCK); 2293 2294 return (rval); 2295 2296 } /* emlxs_fcf_linkdown_notify() */ 2297 2298 2299 extern uint32_t 2300 emlxs_fcf_cvl_notify(emlxs_port_t *port, uint32_t vpi) 2301 { 2302 emlxs_hba_t *hba = HBA; 2303 emlxs_port_t *pport = &PPORT; 2304 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2305 uint32_t rval = 0; 2306 2307 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2308 return (1); 2309 } 2310 2311 if (!(pport->flag & EMLXS_PORT_BOUND) || 2312 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2313 return (1); 2314 } 2315 2316 mutex_enter(&EMLXS_FCF_LOCK); 2317 2318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2319 "fcf_cvl_notify: %s flag=%x " 2320 "fcfi_online=%d. FCFTAB FCF CVL. >", 2321 emlxs_fcftab_state_xlate(port, fcftab->state), 2322 fcftab->flag, fcftab->fcfi_online); 2323 2324 rval = emlxs_fcftab_event(port, FCF_EVENT_CVL, 2325 (void *)((unsigned long)vpi)); 2326 2327 mutex_exit(&EMLXS_FCF_LOCK); 2328 2329 return (rval); 2330 2331 } /* emlxs_fcf_cvl_notify() */ 2332 2333 2334 extern uint32_t 2335 emlxs_fcf_full_notify(emlxs_port_t *port) 2336 { 2337 emlxs_hba_t *hba = HBA; 2338 emlxs_port_t *pport = &PPORT; 2339 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2340 uint32_t rval = 0; 2341 2342 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2343 return (1); 2344 } 2345 2346 if (!(pport->flag & EMLXS_PORT_BOUND) || 2347 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2348 return (1); 2349 } 2350 2351 mutex_enter(&EMLXS_FCF_LOCK); 2352 2353 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2354 "fcf_full_notify: %s flag=%x " 2355 "fcfi_online=%d. FCFTAB FCF full. >", 2356 emlxs_fcftab_state_xlate(port, fcftab->state), 2357 fcftab->flag, fcftab->fcfi_online); 2358 2359 rval = emlxs_fcftab_event(port, FCF_EVENT_FCFTAB_FULL, 0); 2360 2361 mutex_exit(&EMLXS_FCF_LOCK); 2362 2363 return (rval); 2364 2365 } /* emlxs_fcf_full_notify() */ 2366 2367 2368 extern uint32_t 2369 emlxs_fcf_found_notify(emlxs_port_t *port, uint32_t fcf_index) 2370 { 2371 emlxs_hba_t *hba = HBA; 2372 emlxs_port_t *pport = &PPORT; 2373 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2374 uint32_t rval = 0; 2375 2376 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2377 return (1); 2378 } 2379 2380 if (!(pport->flag & EMLXS_PORT_BOUND) || 2381 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2382 return (1); 2383 } 2384 2385 mutex_enter(&EMLXS_FCF_LOCK); 2386 2387 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2388 "fcf_found_notify: %s flag=%x " 2389 "fcfi_online=%d. FCFTAB FCF found. >", 2390 emlxs_fcftab_state_xlate(port, fcftab->state), 2391 fcftab->flag, fcftab->fcfi_online); 2392 2393 rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_FOUND, 2394 (void *)((unsigned long)fcf_index)); 2395 2396 mutex_exit(&EMLXS_FCF_LOCK); 2397 2398 return (rval); 2399 2400 } /* emlxs_fcf_found_notify() */ 2401 2402 2403 extern uint32_t 2404 emlxs_fcf_changed_notify(emlxs_port_t *port, uint32_t fcf_index) 2405 { 2406 emlxs_hba_t *hba = HBA; 2407 emlxs_port_t *pport = &PPORT; 2408 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2409 uint32_t rval = 0; 2410 2411 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2412 return (1); 2413 } 2414 2415 if (!(pport->flag & EMLXS_PORT_BOUND) || 2416 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2417 return (1); 2418 } 2419 2420 mutex_enter(&EMLXS_FCF_LOCK); 2421 2422 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2423 "fcf_changes_notify: %s flag=%x " 2424 "fcfi_online=%d. FCFTAB FCF changed. >", 2425 emlxs_fcftab_state_xlate(port, fcftab->state), 2426 fcftab->flag, fcftab->fcfi_online); 2427 2428 rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_CHANGED, 2429 (void *)((unsigned long)fcf_index)); 2430 2431 mutex_exit(&EMLXS_FCF_LOCK); 2432 2433 return (rval); 2434 2435 } /* emlxs_fcf_changed_notify() */ 2436 2437 2438 extern uint32_t 2439 emlxs_fcf_lost_notify(emlxs_port_t *port, uint32_t fcf_index) 2440 { 2441 emlxs_hba_t *hba = HBA; 2442 emlxs_port_t *pport = &PPORT; 2443 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2444 uint32_t rval = 0; 2445 2446 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 2447 return (1); 2448 } 2449 2450 if (!(pport->flag & EMLXS_PORT_BOUND) || 2451 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2452 return (1); 2453 } 2454 2455 mutex_enter(&EMLXS_FCF_LOCK); 2456 2457 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2458 "fcf_lost_notify: %s flag=%x " 2459 "fcfi_online=%d. FCFTAB FCF lost. >", 2460 emlxs_fcftab_state_xlate(port, fcftab->state), 2461 fcftab->flag, fcftab->fcfi_online); 2462 2463 rval = emlxs_fcftab_event(port, FCF_EVENT_FCF_LOST, 2464 (void *)((unsigned long)fcf_index)); 2465 2466 mutex_exit(&EMLXS_FCF_LOCK); 2467 2468 return (rval); 2469 2470 } /* emlxs_fcf_lost_notify() */ 2471 2472 2473 /* ************************************************************************** */ 2474 /* FCFTAB Generic */ 2475 /* ************************************************************************** */ 2476 2477 static char * 2478 emlxs_fcftab_state_xlate(emlxs_port_t *port, uint32_t state) 2479 { 2480 emlxs_hba_t *hba = HBA; 2481 2482 if (SLI4_FCOE_MODE) { 2483 return (emlxs_fcoe_fcftab_state_xlate(state)); 2484 } else { 2485 return (emlxs_fc_fcftab_state_xlate(state)); 2486 } 2487 2488 } /* emlxs_fcftab_state_xlate() */ 2489 2490 static uint32_t 2491 emlxs_fcftab_event(emlxs_port_t *port, uint32_t evt, void *arg1) 2492 { 2493 emlxs_hba_t *hba = HBA; 2494 2495 if (SLI4_FCOE_MODE) { 2496 return (emlxs_fcoe_fcftab_event(port, evt, arg1)); 2497 } else { 2498 return (emlxs_fc_fcftab_event(port, evt, arg1)); 2499 } 2500 2501 } /* emlxs_fcftab_event() */ 2502 2503 2504 /*ARGSUSED*/ 2505 static uint32_t 2506 emlxs_fcftab_shutdown_action(emlxs_port_t *port, uint32_t evt, 2507 void *arg1) 2508 { 2509 emlxs_hba_t *hba = HBA; 2510 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2511 FCFIobj_t *fcfp; 2512 uint32_t i; 2513 uint32_t online; 2514 2515 if (fcftab->state != FCFTAB_STATE_SHUTDOWN) { 2516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 2517 "fcftab_shutdown_action:%x %s:%s arg=%p. " 2518 "Invalid state. <", 2519 fcftab->TID, 2520 emlxs_fcftab_state_xlate(port, fcftab->state), 2521 emlxs_fcf_event_xlate(evt), arg1); 2522 return (1); 2523 } 2524 2525 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 2526 2527 if (fcftab->prev_state != FCFTAB_STATE_SHUTDOWN) { 2528 /* Offline all FCF's */ 2529 online = 0; 2530 fcfp = fcftab->table; 2531 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 2532 2533 if (fcfp->state <= FCFI_STATE_OFFLINE) { 2534 continue; 2535 } 2536 2537 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2538 "fcftab_shutdown_action:%x fcfi_online=%d. " 2539 "Offlining FCFI:%d. >", 2540 fcftab->TID, 2541 fcftab->fcfi_online, 2542 fcfp->fcf_index); 2543 2544 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_OFFLINE, 2545 fcfp); 2546 2547 online++; 2548 } 2549 2550 if (!online) { 2551 goto done; 2552 } 2553 2554 return (0); 2555 } 2556 2557 /* Check FCF states */ 2558 online = 0; 2559 fcfp = fcftab->table; 2560 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 2561 2562 if (fcfp->state <= FCFI_STATE_OFFLINE) { 2563 continue; 2564 } 2565 2566 online++; 2567 } 2568 2569 if (online) { 2570 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2571 "fcftab_shutdown_action:%x %s:%s arg=%p. " 2572 "fcfi_online=%d,%d <", 2573 fcftab->TID, 2574 emlxs_fcftab_state_xlate(port, fcftab->state), 2575 emlxs_fcf_event_xlate(evt), arg1, 2576 online, fcftab->fcfi_online); 2577 2578 return (0); 2579 } 2580 2581 done: 2582 /* Free FCF table */ 2583 fcfp = fcftab->table; 2584 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 2585 2586 if (fcfp->state == FCFI_STATE_FREE) { 2587 continue; 2588 } 2589 2590 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2591 "fcftab_shutdown_action:%x. Freeing FCFI:%d. >", 2592 fcftab->TID, 2593 fcfp->fcf_index); 2594 2595 (void) emlxs_fcfi_free(port, fcfp); 2596 } 2597 2598 /* Clean the selection table */ 2599 bzero(fcftab->fcfi, sizeof (fcftab->fcfi)); 2600 fcftab->fcfi_count = 0; 2601 2602 fcftab->flag |= EMLXS_FCFTAB_SHUTDOWN; 2603 2604 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2605 "fcftab_shutdown_action:%x %s:%s arg=%p flag=%x fcfi_online=%d. " 2606 "Shutdown. <", 2607 fcftab->TID, 2608 emlxs_fcftab_state_xlate(port, fcftab->state), 2609 emlxs_fcf_event_xlate(evt), arg1, 2610 fcftab->flag, fcftab->fcfi_online); 2611 2612 return (0); 2613 2614 } /* emlxs_fcftab_shutdown_action() */ 2615 2616 2617 /* ************************************************************************** */ 2618 /* FC FCFTAB */ 2619 /* ************************************************************************** */ 2620 2621 static char * 2622 emlxs_fc_fcftab_state_xlate(uint32_t state) 2623 { 2624 static char buffer[32]; 2625 uint32_t i; 2626 uint32_t count; 2627 2628 count = sizeof (emlxs_fc_fcftab_state_table) / sizeof (emlxs_table_t); 2629 for (i = 0; i < count; i++) { 2630 if (state == emlxs_fc_fcftab_state_table[i].code) { 2631 return (emlxs_fc_fcftab_state_table[i].string); 2632 } 2633 } 2634 2635 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 2636 return (buffer); 2637 2638 } /* emlxs_fc_fcftab_state_xlate() */ 2639 2640 2641 static uint32_t 2642 emlxs_fc_fcftab_action(emlxs_port_t *port, uint32_t evt, 2643 void *arg1) 2644 { 2645 emlxs_hba_t *hba = HBA; 2646 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2647 uint32_t rval = 0; 2648 uint32_t(*func) (emlxs_port_t *, uint32_t, void *); 2649 uint32_t index; 2650 uint32_t events; 2651 uint16_t state; 2652 2653 /* Convert event to action table index */ 2654 switch (evt) { 2655 case FCF_EVENT_STATE_ENTER: 2656 index = 0; 2657 break; 2658 case FCF_EVENT_SHUTDOWN: 2659 index = 1; 2660 break; 2661 case FCF_EVENT_LINKUP: 2662 index = 2; 2663 break; 2664 case FCF_EVENT_LINKDOWN: 2665 index = 3; 2666 break; 2667 case FCF_EVENT_FCFI_ONLINE: 2668 index = 4; 2669 break; 2670 case FCF_EVENT_FCFI_OFFLINE: 2671 index = 5; 2672 break; 2673 default: 2674 return (1); 2675 } 2676 2677 events = FC_FCFTAB_ACTION_EVENTS; 2678 state = fcftab->state; 2679 2680 index += (state * events); 2681 func = (uint32_t(*) (emlxs_port_t *, uint32_t, void *)) 2682 emlxs_fc_fcftab_action_table[index]; 2683 2684 if (!func) { 2685 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 2686 "fc_fcftab_action:%x %s:%s arg=%p. No action. <", 2687 fcftab->TID, 2688 emlxs_fc_fcftab_state_xlate(fcftab->state), 2689 emlxs_fcf_event_xlate(evt), arg1); 2690 2691 return (1); 2692 } 2693 2694 rval = (func)(port, evt, arg1); 2695 2696 return (rval); 2697 2698 } /* emlxs_fc_fcftab_action() */ 2699 2700 2701 static uint32_t 2702 emlxs_fc_fcftab_event(emlxs_port_t *port, uint32_t evt, 2703 void *arg1) 2704 { 2705 emlxs_hba_t *hba = HBA; 2706 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2707 uint32_t rval = 0; 2708 2709 /* Filter events */ 2710 switch (evt) { 2711 case FCF_EVENT_SHUTDOWN: 2712 case FCF_EVENT_LINKUP: 2713 case FCF_EVENT_LINKDOWN: 2714 case FCF_EVENT_FCFI_ONLINE: 2715 case FCF_EVENT_FCFI_OFFLINE: 2716 break; 2717 2718 default: 2719 return (1); 2720 } 2721 2722 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 2723 "fc_fcftab_event:%x %s:%s arg=%p.", 2724 fcftab->TID, 2725 emlxs_fc_fcftab_state_xlate(fcftab->state), 2726 emlxs_fcf_event_xlate(evt), arg1); 2727 2728 rval = emlxs_fc_fcftab_action(port, evt, arg1); 2729 2730 return (rval); 2731 2732 } /* emlxs_fc_fcftab_event() */ 2733 2734 2735 /* EMLXS_FCF_LOCK must be held to enter */ 2736 /*ARGSUSED*/ 2737 static uint32_t 2738 emlxs_fc_fcftab_state(emlxs_port_t *port, uint16_t state, uint16_t reason, 2739 uint32_t explain, void *arg1) 2740 { 2741 emlxs_hba_t *hba = HBA; 2742 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2743 uint32_t rval = 0; 2744 2745 if (state >= FC_FCFTAB_ACTION_STATES) { 2746 return (1); 2747 } 2748 2749 if ((fcftab->state == state) && 2750 (reason != FCF_REASON_REENTER)) { 2751 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 2752 "fcftab_state:%x %s:%s:0x%x arg=%p. " 2753 "State not changed. <", 2754 fcftab->TID, 2755 emlxs_fc_fcftab_state_xlate(state), 2756 emlxs_fcf_reason_xlate(reason), 2757 explain, arg1); 2758 return (1); 2759 } 2760 2761 if (!reason) { 2762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 2763 "fcftab_state:%x %s-->%s arg=%p", 2764 fcftab->TID, 2765 emlxs_fc_fcftab_state_xlate(fcftab->state), 2766 emlxs_fc_fcftab_state_xlate(state), arg1); 2767 } else if (reason == FCF_REASON_EVENT) { 2768 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 2769 "fcftab_state:%x %s-->%s:%s:%s arg=%p", 2770 fcftab->TID, 2771 emlxs_fc_fcftab_state_xlate(fcftab->state), 2772 emlxs_fc_fcftab_state_xlate(state), 2773 emlxs_fcf_reason_xlate(reason), 2774 emlxs_fcf_event_xlate(explain), arg1); 2775 } else if (explain) { 2776 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 2777 "fcftab_state:%x %s-->%s:%s:0x%x arg=%p", 2778 fcftab->TID, 2779 emlxs_fc_fcftab_state_xlate(fcftab->state), 2780 emlxs_fc_fcftab_state_xlate(state), 2781 emlxs_fcf_reason_xlate(reason), 2782 explain, arg1); 2783 } else { 2784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 2785 "fcftab_state:%x %s-->%s:%s arg=%p", 2786 fcftab->TID, 2787 emlxs_fc_fcftab_state_xlate(fcftab->state), 2788 emlxs_fc_fcftab_state_xlate(state), 2789 emlxs_fcf_reason_xlate(reason), arg1); 2790 } 2791 2792 fcftab->prev_state = fcftab->state; 2793 fcftab->prev_reason = fcftab->reason; 2794 fcftab->state = state; 2795 fcftab->reason = reason; 2796 2797 rval = emlxs_fc_fcftab_action(port, FCF_EVENT_STATE_ENTER, arg1); 2798 2799 return (rval); 2800 2801 } /* emlxs_fc_fcftab_state() */ 2802 2803 2804 static void 2805 emlxs_fc_fcftab_online_timer(emlxs_hba_t *hba) 2806 { 2807 emlxs_port_t *port = &PPORT; 2808 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2809 2810 /* Check FCF timer */ 2811 if (!fcftab->online_timer || 2812 (hba->timer_tics < fcftab->online_timer)) { 2813 return; 2814 } 2815 fcftab->online_timer = 0; 2816 2817 switch (fcftab->state) { 2818 case FC_FCFTAB_STATE_ONLINE: 2819 emlxs_fcf_linkup(port); 2820 2821 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 2822 fcftab->flag |= EMLXS_FC_FCFTAB_TOPO_REQ; 2823 fcftab->generation++; 2824 2825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2826 "fc_fcftab_online_timer:%x %s gen=%x. Read topology. >", 2827 fcftab->TID, 2828 emlxs_fc_fcftab_state_xlate(fcftab->state), 2829 fcftab->generation); 2830 2831 (void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO, 2832 FCF_REASON_EVENT, 0, 0); 2833 break; 2834 2835 default: 2836 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2837 "fc_fcftab_online_timer:%x %s", 2838 fcftab->TID, 2839 emlxs_fc_fcftab_state_xlate(fcftab->state)); 2840 break; 2841 } 2842 2843 return; 2844 2845 } /* emlxs_fc_fcftab_online_timer() */ 2846 2847 2848 /*ARGSUSED*/ 2849 static uint32_t 2850 emlxs_fc_fcftab_offline_action(emlxs_port_t *port, uint32_t evt, 2851 void *arg1) 2852 { 2853 emlxs_hba_t *hba = HBA; 2854 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2855 uint32_t rval = 0; 2856 2857 if (fcftab->state != FC_FCFTAB_STATE_OFFLINE) { 2858 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 2859 "fc_fcftab_offline_action:%x %s:%s arg=%p. " 2860 "Invalid state. <", 2861 fcftab->TID, 2862 emlxs_fc_fcftab_state_xlate(fcftab->state), 2863 emlxs_fcf_event_xlate(evt), arg1); 2864 return (1); 2865 } 2866 2867 fcftab->flag &= ~EMLXS_FC_FCFTAB_OFFLINE_REQ; 2868 2869 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 2870 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2871 "fc_fcftab_offline_action:%x %s:%s arg=%p flag=%x. " 2872 "Handling request.", 2873 fcftab->TID, 2874 emlxs_fc_fcftab_state_xlate(fcftab->state), 2875 emlxs_fcf_event_xlate(evt), arg1, 2876 fcftab->flag); 2877 2878 rval = emlxs_fc_fcftab_req_handler(port, arg1); 2879 return (rval); 2880 } 2881 2882 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2883 "fc_fcftab_offline_action:%x %s:%s arg=%p fcfi_online=%d. " 2884 "Offline. <", 2885 fcftab->TID, 2886 emlxs_fc_fcftab_state_xlate(fcftab->state), 2887 emlxs_fcf_event_xlate(evt), arg1, 2888 fcftab->fcfi_online); 2889 2890 return (0); 2891 2892 } /* emlxs_fc_fcftab_offline_action() */ 2893 2894 2895 /*ARGSUSED*/ 2896 static uint32_t 2897 emlxs_fc_fcftab_online_action(emlxs_port_t *port, uint32_t evt, 2898 void *arg1) 2899 { 2900 emlxs_hba_t *hba = HBA; 2901 emlxs_port_t *pport = &PPORT; 2902 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2903 uint32_t rval = 0; 2904 2905 if (fcftab->state != FC_FCFTAB_STATE_ONLINE) { 2906 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 2907 "fc_fcftab_online_action:%x %s:%s arg=%p. " 2908 "Invalid state. <", 2909 fcftab->TID, 2910 emlxs_fc_fcftab_state_xlate(fcftab->state), 2911 emlxs_fcf_event_xlate(evt), arg1); 2912 return (1); 2913 } 2914 2915 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 2916 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2917 "fc_fcftab_online_action:%x flag=%x. " 2918 "Handling requested.", 2919 fcftab->TID, 2920 fcftab->flag); 2921 2922 rval = emlxs_fc_fcftab_req_handler(port, arg1); 2923 return (rval); 2924 } 2925 2926 if (fcftab->fcfi_online == 0) { 2927 if (!(pport->flag & EMLXS_PORT_BOUND) || 2928 (pport->vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 2929 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2930 "fc_fcftab_online_action:%x %s:%s " 2931 "fcfi_online=0. Pport not bound. <", 2932 fcftab->TID, 2933 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 2934 emlxs_fcf_event_xlate(evt)); 2935 } else { 2936 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2937 "fc_fcftab_online_action:%x %s:%s " 2938 "fcfi_online=0. Starting online timer. <", 2939 fcftab->TID, 2940 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 2941 emlxs_fcf_event_xlate(evt)); 2942 2943 /* Start the online timer */ 2944 fcftab->online_timer = hba->timer_tics + 1; 2945 } 2946 2947 emlxs_fcf_linkdown(port); 2948 2949 return (0); 2950 } 2951 2952 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2953 "fc_fcftab_online_action:%x flag=%x fcfi_online=%d. " 2954 "Online. <", 2955 fcftab->TID, 2956 fcftab->flag, 2957 fcftab->fcfi_online); 2958 2959 emlxs_fcf_linkup(port); 2960 2961 return (0); 2962 2963 } /* emlxs_fc_fcftab_online_action() */ 2964 2965 2966 /*ARGSUSED*/ 2967 static uint32_t 2968 emlxs_fc_fcftab_topo_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 2969 { 2970 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 2971 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 2972 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 2973 MATCHMAP *mp; 2974 uint8_t *alpa_map; 2975 uint32_t j; 2976 uint16_t TID; 2977 2978 mutex_enter(&EMLXS_FCF_LOCK); 2979 TID = (uint16_t)((unsigned long)mbq->context); 2980 2981 if (fcftab->state != FC_FCFTAB_STATE_TOPO) { 2982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2983 "fc_fcftab_topo_mbcmpl:%x state=%s.", 2984 TID, 2985 emlxs_fc_fcftab_state_xlate(fcftab->state)); 2986 2987 mutex_exit(&EMLXS_FCF_LOCK); 2988 return (0); 2989 } 2990 2991 if (TID != fcftab->generation) { 2992 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 2993 "fc_fcftab_topo_mbcmpl:%x %s. " 2994 "Incorrect generation %x. Dropping.", 2995 TID, 2996 emlxs_fc_fcftab_state_xlate(fcftab->state), 2997 fcftab->generation); 2998 2999 mutex_exit(&EMLXS_FCF_LOCK); 3000 return (0); 3001 } 3002 3003 if (mb4->mbxStatus) { 3004 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3005 "fc_fcftab_topo_mbcmpl:%x failed. %s. >", 3006 fcftab->TID, 3007 emlxs_mb_xlate_status(mb4->mbxStatus)); 3008 3009 if (mb4->mbxStatus == MBXERR_NO_RESOURCES) { 3010 (void) emlxs_fc_fcftab_state(port, 3011 FC_FCFTAB_STATE_TOPO_FAILED, 3012 FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0); 3013 } else { 3014 (void) emlxs_fc_fcftab_state(port, 3015 FC_FCFTAB_STATE_TOPO_FAILED, 3016 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 3017 } 3018 3019 mutex_exit(&EMLXS_FCF_LOCK); 3020 return (0); 3021 } 3022 3023 if (mb4->un.varReadLA.attType == AT_LINK_DOWN) { 3024 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3025 "fc_fcftab_topo_mbcmpl:%x Linkdown attention. " 3026 "Offline requested.", 3027 fcftab->TID); 3028 3029 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 3030 fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ; 3031 (void) emlxs_fc_fcftab_req_handler(port, 0); 3032 3033 mutex_exit(&EMLXS_FCF_LOCK); 3034 return (0); 3035 } 3036 3037 if (hba->link_event_tag != mb4->un.varReadLA.eventTag) { 3038 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3039 "fc_fcftab_topo_mbcmpl:%x Event tag invalid. %x != %x", 3040 fcftab->TID, 3041 hba->link_event_tag, mb4->un.varReadLA.eventTag); 3042 } 3043 3044 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3045 "fc_fcftab_topo_mbcmpl:%x state=%s type=%s iotag=%d " 3046 "alpa=%x. >", 3047 fcftab->TID, 3048 emlxs_fc_fcftab_state_xlate(fcftab->state), 3049 (mb4->un.varReadLA.attType == AT_LINK_UP)?"linkup":"linkdown", 3050 hba->link_event_tag, 3051 (uint32_t)mb4->un.varReadLA.granted_AL_PA); 3052 3053 /* Link is up */ 3054 3055 /* Save the linkspeed & topology */ 3056 hba->linkspeed = mb4->un.varReadLA.UlnkSpeed; 3057 hba->topology = mb4->un.varReadLA.topology; 3058 3059 if (hba->topology != TOPOLOGY_LOOP) { 3060 port->did = 0; 3061 port->lip_type = 0; 3062 hba->flag &= ~FC_BYPASSED_MODE; 3063 bzero((caddr_t)port->alpa_map, 128); 3064 3065 goto done; 3066 } 3067 3068 /* TOPOLOGY_LOOP */ 3069 3070 port->lip_type = mb4->un.varReadLA.lipType; 3071 3072 if (mb4->un.varReadLA.pb) { 3073 hba->flag |= FC_BYPASSED_MODE; 3074 } else { 3075 hba->flag &= ~FC_BYPASSED_MODE; 3076 } 3077 3078 /* Save the granted_alpa and alpa_map */ 3079 3080 port->granted_alpa = mb4->un.varReadLA.granted_AL_PA; 3081 mp = (MATCHMAP *)mbq->bp; 3082 alpa_map = (uint8_t *)port->alpa_map; 3083 3084 bcopy((caddr_t)mp->virt, (caddr_t)alpa_map, 128); 3085 3086 /* Check number of devices in map */ 3087 if (alpa_map[0] > 127) { 3088 alpa_map[0] = 127; 3089 } 3090 3091 EMLXS_MSGF(EMLXS_CONTEXT, 3092 &emlxs_link_atten_msg, 3093 "alpa_map: %d device(s): " 3094 "%02x %02x %02x %02x %02x %02x %02x %02x", 3095 alpa_map[0], alpa_map[1], 3096 alpa_map[2], alpa_map[3], 3097 alpa_map[4], alpa_map[5], 3098 alpa_map[6], alpa_map[7], 3099 alpa_map[8]); 3100 3101 for (j = 9; j <= alpa_map[0]; j += 8) { 3102 EMLXS_MSGF(EMLXS_CONTEXT, 3103 &emlxs_link_atten_msg, 3104 "alpa_map: " 3105 "%02x %02x %02x %02x %02x %02x %02x %02x", 3106 alpa_map[j], 3107 alpa_map[j + 1], 3108 alpa_map[j + 2], 3109 alpa_map[j + 3], 3110 alpa_map[j + 4], 3111 alpa_map[j + 5], 3112 alpa_map[j + 6], 3113 alpa_map[j + 7]); 3114 } 3115 3116 done: 3117 3118 (void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_CMPL, 3119 0, 0, 0); 3120 3121 mutex_exit(&EMLXS_FCF_LOCK); 3122 return (0); 3123 3124 } /* emlxs_fc_fcftab_topo_mbcmpl() */ 3125 3126 3127 /*ARGSUSED*/ 3128 static uint32_t 3129 emlxs_fc_fcftab_topo_action(emlxs_port_t *port, uint32_t evt, 3130 void *arg1) 3131 { 3132 emlxs_hba_t *hba = HBA; 3133 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3134 MAILBOXQ *mbq; 3135 MAILBOX4 *mb4; 3136 uint32_t rval = 0; 3137 MATCHMAP *mp; 3138 3139 if (fcftab->state != FC_FCFTAB_STATE_TOPO) { 3140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3141 "fc_fcftab_topo_action:%x %s:%s arg=%p. " 3142 "Invalid state. <", 3143 fcftab->TID, 3144 emlxs_fc_fcftab_state_xlate(fcftab->state), 3145 emlxs_fcf_event_xlate(evt), arg1); 3146 return (1); 3147 } 3148 3149 if ((fcftab->prev_state != FC_FCFTAB_STATE_TOPO_FAILED) || 3150 (fcftab->flag & EMLXS_FC_FCFTAB_TOPO_REQ)) { 3151 fcftab->flag &= ~EMLXS_FC_FCFTAB_TOPO_REQ; 3152 fcftab->attempts = 0; 3153 } 3154 3155 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 3156 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3157 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3158 "Handling request.", 3159 fcftab->TID, 3160 emlxs_fc_fcftab_state_xlate(fcftab->state), 3161 emlxs_fcf_event_xlate(evt), arg1, 3162 fcftab->generation, 3163 fcftab->flag); 3164 3165 rval = emlxs_fc_fcftab_req_handler(port, arg1); 3166 return (rval); 3167 } 3168 3169 if (fcftab->attempts == 0) { 3170 fcftab->TID = fcftab->generation; 3171 } 3172 3173 if (hba->topology != TOPOLOGY_LOOP) { 3174 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3175 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3176 "Fabric Topology. Skipping READ_TOPO.", 3177 fcftab->TID, 3178 emlxs_fc_fcftab_state_xlate(fcftab->state), 3179 emlxs_fcf_event_xlate(evt), arg1, 3180 fcftab->generation, 3181 fcftab->flag); 3182 3183 port->did = 0; 3184 port->lip_type = 0; 3185 hba->flag &= ~FC_BYPASSED_MODE; 3186 bzero((caddr_t)port->alpa_map, 128); 3187 3188 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK, 3189 FCF_REASON_EVENT, evt, arg1); 3190 return (rval); 3191 } 3192 3193 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3194 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3195 "Sending READ_TOPO. <", 3196 fcftab->TID, 3197 emlxs_fc_fcftab_state_xlate(fcftab->state), 3198 emlxs_fcf_event_xlate(evt), arg1, 3199 fcftab->generation, 3200 fcftab->flag); 3201 3202 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 3203 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED, 3204 FCF_REASON_NO_MBOX, 0, arg1); 3205 return (rval); 3206 } 3207 mb4 = (MAILBOX4*)mbq; 3208 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 3209 3210 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 3211 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3212 3213 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED, 3214 FCF_REASON_NO_BUFFER, 0, arg1); 3215 return (rval); 3216 } 3217 bzero(mp->virt, mp->size); 3218 3219 mbq->nonembed = NULL; 3220 mbq->bp = (void *)mp; 3221 mbq->mbox_cmpl = emlxs_fc_fcftab_topo_mbcmpl; 3222 mbq->context = (void *)((unsigned long)fcftab->TID); 3223 mbq->port = (void *)port; 3224 3225 mb4->un.varSLIConfig.be.embedded = 0; 3226 mb4->mbxCommand = MBX_READ_TOPOLOGY; 3227 mb4->mbxOwner = OWN_HOST; 3228 3229 mb4->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128; 3230 mb4->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys); 3231 mb4->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys); 3232 3233 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 3234 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 3235 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 3236 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3237 3238 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_FAILED, 3239 FCF_REASON_SEND_FAILED, rval, arg1); 3240 3241 return (rval); 3242 } 3243 3244 return (0); 3245 3246 } /* emlxs_fc_fcftab_topo_action() */ 3247 3248 3249 /*ARGSUSED*/ 3250 static uint32_t 3251 emlxs_fc_fcftab_topo_failed_action(emlxs_port_t *port, uint32_t evt, 3252 void *arg1) 3253 { 3254 emlxs_hba_t *hba = HBA; 3255 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3256 uint32_t rval = 0; 3257 3258 fcftab->attempts++; 3259 3260 if (fcftab->state != FC_FCFTAB_STATE_TOPO_FAILED) { 3261 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3262 "fc_fcftab_topo_failed_action:%x %s:%s arg=%p " 3263 "attempt=%d. Invalid state. <", 3264 fcftab->TID, 3265 emlxs_fc_fcftab_state_xlate(fcftab->state), 3266 emlxs_fcf_event_xlate(evt), 3267 arg1, fcftab->attempts); 3268 return (1); 3269 } 3270 3271 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) || 3272 (fcftab->reason == FCF_REASON_SEND_FAILED) || 3273 (fcftab->attempts >= 3)) { 3274 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3275 "fc_fcftab_topo_failed_action:%x %s:%s arg=%p " 3276 "attempt=%d reason=%x. Giving up.", 3277 fcftab->TID, 3278 emlxs_fc_fcftab_state_xlate(fcftab->state), 3279 emlxs_fcf_event_xlate(evt), arg1, 3280 fcftab->attempts, 3281 fcftab->reason); 3282 3283 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO_CMPL, 3284 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3285 3286 } else { 3287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3288 "fc_fcftab_topo_failed_action:%x %s:%s arg=%p " 3289 "attempt=%d reason=%x. Retrying.", 3290 fcftab->TID, 3291 emlxs_fc_fcftab_state_xlate(fcftab->state), 3292 emlxs_fcf_event_xlate(evt), arg1, 3293 fcftab->attempts, 3294 fcftab->reason); 3295 3296 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO, 3297 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3298 } 3299 3300 return (rval); 3301 3302 } /* emlxs_fc_fcftab_topo_failed_action() */ 3303 3304 3305 /*ARGSUSED*/ 3306 static uint32_t 3307 emlxs_fc_fcftab_topo_cmpl_action(emlxs_port_t *port, uint32_t evt, 3308 void *arg1) 3309 { 3310 emlxs_hba_t *hba = HBA; 3311 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3312 uint32_t rval = 0; 3313 3314 if (fcftab->state != FC_FCFTAB_STATE_TOPO_CMPL) { 3315 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3316 "fc_fcftab_topo_cmpl_action:%x %s:%s arg=%p. " 3317 "Invalid state. <", 3318 fcftab->TID, 3319 emlxs_fc_fcftab_state_xlate(fcftab->state), 3320 emlxs_fcf_event_xlate(evt), arg1); 3321 return (1); 3322 } 3323 3324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3325 "fc_fcftab_topo_cmpl_action:%x attempts=%d. " 3326 "Config link.", 3327 fcftab->TID, 3328 fcftab->attempts); 3329 3330 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK, 3331 FCF_REASON_EVENT, evt, arg1); 3332 3333 return (rval); 3334 3335 } /* emlxs_fc_fcftab_topo_cmpl_action() */ 3336 3337 3338 /*ARGSUSED*/ 3339 static uint32_t 3340 emlxs_fc_fcftab_cfglink_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 3341 { 3342 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 3343 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3344 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 3345 uint16_t TID; 3346 3347 mutex_enter(&EMLXS_FCF_LOCK); 3348 TID = (uint16_t)((unsigned long)mbq->context); 3349 3350 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK) { 3351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3352 "fc_fcftab_cfglink_mbcmpl:%x state=%s.", 3353 TID, 3354 emlxs_fc_fcftab_state_xlate(fcftab->state)); 3355 3356 mutex_exit(&EMLXS_FCF_LOCK); 3357 return (0); 3358 } 3359 3360 if (TID != fcftab->generation) { 3361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3362 "fc_fcftab_cfglink_mbcmpl:%x %s. " 3363 "Incorrect generation %x. Dropping.", 3364 TID, 3365 emlxs_fc_fcftab_state_xlate(fcftab->state), 3366 fcftab->generation); 3367 3368 mutex_exit(&EMLXS_FCF_LOCK); 3369 return (0); 3370 } 3371 3372 if (mb4->mbxStatus) { 3373 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3374 "fc_fcftab_cfglink_mbcmpl:%x failed. %s. >", 3375 fcftab->TID, 3376 emlxs_mb_xlate_status(mb4->mbxStatus)); 3377 3378 if (mb4->mbxStatus == MBXERR_NO_RESOURCES) { 3379 (void) emlxs_fc_fcftab_state(port, 3380 FC_FCFTAB_STATE_CFGLINK_FAILED, 3381 FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0); 3382 } else { 3383 (void) emlxs_fc_fcftab_state(port, 3384 FC_FCFTAB_STATE_CFGLINK_FAILED, 3385 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 3386 } 3387 3388 mutex_exit(&EMLXS_FCF_LOCK); 3389 return (0); 3390 } 3391 3392 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3393 "fc_fcftab_cfglink_mbcmpl:%x. >", 3394 fcftab->TID); 3395 3396 (void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK_CMPL, 3397 0, 0, 0); 3398 3399 mutex_exit(&EMLXS_FCF_LOCK); 3400 return (0); 3401 3402 } /* emlxs_fc_fcftab_cfglink_mbcmpl() */ 3403 3404 3405 3406 /*ARGSUSED*/ 3407 static uint32_t 3408 emlxs_fc_fcftab_cfglink_action(emlxs_port_t *port, uint32_t evt, 3409 void *arg1) 3410 { 3411 emlxs_hba_t *hba = HBA; 3412 emlxs_config_t *cfg = &CFG; 3413 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3414 MAILBOXQ *mbq; 3415 MAILBOX4 *mb4; 3416 uint32_t rval = 0; 3417 3418 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK) { 3419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3420 "fc_fcftab_cfglink_action:%x %s:%s arg=%p. " 3421 "Invalid state. <", 3422 fcftab->TID, 3423 emlxs_fc_fcftab_state_xlate(fcftab->state), 3424 emlxs_fcf_event_xlate(evt), arg1); 3425 return (1); 3426 } 3427 3428 if ((fcftab->prev_state != FC_FCFTAB_STATE_CFGLINK_FAILED) || 3429 (fcftab->flag & EMLXS_FC_FCFTAB_CFGLINK_REQ)) { 3430 fcftab->flag &= ~EMLXS_FC_FCFTAB_CFGLINK_REQ; 3431 fcftab->attempts = 0; 3432 } 3433 3434 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 3435 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3436 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3437 "Handling request.", 3438 fcftab->TID, 3439 emlxs_fc_fcftab_state_xlate(fcftab->state), 3440 emlxs_fcf_event_xlate(evt), arg1, 3441 fcftab->generation, 3442 fcftab->flag); 3443 3444 rval = emlxs_fc_fcftab_req_handler(port, arg1); 3445 return (rval); 3446 } 3447 3448 if (fcftab->attempts == 0) { 3449 fcftab->TID = fcftab->generation; 3450 } 3451 3452 if (hba->topology != TOPOLOGY_LOOP) { 3453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3454 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3455 "Fabric Topology. Skipping CONFIG_LINK.", 3456 fcftab->TID, 3457 emlxs_fc_fcftab_state_xlate(fcftab->state), 3458 emlxs_fcf_event_xlate(evt), arg1, 3459 fcftab->generation, 3460 fcftab->flag); 3461 3462 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM, 3463 FCF_REASON_EVENT, evt, arg1); 3464 return (rval); 3465 } 3466 3467 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3468 "fc_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 3469 "Sending CONFIG_LINK. <", 3470 fcftab->TID, 3471 emlxs_fc_fcftab_state_xlate(fcftab->state), 3472 emlxs_fcf_event_xlate(evt), arg1, 3473 fcftab->generation, 3474 fcftab->flag); 3475 3476 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 3477 rval = emlxs_fc_fcftab_state(port, 3478 FC_FCFTAB_STATE_CFGLINK_FAILED, 3479 FCF_REASON_NO_MBOX, 0, arg1); 3480 return (rval); 3481 } 3482 mb4 = (MAILBOX4*)mbq; 3483 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 3484 3485 mbq->nonembed = NULL; 3486 mbq->mbox_cmpl = emlxs_fc_fcftab_cfglink_mbcmpl; 3487 mbq->context = (void *)((unsigned long)fcftab->TID); 3488 mbq->port = (void *)port; 3489 3490 mb4->un.varSLIConfig.be.embedded = 0; 3491 mb4->mbxCommand = MBX_CONFIG_LINK; 3492 mb4->mbxOwner = OWN_HOST; 3493 3494 if (cfg[CFG_CR_DELAY].current) { 3495 mb4->un.varCfgLnk.cr = 1; 3496 mb4->un.varCfgLnk.ci = 1; 3497 mb4->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current; 3498 mb4->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current; 3499 } 3500 3501 if (cfg[CFG_ACK0].current) { 3502 mb4->un.varCfgLnk.ack0_enable = 1; 3503 } 3504 3505 mb4->un.varCfgLnk.myId = port->did; 3506 mb4->un.varCfgLnk.edtov = hba->fc_edtov; 3507 mb4->un.varCfgLnk.arbtov = hba->fc_arbtov; 3508 mb4->un.varCfgLnk.ratov = hba->fc_ratov; 3509 mb4->un.varCfgLnk.rttov = hba->fc_rttov; 3510 mb4->un.varCfgLnk.altov = hba->fc_altov; 3511 mb4->un.varCfgLnk.crtov = hba->fc_crtov; 3512 3513 3514 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 3515 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 3516 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3517 3518 rval = emlxs_fc_fcftab_state(port, 3519 FC_FCFTAB_STATE_CFGLINK_FAILED, 3520 FCF_REASON_SEND_FAILED, rval, arg1); 3521 3522 return (rval); 3523 } 3524 3525 return (0); 3526 3527 } /* emlxs_fc_fcftab_cfglink_action() */ 3528 3529 3530 /*ARGSUSED*/ 3531 static uint32_t 3532 emlxs_fc_fcftab_cfglink_failed_action(emlxs_port_t *port, uint32_t evt, 3533 void *arg1) 3534 { 3535 emlxs_hba_t *hba = HBA; 3536 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3537 uint32_t rval = 0; 3538 3539 fcftab->attempts++; 3540 3541 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK_FAILED) { 3542 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3543 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p " 3544 "attempt=%d. Invalid state. <", 3545 fcftab->TID, 3546 emlxs_fc_fcftab_state_xlate(fcftab->state), 3547 emlxs_fcf_event_xlate(evt), 3548 arg1, fcftab->attempts); 3549 return (1); 3550 } 3551 3552 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) || 3553 (fcftab->reason == FCF_REASON_SEND_FAILED) || 3554 (fcftab->attempts >= 3)) { 3555 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3556 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p " 3557 "attempt=%d reason=%x. Giving up.", 3558 fcftab->TID, 3559 emlxs_fc_fcftab_state_xlate(fcftab->state), 3560 emlxs_fcf_event_xlate(evt), arg1, 3561 fcftab->attempts, 3562 fcftab->reason); 3563 3564 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK_CMPL, 3565 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3566 3567 } else { 3568 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3569 "fc_fcftab_cfglink_failed_action:%x %s:%s arg=%p " 3570 "attempt=%d reason=%x. Retrying.", 3571 fcftab->TID, 3572 emlxs_fc_fcftab_state_xlate(fcftab->state), 3573 emlxs_fcf_event_xlate(evt), arg1, 3574 fcftab->attempts, 3575 fcftab->reason); 3576 3577 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK, 3578 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3579 } 3580 3581 return (rval); 3582 3583 } /* emlxs_fc_fcftab_cfglink_failed_action() */ 3584 3585 3586 /*ARGSUSED*/ 3587 static uint32_t 3588 emlxs_fc_fcftab_cfglink_cmpl_action(emlxs_port_t *port, uint32_t evt, 3589 void *arg1) 3590 { 3591 emlxs_hba_t *hba = HBA; 3592 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3593 uint32_t rval = 0; 3594 3595 if (fcftab->state != FC_FCFTAB_STATE_CFGLINK_CMPL) { 3596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3597 "fc_fcftab_cfglink_cmpl_action:%x %s:%s arg=%p. " 3598 "Invalid state. <", 3599 fcftab->TID, 3600 emlxs_fc_fcftab_state_xlate(fcftab->state), 3601 emlxs_fcf_event_xlate(evt), arg1); 3602 return (1); 3603 } 3604 3605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3606 "fc_fcftab_cfglink_cmpl_action:%x attempts=%d. " 3607 "Read SPARM.", 3608 fcftab->TID, 3609 fcftab->attempts); 3610 3611 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM, 3612 FCF_REASON_EVENT, evt, arg1); 3613 3614 return (rval); 3615 3616 } /* emlxs_fc_fcftab_cfglink_cmpl_action() */ 3617 3618 3619 /*ARGSUSED*/ 3620 static uint32_t 3621 emlxs_fc_fcftab_sparm_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 3622 { 3623 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 3624 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3625 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 3626 MATCHMAP *mp; 3627 emlxs_port_t *vport; 3628 VPIobj_t *vpip; 3629 int32_t i; 3630 uint8_t null_wwn[8]; 3631 uint16_t TID; 3632 3633 mutex_enter(&EMLXS_FCF_LOCK); 3634 TID = (uint16_t)((unsigned long)mbq->context); 3635 3636 if (fcftab->state != FC_FCFTAB_STATE_SPARM) { 3637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3638 "fc_fcftab_sparm_mbcmpl:%x state=%s.", 3639 TID, 3640 emlxs_fc_fcftab_state_xlate(fcftab->state)); 3641 3642 mutex_exit(&EMLXS_FCF_LOCK); 3643 return (0); 3644 } 3645 3646 if (TID != fcftab->generation) { 3647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3648 "fc_fcftab_sparm_mbcmpl:%x %s. " 3649 "Incorrect generation %x. Dropping.", 3650 TID, 3651 emlxs_fc_fcftab_state_xlate(fcftab->state), 3652 fcftab->generation); 3653 3654 mutex_exit(&EMLXS_FCF_LOCK); 3655 return (0); 3656 } 3657 3658 if (mb4->mbxStatus) { 3659 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3660 "fc_fcftab_sparm_mbcmpl:%x failed. %s. >", 3661 fcftab->TID, 3662 emlxs_mb_xlate_status(mb4->mbxStatus)); 3663 3664 if (mb4->mbxStatus == MBXERR_NO_RESOURCES) { 3665 (void) emlxs_fc_fcftab_state(port, 3666 FC_FCFTAB_STATE_SPARM_FAILED, 3667 FCF_REASON_MBOX_BUSY, mb4->mbxStatus, 0); 3668 } else { 3669 (void) emlxs_fc_fcftab_state(port, 3670 FC_FCFTAB_STATE_SPARM_FAILED, 3671 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 3672 } 3673 3674 mutex_exit(&EMLXS_FCF_LOCK); 3675 return (0); 3676 } 3677 3678 /* Save the parameters */ 3679 mp = (MATCHMAP *)mbq->bp; 3680 bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM)); 3681 3682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3683 "fc_fcftab_sparm_mbcmpl:%x edtov=%x,%x bbc=%x. >", 3684 fcftab->TID, 3685 hba->fc_edtov, hba->sparam.cmn.e_d_tov, 3686 hba->sparam.cmn.bbCreditlsb); 3687 3688 /* Initialize the node name and port name only once */ 3689 bzero(null_wwn, 8); 3690 if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) && 3691 (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) { 3692 bcopy((caddr_t)&hba->sparam.nodeName, 3693 (caddr_t)&hba->wwnn, sizeof (NAME_TYPE)); 3694 3695 bcopy((caddr_t)&hba->sparam.portName, 3696 (caddr_t)&hba->wwpn, sizeof (NAME_TYPE)); 3697 } else { 3698 bcopy((caddr_t)&hba->wwnn, 3699 (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE)); 3700 3701 bcopy((caddr_t)&hba->wwpn, 3702 (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE)); 3703 } 3704 3705 /* Update all bound ports */ 3706 for (i = 0; i < MAX_VPORTS; i++) { 3707 vport = &VPORT(i); 3708 vpip = vport->vpip; 3709 3710 if (!(vport->flag & EMLXS_PORT_BOUND) || 3711 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 3712 continue; 3713 } 3714 3715 bcopy((caddr_t)&hba->sparam, 3716 (caddr_t)&vport->sparam, 3717 sizeof (SERV_PARM)); 3718 3719 bcopy((caddr_t)&vport->wwnn, 3720 (caddr_t)&vport->sparam.nodeName, 3721 sizeof (NAME_TYPE)); 3722 3723 bcopy((caddr_t)&vport->wwpn, 3724 (caddr_t)&vport->sparam.portName, 3725 sizeof (NAME_TYPE)); 3726 } 3727 3728 (void) emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM_CMPL, 3729 0, 0, 0); 3730 3731 mutex_exit(&EMLXS_FCF_LOCK); 3732 return (0); 3733 3734 } /* emlxs_fc_fcftab_sparm_mbcmpl() */ 3735 3736 3737 /*ARGSUSED*/ 3738 static uint32_t 3739 emlxs_fc_fcftab_sparm_action(emlxs_port_t *port, uint32_t evt, 3740 void *arg1) 3741 { 3742 emlxs_hba_t *hba = HBA; 3743 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3744 MAILBOXQ *mbq; 3745 MAILBOX4 *mb4; 3746 uint32_t rval = 0; 3747 MATCHMAP *mp; 3748 3749 if (fcftab->state != FC_FCFTAB_STATE_SPARM) { 3750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3751 "fc_fcftab_sparm_action:%x %s:%s arg=%p. " 3752 "Invalid state. <", 3753 fcftab->TID, 3754 emlxs_fc_fcftab_state_xlate(fcftab->state), 3755 emlxs_fcf_event_xlate(evt), arg1); 3756 return (1); 3757 } 3758 3759 if ((fcftab->prev_state != FC_FCFTAB_STATE_SPARM_FAILED) || 3760 (fcftab->flag & EMLXS_FC_FCFTAB_SPARM_REQ)) { 3761 fcftab->flag &= ~EMLXS_FC_FCFTAB_SPARM_REQ; 3762 fcftab->attempts = 0; 3763 } 3764 3765 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 3766 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3767 "fc_fcftab_read_action:%x %s:%s arg=%p flag=%x. " 3768 "Handling request.", 3769 fcftab->TID, 3770 emlxs_fc_fcftab_state_xlate(fcftab->state), 3771 emlxs_fcf_event_xlate(evt), arg1, 3772 fcftab->flag); 3773 3774 rval = emlxs_fc_fcftab_req_handler(port, arg1); 3775 return (rval); 3776 } 3777 3778 if (fcftab->attempts == 0) { 3779 fcftab->TID = fcftab->generation; 3780 } 3781 3782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3783 "fc_fcftab_read_action:%x %s:%s arg=%p attempts=%d. " 3784 "Reading SPARM. <", 3785 fcftab->TID, 3786 emlxs_fc_fcftab_state_xlate(fcftab->state), 3787 emlxs_fcf_event_xlate(evt), arg1, 3788 fcftab->attempts); 3789 3790 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 3791 rval = emlxs_fc_fcftab_state(port, 3792 FC_FCFTAB_STATE_SPARM_FAILED, 3793 FCF_REASON_NO_MBOX, 0, arg1); 3794 return (rval); 3795 } 3796 mb4 = (MAILBOX4*)mbq; 3797 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 3798 3799 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 3800 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3801 3802 rval = emlxs_fc_fcftab_state(port, 3803 FC_FCFTAB_STATE_SPARM_FAILED, 3804 FCF_REASON_NO_BUFFER, 0, arg1); 3805 return (rval); 3806 } 3807 bzero(mp->virt, mp->size); 3808 3809 mbq->nonembed = NULL; 3810 mbq->bp = (void *)mp; 3811 mbq->mbox_cmpl = emlxs_fc_fcftab_sparm_mbcmpl; 3812 mbq->context = (void *)((unsigned long)fcftab->TID); 3813 mbq->port = (void *)port; 3814 3815 mb4->un.varSLIConfig.be.embedded = 0; 3816 mb4->mbxCommand = MBX_READ_SPARM64; 3817 mb4->mbxOwner = OWN_HOST; 3818 3819 mb4->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 3820 mb4->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys); 3821 mb4->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys); 3822 3823 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 3824 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 3825 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 3826 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 3827 3828 rval = emlxs_fc_fcftab_state(port, 3829 FC_FCFTAB_STATE_SPARM_FAILED, 3830 FCF_REASON_SEND_FAILED, rval, arg1); 3831 3832 return (rval); 3833 } 3834 3835 return (0); 3836 3837 } /* emlxs_fc_fcftab_sparm_action() */ 3838 3839 3840 /*ARGSUSED*/ 3841 static uint32_t 3842 emlxs_fc_fcftab_sparm_failed_action(emlxs_port_t *port, uint32_t evt, 3843 void *arg1) 3844 { 3845 emlxs_hba_t *hba = HBA; 3846 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3847 uint32_t rval = 0; 3848 3849 fcftab->attempts++; 3850 3851 if (fcftab->state != FC_FCFTAB_STATE_SPARM_FAILED) { 3852 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3853 "fc_fcftab_sparm_failed_action:%x %s:%s arg=%p " 3854 "attempt=%d. Invalid state. <", 3855 fcftab->TID, 3856 emlxs_fc_fcftab_state_xlate(fcftab->state), 3857 emlxs_fcf_event_xlate(evt), 3858 arg1, fcftab->attempts); 3859 return (1); 3860 } 3861 3862 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) || 3863 (fcftab->reason == FCF_REASON_SEND_FAILED) || 3864 (fcftab->attempts >= 3)) { 3865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3866 "fc_fcftab_read_failed_action:%x %s:%s arg=%p " 3867 "attempt=%d reason=%x. Giving up.", 3868 fcftab->TID, 3869 emlxs_fc_fcftab_state_xlate(fcftab->state), 3870 emlxs_fcf_event_xlate(evt), arg1, 3871 fcftab->attempts, 3872 fcftab->reason); 3873 3874 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM_CMPL, 3875 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3876 } else { 3877 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3878 "fc_fcftab_read_failed_action:%x %s:%s arg=%p " 3879 "attempt=%d reason=%x. Retrying.", 3880 fcftab->TID, 3881 emlxs_fc_fcftab_state_xlate(fcftab->state), 3882 emlxs_fcf_event_xlate(evt), arg1, 3883 fcftab->attempts, 3884 fcftab->reason); 3885 3886 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM, 3887 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 3888 } 3889 3890 return (rval); 3891 3892 } /* emlxs_fc_fcftab_sparm_failed_action() */ 3893 3894 3895 /*ARGSUSED*/ 3896 static uint32_t 3897 emlxs_fc_fcftab_sparm_cmpl_action(emlxs_port_t *port, uint32_t evt, 3898 void *arg1) 3899 { 3900 emlxs_hba_t *hba = HBA; 3901 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3902 uint32_t rval = 0; 3903 3904 if (fcftab->state != FC_FCFTAB_STATE_SPARM_CMPL) { 3905 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 3906 "fc_fcftab_sparm_cmpl_action:%x %s:%s arg=%p. " 3907 "Invalid state. <", 3908 fcftab->TID, 3909 emlxs_fc_fcftab_state_xlate(fcftab->state), 3910 emlxs_fcf_event_xlate(evt), arg1); 3911 return (1); 3912 } 3913 3914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3915 "fc_fcftab_sparm_cmpl_action:%x attempts=%d. " 3916 "Bring FCFTAB online.", 3917 fcftab->TID, 3918 fcftab->attempts); 3919 3920 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE, 3921 FCF_REASON_EVENT, evt, arg1); 3922 3923 return (rval); 3924 3925 } /* emlxs_fc_fcftab_sparm_cmpl_action() */ 3926 3927 3928 /*ARGSUSED*/ 3929 static void 3930 emlxs_fc_fcftab_process(emlxs_port_t *port) 3931 { 3932 emlxs_hba_t *hba = HBA; 3933 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 3934 FCFIobj_t *fcfp; 3935 FCF_RECORD_t fcf_record; 3936 FCF_RECORD_t *fcf_rec; 3937 uint8_t bitmap[512]; 3938 uint16_t i; 3939 3940 /* Get the FCFI */ 3941 fcfp = fcftab->fcfi[0]; 3942 3943 if (!fcfp) { 3944 /* Allocate an fcfi */ 3945 fcfp = emlxs_fcfi_alloc(port); 3946 } 3947 3948 if (!fcfp) { 3949 fcftab->fcfi_count = 0; 3950 3951 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3952 "fc_fcftab_process:%x No FCF available.", 3953 fcftab->TID); 3954 return; 3955 } 3956 3957 if (fcfp->flag & EMLXS_FCFI_SELECTED) { 3958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3959 "fc_fcftab_process:%x fcfi=%d %s. " 3960 "FCF still selected.", 3961 fcftab->TID, 3962 fcfp->fcf_index, 3963 emlxs_fcfi_state_xlate(fcfp->state)); 3964 } else { 3965 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 3966 "fc_fcftab_process:%x fcfi=%d %s. " 3967 "New FCF selected.", 3968 fcftab->TID, 3969 fcfp->fcf_index, 3970 emlxs_fcfi_state_xlate(fcfp->state)); 3971 } 3972 3973 /* Initalize an fcf_rec */ 3974 fcf_rec = &fcf_record; 3975 bzero(fcf_rec, sizeof (FCF_RECORD_t)); 3976 3977 fcf_rec->max_recv_size = EMLXS_FCOE_MAX_RCV_SZ; 3978 fcf_rec->fka_adv_period = 0; 3979 fcf_rec->fip_priority = 128; 3980 3981 #ifdef EMLXS_BIG_ENDIAN 3982 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC3; 3983 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC2; 3984 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC1; 3985 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC0; 3986 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC5; 3987 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC4; 3988 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[2]; 3989 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1]; 3990 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[0]; 3991 #endif /* EMLXS_BIG_ENDIAN */ 3992 #ifdef EMLXS_LITTLE_ENDIAN 3993 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC0; 3994 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC1; 3995 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC2; 3996 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC3; 3997 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC4; 3998 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC5; 3999 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[0]; 4000 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1]; 4001 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[2]; 4002 #endif /* EMLXS_LITTLE_ENDIAN */ 4003 4004 if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) { 4005 bzero((void *) bitmap, 512); 4006 i = hba->sli.sli4.cfgFCOE.VLanId; 4007 bitmap[i / 8] = (1 << (i % 8)); 4008 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512); 4009 } else { 4010 bzero((void *) bitmap, 512); 4011 bitmap[0] = 1; /* represents bit 0 */ 4012 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512); 4013 } 4014 4015 fcf_rec->fcf_valid = 1; 4016 fcf_rec->fcf_available = 1; 4017 4018 /* Update the FCFI */ 4019 emlxs_fcfi_update(port, fcfp, fcf_rec, hba->link_event_tag); 4020 4021 /* Select the FCFI */ 4022 fcfp->flag &= ~EMLXS_FCFI_FAILED; 4023 fcfp->flag |= EMLXS_FCFI_SELECTED; 4024 fcftab->fcfi[0] = fcfp; 4025 fcftab->fcfi_count = 1; 4026 4027 return; 4028 4029 } /* emlxs_fc_fcftab_process() */ 4030 4031 4032 /*ARGSUSED*/ 4033 static uint32_t 4034 emlxs_fc_fcftab_fcfi_online_action(emlxs_port_t *port, uint32_t evt, 4035 void *arg1) 4036 { 4037 emlxs_hba_t *hba = HBA; 4038 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4039 uint32_t rval = 0; 4040 FCFIobj_t *fcfp; 4041 4042 if (fcftab->state != FC_FCFTAB_STATE_FCFI_ONLINE) { 4043 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4044 "fc_fcftab_fcfi_online_action:%x %s:%s arg=%p. " 4045 "Invalid state. <", 4046 fcftab->TID, 4047 emlxs_fc_fcftab_state_xlate(fcftab->state), 4048 emlxs_fcf_event_xlate(evt), arg1); 4049 return (1); 4050 } 4051 4052 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 4053 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4054 "fc_fcftab_fcfi_online_action:%x flag=%x. " 4055 "Handling request.", 4056 fcftab->TID, 4057 fcftab->flag); 4058 4059 rval = emlxs_fc_fcftab_req_handler(port, arg1); 4060 return (rval); 4061 } 4062 4063 emlxs_fc_fcftab_process(port); 4064 4065 fcfp = fcftab->fcfi[0]; 4066 if (!fcfp) { 4067 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4068 "fc_fcftab_fcfi_online_action:%x. " 4069 "No FCF available. Offlining.", 4070 fcftab->TID); 4071 4072 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 4073 fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ; 4074 rval = emlxs_fc_fcftab_req_handler(port, arg1); 4075 4076 mutex_exit(&EMLXS_FCF_LOCK); 4077 return (rval); 4078 } 4079 4080 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4081 "fc_fcftab_fcfi_online_action:%x fcfi_count=%d. " 4082 "Onlining FCFI:%d. >", 4083 fcftab->TID, 4084 fcftab->fcfi_count, 4085 fcfp->fcf_index); 4086 4087 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_ONLINE, fcfp); 4088 4089 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE_CMPL, 4090 FCF_REASON_EVENT, evt, arg1); 4091 4092 return (rval); 4093 4094 } /* emlxs_fc_fcftab_fcfi_online_action() */ 4095 4096 4097 /*ARGSUSED*/ 4098 static uint32_t 4099 emlxs_fc_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, uint32_t evt, 4100 void *arg1) 4101 { 4102 emlxs_hba_t *hba = HBA; 4103 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4104 uint32_t rval = 0; 4105 4106 if (fcftab->state != FC_FCFTAB_STATE_FCFI_ONLINE_CMPL) { 4107 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4108 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. " 4109 "Invalid state. <", 4110 fcftab->TID, 4111 emlxs_fc_fcftab_state_xlate(fcftab->state), 4112 emlxs_fcf_event_xlate(evt), arg1); 4113 return (1); 4114 } 4115 4116 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 4117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4118 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p " 4119 "flag=%x. Handling request.", 4120 fcftab->TID, 4121 emlxs_fc_fcftab_state_xlate(fcftab->state), 4122 emlxs_fcf_event_xlate(evt), arg1, 4123 fcftab->flag); 4124 4125 rval = emlxs_fc_fcftab_req_handler(port, arg1); 4126 return (rval); 4127 } 4128 4129 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4130 "fc_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. " 4131 "Going online.", 4132 fcftab->TID, 4133 emlxs_fc_fcftab_state_xlate(fcftab->state), 4134 emlxs_fcf_event_xlate(evt), arg1); 4135 4136 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_ONLINE, 4137 FCF_REASON_EVENT, evt, arg1); 4138 4139 return (rval); 4140 4141 } /* emlxs_fc_fcftab_fcfi_online_cmpl_action() */ 4142 4143 4144 /*ARGSUSED*/ 4145 static uint32_t 4146 emlxs_fc_fcftab_fcfi_offline_action(emlxs_port_t *port, uint32_t evt, 4147 void *arg1) 4148 { 4149 emlxs_hba_t *hba = HBA; 4150 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4151 uint32_t rval = 0; 4152 FCFIobj_t *fcfp; 4153 4154 if (fcftab->state != FC_FCFTAB_STATE_FCFI_OFFLINE) { 4155 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4156 "fc_fcftab_fcftab_offline_action:%x %s:%s arg=%p. " 4157 "Invalid state. <", 4158 fcftab->TID, 4159 emlxs_fc_fcftab_state_xlate(fcftab->state), 4160 emlxs_fcf_event_xlate(evt), arg1); 4161 return (1); 4162 } 4163 4164 if (fcftab->fcfi_online) { 4165 fcfp = fcftab->fcfi[0]; 4166 4167 if (!(fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) { 4168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4169 "fc_fcftab_fcfi_offline_action:%d. " 4170 "Offlining FCFI:%d. >", 4171 fcftab->TID, 4172 fcfp->fcf_index); 4173 4174 rval = emlxs_fcfi_event(port, 4175 FCF_EVENT_FCFI_OFFLINE, fcfp); 4176 4177 return (rval); 4178 } 4179 4180 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4181 "fc_fcftab_fcfi_offline_action:%x fcfi_online=%d. " 4182 "Waiting on FCF. <", 4183 fcftab->TID, 4184 fcftab->fcfi_online); 4185 4186 return (0); 4187 } 4188 4189 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4190 "fc_fcftab_fcfi_offline_action:%x %s:%s arg=%p.", 4191 fcftab->TID, 4192 emlxs_fc_fcftab_state_xlate(fcftab->state), 4193 emlxs_fcf_event_xlate(evt), arg1); 4194 4195 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL, 4196 FCF_REASON_EVENT, evt, arg1); 4197 4198 return (rval); 4199 4200 } /* emlxs_fc_fcftab_fcfi_offline_action() */ 4201 4202 4203 /*ARGSUSED*/ 4204 static uint32_t 4205 emlxs_fc_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, uint32_t evt, 4206 void *arg1) 4207 { 4208 emlxs_hba_t *hba = HBA; 4209 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4210 uint32_t rval = 0; 4211 4212 if (fcftab->state != FC_FCFTAB_STATE_FCFI_OFFLINE_CMPL) { 4213 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4214 "fc_fcftab_fcftab_offline_cmpl_action:%x %s:%s arg=%p. " 4215 "Invalid state. <", 4216 fcftab->TID, 4217 emlxs_fc_fcftab_state_xlate(fcftab->state), 4218 emlxs_fcf_event_xlate(evt), arg1); 4219 return (1); 4220 } 4221 4222 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 4223 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4224 "fc_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. " 4225 "Handling request.", 4226 fcftab->TID, 4227 emlxs_fc_fcftab_state_xlate(fcftab->state), 4228 emlxs_fcf_event_xlate(evt), arg1); 4229 4230 rval = emlxs_fc_fcftab_req_handler(port, arg1); 4231 return (rval); 4232 } 4233 4234 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4235 "fc_fcftab_fcftab_offline_cmpl_action:%x %s:%s arg=%p. " 4236 "Returning FCF(s) online.", 4237 fcftab->TID, 4238 emlxs_fc_fcftab_state_xlate(fcftab->state), 4239 emlxs_fcf_event_xlate(evt), arg1); 4240 4241 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE, 4242 FCF_REASON_EVENT, evt, arg1); 4243 4244 return (rval); 4245 4246 } /* emlxs_fc_fcftab_fcfi_offline_cmpl_action() */ 4247 4248 4249 /*ARGSUSED*/ 4250 static uint32_t 4251 emlxs_fc_fcftab_linkup_evt_action(emlxs_port_t *port, uint32_t evt, 4252 void *arg1) 4253 { 4254 emlxs_hba_t *hba = HBA; 4255 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4256 uint32_t rval = 0; 4257 4258 if (evt != FCF_EVENT_LINKUP) { 4259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4260 "fc_fcftab_linkup_evt_action:%x %s:%s arg=%p flag=%x. " 4261 "Invalid event type. <", 4262 fcftab->TID, 4263 emlxs_fc_fcftab_state_xlate(fcftab->state), 4264 emlxs_fcf_event_xlate(evt), arg1, 4265 fcftab->flag); 4266 return (1); 4267 } 4268 4269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4270 "fc_fcftab_linkup_evt_action:%x %s:%s arg=%p gen=%x. Link up.", 4271 fcftab->TID, 4272 emlxs_fc_fcftab_state_xlate(fcftab->state), 4273 emlxs_fcf_event_xlate(evt), arg1, 4274 fcftab->generation); 4275 4276 emlxs_fcf_linkup(port); 4277 4278 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 4279 fcftab->flag |= EMLXS_FC_FCFTAB_TOPO_REQ; 4280 fcftab->generation++; 4281 4282 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4283 "fc_fcftab_linkup_evt_action:%x %s gen=%x. " 4284 "Read topology.", 4285 fcftab->TID, 4286 emlxs_fc_fcftab_state_xlate(fcftab->state), 4287 fcftab->generation); 4288 4289 switch (fcftab->state) { 4290 case FC_FCFTAB_STATE_TOPO: 4291 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO, 4292 FCF_REASON_REENTER, evt, arg1); 4293 break; 4294 4295 default: 4296 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO, 4297 FCF_REASON_EVENT, evt, arg1); 4298 break; 4299 } 4300 4301 return (rval); 4302 4303 } /* emlxs_fc_fcftab_linkup_evt_action() */ 4304 4305 4306 /*ARGSUSED*/ 4307 static uint32_t 4308 emlxs_fc_fcftab_linkdown_evt_action(emlxs_port_t *port, uint32_t evt, 4309 void *arg1) 4310 { 4311 emlxs_hba_t *hba = HBA; 4312 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4313 uint32_t rval = 0; 4314 uint32_t i; 4315 FCFIobj_t *fcfp; 4316 4317 if (evt != FCF_EVENT_LINKDOWN) { 4318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4319 "fc_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. " 4320 "Invalid event type. <", 4321 fcftab->TID, 4322 emlxs_fc_fcftab_state_xlate(fcftab->state), 4323 emlxs_fcf_event_xlate(evt), arg1, 4324 fcftab->flag); 4325 return (1); 4326 } 4327 4328 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 4329 fcftab->flag |= EMLXS_FC_FCFTAB_OFFLINE_REQ; 4330 4331 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4332 "fc_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. Linkdown.", 4333 fcftab->TID, 4334 emlxs_fc_fcftab_state_xlate(fcftab->state), 4335 emlxs_fcf_event_xlate(evt), arg1, 4336 fcftab->flag); 4337 4338 emlxs_fcf_linkdown(port); 4339 4340 /* Pause all active FCFI's */ 4341 for (i = 0; i < fcftab->fcfi_count; i++) { 4342 fcfp = fcftab->fcfi[i]; 4343 4344 if ((fcfp->state == FCFI_STATE_OFFLINE) || 4345 (fcfp->state == FCFI_STATE_PAUSED)) { 4346 break; 4347 } 4348 4349 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4350 "fc_fcftab_linkdown_evt_action:%x. " 4351 "Pausing FCFI:%d. >", 4352 fcftab->TID, 4353 fcfp->fcf_index); 4354 4355 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_PAUSE, fcfp); 4356 } 4357 4358 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4359 "fc_fcftab_linkdown_evt_action:%x " 4360 "Going offline.", 4361 fcftab->TID); 4362 4363 switch (fcftab->state) { 4364 case FC_FCFTAB_STATE_OFFLINE: 4365 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE, 4366 FCF_REASON_REENTER, evt, arg1); 4367 break; 4368 4369 default: 4370 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE, 4371 FCF_REASON_EVENT, evt, arg1); 4372 break; 4373 } 4374 4375 return (rval); 4376 4377 } /* emlxs_fc_fcftab_linkdown_evt_action() */ 4378 4379 4380 /*ARGSUSED*/ 4381 static uint32_t 4382 emlxs_fc_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, uint32_t evt, 4383 void *arg1) 4384 { 4385 emlxs_hba_t *hba = HBA; 4386 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4387 uint32_t rval = 0; 4388 FCFIobj_t *fcfp; 4389 4390 if (evt != FCF_EVENT_FCFI_OFFLINE) { 4391 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4392 "fc_fcftab_fcftab_offline_evt_action:%x %s:%s arg=%p " 4393 "flag=%x. Invalid event type. <", 4394 fcftab->TID, 4395 emlxs_fc_fcftab_state_xlate(fcftab->state), 4396 emlxs_fcf_event_xlate(evt), arg1, 4397 fcftab->flag); 4398 return (1); 4399 } 4400 4401 fcfp = (FCFIobj_t *)arg1; 4402 4403 switch (fcftab->state) { 4404 case FC_FCFTAB_STATE_SHUTDOWN: 4405 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4406 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. " 4407 "Shutting down.", 4408 fcftab->TID, 4409 fcfp->fcf_index); 4410 4411 /* This will trigger final shutdown */ 4412 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SHUTDOWN, 4413 FCF_REASON_REENTER, evt, arg1); 4414 break; 4415 4416 case FC_FCFTAB_STATE_FCFI_OFFLINE: 4417 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4418 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. Offlining.", 4419 fcftab->TID, 4420 fcfp->fcf_index); 4421 4422 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_OFFLINE, 4423 FCF_REASON_REENTER, evt, arg1); 4424 break; 4425 4426 case FC_FCFTAB_STATE_FCFI_ONLINE: 4427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4428 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d. " 4429 "Retrying FCF.", 4430 fcftab->TID, 4431 fcfp->fcf_index); 4432 4433 fcfp->flag |= EMLXS_FCFI_FAILED; 4434 4435 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_FCFI_ONLINE, 4436 FCF_REASON_REENTER, evt, arg1); 4437 break; 4438 4439 case FC_FCFTAB_STATE_ONLINE: 4440 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4441 "fc_fcftab_fcfi_offline_evt_action:%x fcfi:%d.", 4442 fcftab->TID, 4443 fcfp->fcf_index); 4444 4445 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_ONLINE, 4446 FCF_REASON_REENTER, evt, arg1); 4447 break; 4448 4449 default: 4450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4451 "fc_fcftab_fcfi_offline_evt_action:%x %s fcfi:%d.", 4452 fcftab->TID, 4453 emlxs_fc_fcftab_state_xlate(fcftab->state), 4454 fcfp->fcf_index); 4455 break; 4456 } 4457 4458 return (rval); 4459 4460 } /* emlxs_fc_fcftab_fcfi_offline_evt_action() */ 4461 4462 4463 /*ARGSUSED*/ 4464 static uint32_t 4465 emlxs_fc_fcftab_fcfi_online_evt_action(emlxs_port_t *port, uint32_t evt, 4466 void *arg1) 4467 { 4468 emlxs_hba_t *hba = HBA; 4469 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4470 uint32_t rval = 0; 4471 FCFIobj_t *fcfp; 4472 4473 if (evt != FCF_EVENT_FCFI_ONLINE) { 4474 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4475 "fc_fcftab_fcftab_online_evt_action:%x %s:%s arg=%p " 4476 "flag=%x. Invalid event type. <", 4477 fcftab->TID, 4478 emlxs_fc_fcftab_state_xlate(fcftab->state), 4479 emlxs_fcf_event_xlate(evt), arg1, 4480 fcftab->flag); 4481 return (1); 4482 } 4483 4484 fcfp = (FCFIobj_t *)arg1; 4485 4486 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4487 "fc_fcftab_fcfi_online_evt_action:%d fcfi:%d. <", 4488 fcftab->TID, 4489 fcfp->fcf_index); 4490 4491 return (rval); 4492 4493 } /* emlxs_fc_fcftab_fcfi_online_evt_action() */ 4494 4495 4496 /*ARGSUSED*/ 4497 static uint32_t 4498 emlxs_fc_fcftab_shutdown_evt_action(emlxs_port_t *port, uint32_t evt, 4499 void *arg1) 4500 { 4501 emlxs_hba_t *hba = HBA; 4502 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4503 uint32_t rval = 0; 4504 4505 if (evt != FCF_EVENT_SHUTDOWN) { 4506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4507 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 4508 "Invalid event type. <", 4509 fcftab->TID, 4510 emlxs_fc_fcftab_state_xlate(fcftab->state), 4511 emlxs_fcf_event_xlate(evt), arg1, 4512 fcftab->flag); 4513 return (1); 4514 } 4515 4516 if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) { 4517 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4518 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 4519 "Already shut down. <", 4520 fcftab->TID, 4521 emlxs_fc_fcftab_state_xlate(fcftab->state), 4522 emlxs_fcf_event_xlate(evt), arg1, 4523 fcftab->flag); 4524 return (1); 4525 } 4526 4527 if (fcftab->state == FC_FCFTAB_STATE_SHUTDOWN) { 4528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4529 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 4530 "Already shutting down. <", 4531 fcftab->TID, 4532 emlxs_fc_fcftab_state_xlate(fcftab->state), 4533 emlxs_fcf_event_xlate(evt), arg1, 4534 fcftab->flag); 4535 return (1); 4536 } 4537 4538 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4539 "fc_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 4540 "Shutting down.", 4541 fcftab->TID, 4542 emlxs_fc_fcftab_state_xlate(fcftab->state), 4543 emlxs_fcf_event_xlate(evt), arg1, 4544 fcftab->flag); 4545 4546 emlxs_fcf_linkdown(port); 4547 4548 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SHUTDOWN, 4549 FCF_REASON_EVENT, evt, arg1); 4550 4551 return (rval); 4552 4553 } /* emlxs_fc_fcftab_shutdown_evt_action() */ 4554 4555 4556 static uint32_t 4557 emlxs_fc_fcftab_req_handler(emlxs_port_t *port, void *arg1) 4558 { 4559 emlxs_hba_t *hba = HBA; 4560 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4561 uint32_t rval = 0; 4562 4563 if (!(fcftab->flag & EMLXS_FCFTAB_REQ_MASK)) { 4564 return (1); 4565 } 4566 4567 if (fcftab->flag & EMLXS_FC_FCFTAB_OFFLINE_REQ) { 4568 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_OFFLINE, 4569 FCF_REASON_REQUESTED, 0, arg1); 4570 } 4571 4572 else if (fcftab->flag & EMLXS_FC_FCFTAB_TOPO_REQ) { 4573 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_TOPO, 4574 FCF_REASON_REQUESTED, 0, arg1); 4575 } 4576 4577 else if (fcftab->flag & EMLXS_FC_FCFTAB_CFGLINK_REQ) { 4578 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_CFGLINK, 4579 FCF_REASON_REQUESTED, 0, arg1); 4580 } 4581 4582 else if (fcftab->flag & EMLXS_FC_FCFTAB_SPARM_REQ) { 4583 rval = emlxs_fc_fcftab_state(port, FC_FCFTAB_STATE_SPARM, 4584 FCF_REASON_REQUESTED, 0, arg1); 4585 } 4586 4587 return (rval); 4588 4589 } /* emlxs_fc_fcftab_req_handler() */ 4590 4591 4592 4593 /* ************************************************************************** */ 4594 /* FCOE FCFTAB */ 4595 /* ************************************************************************** */ 4596 4597 static char * 4598 emlxs_fcoe_fcftab_state_xlate(uint32_t state) 4599 { 4600 static char buffer[32]; 4601 uint32_t i; 4602 uint32_t count; 4603 4604 count = sizeof (emlxs_fcoe_fcftab_state_table) / sizeof (emlxs_table_t); 4605 for (i = 0; i < count; i++) { 4606 if (state == emlxs_fcoe_fcftab_state_table[i].code) { 4607 return (emlxs_fcoe_fcftab_state_table[i].string); 4608 } 4609 } 4610 4611 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 4612 return (buffer); 4613 4614 } /* emlxs_fcoe_fcftab_state_xlate() */ 4615 4616 4617 static uint32_t 4618 emlxs_fcoe_fcftab_action(emlxs_port_t *port, uint32_t evt, 4619 void *arg1) 4620 { 4621 emlxs_hba_t *hba = HBA; 4622 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4623 uint32_t rval = 0; 4624 uint32_t(*func) (emlxs_port_t *, uint32_t, void *); 4625 uint32_t index; 4626 uint32_t events; 4627 uint16_t state; 4628 4629 /* Convert event to action table index */ 4630 switch (evt) { 4631 case FCF_EVENT_STATE_ENTER: 4632 index = 0; 4633 break; 4634 case FCF_EVENT_SHUTDOWN: 4635 index = 1; 4636 break; 4637 case FCF_EVENT_LINKUP: 4638 index = 2; 4639 break; 4640 case FCF_EVENT_LINKDOWN: 4641 index = 3; 4642 break; 4643 case FCF_EVENT_CVL: 4644 index = 4; 4645 break; 4646 case FCF_EVENT_FCF_FOUND: 4647 index = 5; 4648 break; 4649 case FCF_EVENT_FCF_LOST: 4650 index = 6; 4651 break; 4652 case FCF_EVENT_FCF_CHANGED: 4653 index = 7; 4654 break; 4655 case FCF_EVENT_FCFTAB_FULL: 4656 index = 8; 4657 break; 4658 case FCF_EVENT_FCFI_ONLINE: 4659 index = 9; 4660 break; 4661 case FCF_EVENT_FCFI_OFFLINE: 4662 index = 10; 4663 break; 4664 default: 4665 return (1); 4666 } 4667 4668 events = FCOE_FCFTAB_ACTION_EVENTS; 4669 state = fcftab->state; 4670 4671 index += (state * events); 4672 func = (uint32_t(*) (emlxs_port_t *, uint32_t, void *)) 4673 emlxs_fcoe_fcftab_action_table[index]; 4674 4675 if (!func) { 4676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 4677 "fcoe_fcftab_action:%x %s:%s arg=%p. No action. <", 4678 fcftab->TID, 4679 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4680 emlxs_fcf_event_xlate(evt), arg1); 4681 4682 return (1); 4683 } 4684 4685 rval = (func)(port, evt, arg1); 4686 4687 return (rval); 4688 4689 } /* emlxs_fcoe_fcftab_action() */ 4690 4691 4692 static uint32_t 4693 emlxs_fcoe_fcftab_event(emlxs_port_t *port, uint32_t evt, 4694 void *arg1) 4695 { 4696 emlxs_hba_t *hba = HBA; 4697 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4698 uint32_t rval = 0; 4699 4700 /* Filter events */ 4701 switch (evt) { 4702 case FCF_EVENT_SHUTDOWN: 4703 case FCF_EVENT_LINKUP: 4704 case FCF_EVENT_LINKDOWN: 4705 case FCF_EVENT_CVL: 4706 case FCF_EVENT_FCF_FOUND: 4707 case FCF_EVENT_FCF_LOST: 4708 case FCF_EVENT_FCF_CHANGED: 4709 case FCF_EVENT_FCFTAB_FULL: 4710 case FCF_EVENT_FCFI_OFFLINE: 4711 case FCF_EVENT_FCFI_ONLINE: 4712 break; 4713 4714 default: 4715 return (1); 4716 } 4717 4718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 4719 "fcoe_fcftab_event:%x %s:%s arg=%p.", 4720 fcftab->TID, 4721 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4722 emlxs_fcf_event_xlate(evt), arg1); 4723 4724 rval = emlxs_fcoe_fcftab_action(port, evt, arg1); 4725 4726 return (rval); 4727 4728 } /* emlxs_fcoe_fcftab_event() */ 4729 4730 4731 /* EMLXS_FCF_LOCK must be held to enter */ 4732 /*ARGSUSED*/ 4733 static uint32_t 4734 emlxs_fcoe_fcftab_state(emlxs_port_t *port, uint16_t state, uint16_t reason, 4735 uint32_t explain, void *arg1) 4736 { 4737 emlxs_hba_t *hba = HBA; 4738 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4739 uint32_t rval = 0; 4740 4741 if (state >= FCOE_FCFTAB_ACTION_STATES) { 4742 return (1); 4743 } 4744 4745 if ((fcftab->state == state) && 4746 (reason != FCF_REASON_REENTER)) { 4747 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4748 "fcftab_state:%x %s:%s:0x%x arg=%p. " 4749 "State not changed. <", 4750 fcftab->TID, 4751 emlxs_fcoe_fcftab_state_xlate(state), 4752 emlxs_fcf_reason_xlate(reason), 4753 explain, arg1); 4754 return (1); 4755 } 4756 4757 if (!reason) { 4758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 4759 "fcftab_state:%x %s-->%s arg=%p", 4760 fcftab->TID, 4761 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4762 emlxs_fcoe_fcftab_state_xlate(state), arg1); 4763 } else if (reason == FCF_REASON_EVENT) { 4764 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 4765 "fcftab_state:%x %s-->%s:%s:%s arg=%p", 4766 fcftab->TID, 4767 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4768 emlxs_fcoe_fcftab_state_xlate(state), 4769 emlxs_fcf_reason_xlate(reason), 4770 emlxs_fcf_event_xlate(explain), arg1); 4771 } else if (explain) { 4772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 4773 "fcftab_state:%x %s-->%s:%s:0x%x arg=%p", 4774 fcftab->TID, 4775 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4776 emlxs_fcoe_fcftab_state_xlate(state), 4777 emlxs_fcf_reason_xlate(reason), 4778 explain, arg1); 4779 } else { 4780 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 4781 "fcftab_state:%x %s-->%s:%s arg=%p", 4782 fcftab->TID, 4783 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4784 emlxs_fcoe_fcftab_state_xlate(state), 4785 emlxs_fcf_reason_xlate(reason), arg1); 4786 } 4787 4788 fcftab->prev_state = fcftab->state; 4789 fcftab->prev_reason = fcftab->reason; 4790 fcftab->state = state; 4791 fcftab->reason = reason; 4792 4793 rval = emlxs_fcoe_fcftab_action(port, FCF_EVENT_STATE_ENTER, arg1); 4794 4795 return (rval); 4796 4797 } /* emlxs_fcoe_fcftab_state() */ 4798 4799 4800 /*ARGSUSED*/ 4801 static uint32_t 4802 emlxs_fcoe_fcftab_fcfi_offline_evt_action(emlxs_port_t *port, uint32_t evt, 4803 void *arg1) 4804 { 4805 emlxs_hba_t *hba = HBA; 4806 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4807 uint32_t rval = 0; 4808 FCFIobj_t *fcfp; 4809 4810 if (evt != FCF_EVENT_FCFI_OFFLINE) { 4811 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4812 "fcoe_fcftab_fcfi_offline_evt_action:%x %s:%s arg=%p " 4813 "flag=%x. Invalid event type. <", 4814 fcftab->TID, 4815 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4816 emlxs_fcf_event_xlate(evt), arg1, 4817 fcftab->flag); 4818 return (1); 4819 } 4820 4821 fcfp = (FCFIobj_t *)arg1; 4822 4823 switch (fcftab->state) { 4824 case FCOE_FCFTAB_STATE_SHUTDOWN: 4825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4826 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. " 4827 "Shutting down.", 4828 fcftab->TID, 4829 fcfp->fcf_index); 4830 4831 /* This will trigger final shutdown */ 4832 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SHUTDOWN, 4833 FCF_REASON_REENTER, evt, arg1); 4834 break; 4835 4836 case FCOE_FCFTAB_STATE_FCFI_OFFLINE: 4837 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4838 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. " 4839 "Offlining.", 4840 fcftab->TID, 4841 fcfp->fcf_index); 4842 4843 rval = emlxs_fcoe_fcftab_state(port, 4844 FCOE_FCFTAB_STATE_FCFI_OFFLINE, 4845 FCF_REASON_REENTER, evt, arg1); 4846 break; 4847 4848 case FCOE_FCFTAB_STATE_FCFI_ONLINE: 4849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4850 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d. " 4851 "Attempting failover.", 4852 fcftab->TID, 4853 fcfp->fcf_index); 4854 4855 fcfp->flag |= EMLXS_FCFI_FAILED; 4856 4857 rval = emlxs_fcoe_fcftab_state(port, 4858 FCOE_FCFTAB_STATE_FCFI_ONLINE, 4859 FCF_REASON_REENTER, evt, arg1); 4860 break; 4861 4862 case FCOE_FCFTAB_STATE_ONLINE: 4863 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4864 "fcoe_fcftab_fcfi_offline_evt_action:%x fcfi:%d.", 4865 fcftab->TID, 4866 fcfp->fcf_index); 4867 4868 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_ONLINE, 4869 FCF_REASON_REENTER, evt, arg1); 4870 break; 4871 4872 default: 4873 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4874 "fcoe_fcftab_fcfi_offline_evt_action:%x %s fcfi:%d.", 4875 fcftab->TID, 4876 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4877 fcfp->fcf_index); 4878 break; 4879 } 4880 4881 return (rval); 4882 4883 } /* emlxs_fcoe_fcftab_fcfi_offline_evt_action() */ 4884 4885 4886 /*ARGSUSED*/ 4887 static uint32_t 4888 emlxs_fcoe_fcftab_fcfi_online_evt_action(emlxs_port_t *port, uint32_t evt, 4889 void *arg1) 4890 { 4891 emlxs_hba_t *hba = HBA; 4892 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4893 uint32_t rval = 0; 4894 FCFIobj_t *fcfp; 4895 4896 if (evt != FCF_EVENT_FCFI_ONLINE) { 4897 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4898 "fcoe_fcftab_fcfi_online_evt_action:%x %s:%s arg=%p " 4899 "flag=%x. Invalid event type. <", 4900 fcftab->TID, 4901 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4902 emlxs_fcf_event_xlate(evt), arg1, 4903 fcftab->flag); 4904 return (1); 4905 } 4906 4907 fcfp = (FCFIobj_t *)arg1; 4908 4909 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4910 "fcoe_fcftab_fcfi_online_evt_action:%x fcfi:%d. <", 4911 fcftab->TID, 4912 fcfp->fcf_index); 4913 4914 return (rval); 4915 4916 } /* emlxs_fcoe_fcftab_fcfi_online_evt_action() */ 4917 4918 4919 /*ARGSUSED*/ 4920 static uint32_t 4921 emlxs_fcoe_fcftab_cvl_evt_action(emlxs_port_t *port, uint32_t evt, 4922 void *arg1) 4923 { 4924 emlxs_hba_t *hba = HBA; 4925 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4926 uint32_t rval = 0; 4927 emlxs_port_t *vport; 4928 uint32_t vpi; 4929 VPIobj_t *vpip; 4930 4931 if (evt != FCF_EVENT_CVL) { 4932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4933 "fcoe_fcftab_cvl_evt_action:%x %s:%s arg=%p flag=%x. " 4934 "Invalid event type. <", 4935 fcftab->TID, 4936 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4937 emlxs_fcf_event_xlate(evt), arg1, 4938 fcftab->flag); 4939 return (1); 4940 } 4941 4942 /* Pause VPI */ 4943 vpi = (uint32_t)((unsigned long)arg1); 4944 vport = &VPORT(vpi); 4945 vpip = vport->vpip; 4946 4947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4948 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. Pausing VPI:%d. >", 4949 fcftab->TID, 4950 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4951 fcftab->generation, 4952 vpip->VPI); 4953 4954 rval = emlxs_vpi_event(vport, FCF_EVENT_VPI_PAUSE, vpip); 4955 4956 switch (fcftab->state) { 4957 case FCOE_FCFTAB_STATE_SOLICIT: 4958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4959 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. " 4960 "Already soliciting. <", 4961 fcftab->TID, 4962 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4963 fcftab->generation); 4964 break; 4965 4966 default: 4967 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 4968 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ; 4969 fcftab->generation++; 4970 4971 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 4972 "fcoe_fcftab_cvl_evt_action:%x %s gen=%x. Soliciting.", 4973 fcftab->TID, 4974 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 4975 fcftab->generation); 4976 4977 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 4978 FCF_REASON_EVENT, evt, arg1); 4979 break; 4980 } 4981 4982 return (rval); 4983 4984 } /* emlxs_fcoe_fcftab_cvl_evt_action() */ 4985 4986 4987 /*ARGSUSED*/ 4988 static uint32_t 4989 emlxs_fcoe_fcftab_linkup_evt_action(emlxs_port_t *port, uint32_t evt, 4990 void *arg1) 4991 { 4992 emlxs_hba_t *hba = HBA; 4993 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 4994 uint32_t rval = 0; 4995 4996 if (evt != FCF_EVENT_LINKUP) { 4997 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 4998 "fcoe_fcftab_linkup_evt_action:%x %s:%s arg=%p flag=%x. " 4999 "Invalid event type. <", 5000 fcftab->TID, 5001 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5002 emlxs_fcf_event_xlate(evt), arg1, 5003 fcftab->flag); 5004 return (1); 5005 } 5006 5007 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5008 "fcoe_fcftab_linkup_evt_action:%x %s:%s arg=%p gen=%x. Link up.", 5009 fcftab->TID, 5010 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5011 emlxs_fcf_event_xlate(evt), arg1, 5012 fcftab->generation); 5013 5014 emlxs_fcf_linkup(port); 5015 5016 switch (fcftab->state) { 5017 case FCOE_FCFTAB_STATE_SOLICIT: 5018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5019 "fcoe_fcftab_linkup_evt_action:%x %s gen=%x. " 5020 "Already soliciting. <", 5021 fcftab->TID, 5022 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5023 fcftab->generation); 5024 break; 5025 5026 default: 5027 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 5028 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ; 5029 fcftab->generation++; 5030 5031 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5032 "fcoe_fcftab_linkup_evt_action:%x %s gen=%x. Soliciting.", 5033 fcftab->TID, 5034 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5035 fcftab->generation); 5036 5037 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 5038 FCF_REASON_EVENT, evt, arg1); 5039 break; 5040 } 5041 5042 return (rval); 5043 5044 } /* emlxs_fcoe_fcftab_linkup_evt_action() */ 5045 5046 5047 /*ARGSUSED*/ 5048 static uint32_t 5049 emlxs_fcoe_fcftab_linkdown_evt_action(emlxs_port_t *port, uint32_t evt, 5050 void *arg1) 5051 { 5052 emlxs_hba_t *hba = HBA; 5053 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5054 uint32_t rval = 0; 5055 int32_t i; 5056 FCFIobj_t *fcfp; 5057 5058 if (evt != FCF_EVENT_LINKDOWN) { 5059 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5060 "fcoe_fcftab_linkdown_evt_action:%x %s:%s arg=%p " 5061 "flag=%x. Invalid event type. <", 5062 fcftab->TID, 5063 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5064 emlxs_fcf_event_xlate(evt), arg1, 5065 fcftab->flag); 5066 return (1); 5067 } 5068 5069 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 5070 fcftab->flag |= EMLXS_FCOE_FCFTAB_OFFLINE_REQ; 5071 5072 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5073 "fcoe_fcftab_linkdown_evt_action:%x %s:%s arg=%p flag=%x. " 5074 "Linkdown.", 5075 fcftab->TID, 5076 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5077 emlxs_fcf_event_xlate(evt), arg1, 5078 fcftab->flag); 5079 5080 emlxs_fcf_linkdown(port); 5081 5082 /* Pause all active FCFI's */ 5083 for (i = 0; i < fcftab->fcfi_count; i++) { 5084 fcfp = fcftab->fcfi[i]; 5085 5086 if ((fcfp->state == FCFI_STATE_OFFLINE) || 5087 (fcfp->state == FCFI_STATE_PAUSED)) { 5088 break; 5089 } 5090 5091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5092 "fcoe_fcftab_linkdown_evt_action:%x Pausing FCFI:%d. >", 5093 fcftab->TID, 5094 fcfp->fcf_index); 5095 5096 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_PAUSE, fcfp); 5097 } 5098 5099 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5100 "fcoe_fcftab_linkdown_evt_action:%x " 5101 "Going offline.", 5102 fcftab->TID); 5103 5104 switch (fcftab->state) { 5105 case FCOE_FCFTAB_STATE_OFFLINE: 5106 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE, 5107 FCF_REASON_REENTER, evt, arg1); 5108 break; 5109 5110 default: 5111 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE, 5112 FCF_REASON_EVENT, evt, arg1); 5113 break; 5114 } 5115 5116 return (rval); 5117 5118 } /* emlxs_fcoe_fcftab_linkdown_evt_action() */ 5119 5120 5121 /*ARGSUSED*/ 5122 static uint32_t 5123 emlxs_fcoe_fcftab_shutdown_evt_action(emlxs_port_t *port, uint32_t evt, 5124 void *arg1) 5125 { 5126 emlxs_hba_t *hba = HBA; 5127 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5128 uint32_t rval = 0; 5129 5130 if (evt != FCF_EVENT_SHUTDOWN) { 5131 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5132 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 5133 "Invalid event type. <", 5134 fcftab->TID, 5135 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5136 emlxs_fcf_event_xlate(evt), arg1, 5137 fcftab->flag); 5138 return (1); 5139 } 5140 5141 if (fcftab->flag & EMLXS_FCFTAB_SHUTDOWN) { 5142 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5143 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 5144 "Already shut down. <", 5145 fcftab->TID, 5146 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5147 emlxs_fcf_event_xlate(evt), arg1, 5148 fcftab->flag); 5149 return (1); 5150 } 5151 5152 if (fcftab->state == FCOE_FCFTAB_STATE_SHUTDOWN) { 5153 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5154 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 5155 "Already shutting down. <", 5156 fcftab->TID, 5157 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5158 emlxs_fcf_event_xlate(evt), arg1, 5159 fcftab->flag); 5160 return (1); 5161 } 5162 5163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5164 "fcoe_fcftab_shutdown_evt_action:%x %s:%s arg=%p flag=%x. " 5165 "Shutting down.", 5166 fcftab->TID, 5167 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5168 emlxs_fcf_event_xlate(evt), arg1, 5169 fcftab->flag); 5170 5171 emlxs_fcf_linkdown(port); 5172 5173 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SHUTDOWN, 5174 FCF_REASON_EVENT, evt, arg1); 5175 5176 return (rval); 5177 5178 } /* emlxs_fcoe_fcftab_shutdown_evt_action() */ 5179 5180 5181 static uint32_t 5182 emlxs_fcoe_fcftab_req_handler(emlxs_port_t *port, void *arg1) 5183 { 5184 emlxs_hba_t *hba = HBA; 5185 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5186 uint32_t rval = 0; 5187 5188 if (!(fcftab->flag & EMLXS_FCFTAB_REQ_MASK)) { 5189 return (1); 5190 } 5191 5192 if (fcftab->flag & EMLXS_FCOE_FCFTAB_OFFLINE_REQ) { 5193 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_OFFLINE, 5194 FCF_REASON_REQUESTED, 0, arg1); 5195 } 5196 5197 else if (fcftab->flag & EMLXS_FCOE_FCFTAB_SOL_REQ) { 5198 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 5199 FCF_REASON_REQUESTED, 0, arg1); 5200 } 5201 5202 else if (fcftab->flag & EMLXS_FCOE_FCFTAB_READ_REQ) { 5203 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ, 5204 FCF_REASON_REQUESTED, 0, FCFTAB_READ_ALL); 5205 } 5206 5207 return (rval); 5208 5209 } /* emlxs_fcoe_fcftab_req_handler() */ 5210 5211 5212 static void 5213 emlxs_fcoe_fcftab_read_timer(emlxs_hba_t *hba) 5214 { 5215 emlxs_port_t *port = &PPORT; 5216 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5217 5218 /* Check FCF timer */ 5219 if (!fcftab->read_timer || 5220 (hba->timer_tics < fcftab->read_timer)) { 5221 return; 5222 } 5223 fcftab->read_timer = 0; 5224 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ; 5225 5226 switch (fcftab->state) { 5227 case FCOE_FCFTAB_STATE_SOLICIT_CMPL: 5228 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5229 "fcoe_fcftab_timer:%x %s >", 5230 fcftab->TID, 5231 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5232 5233 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ, 5234 0, 0, FCFTAB_READ_ALL); 5235 break; 5236 5237 default: 5238 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5239 "fcoe_fcftab_timer:%x %s", 5240 fcftab->TID, 5241 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5242 break; 5243 } 5244 5245 return; 5246 5247 } /* emlxs_fcoe_fcftab_read_timer() */ 5248 5249 5250 static void 5251 emlxs_fcoe_fcftab_sol_timer(emlxs_hba_t *hba) 5252 { 5253 emlxs_port_t *port = &PPORT; 5254 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5255 5256 /* Check FCF timer */ 5257 if (!fcftab->sol_timer || 5258 (hba->timer_tics < fcftab->sol_timer)) { 5259 return; 5260 } 5261 fcftab->sol_timer = 0; 5262 5263 switch (fcftab->state) { 5264 case FCOE_FCFTAB_STATE_ONLINE: 5265 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 5266 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ; 5267 fcftab->generation++; 5268 5269 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5270 "fcoe_fcftab_sol_timer:%x %s gen=%x. Soliciting. >", 5271 fcftab->TID, 5272 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5273 fcftab->generation); 5274 5275 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 5276 FCF_REASON_EVENT, 0, 0); 5277 break; 5278 5279 default: 5280 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5281 "fcoe_fcftab_sol_timer:%x %s", 5282 fcftab->TID, 5283 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5284 break; 5285 } 5286 5287 return; 5288 5289 } /* emlxs_fcoe_fcftab_sol_timer() */ 5290 5291 5292 static void 5293 emlxs_fcoe_fcftab_offline_timer(emlxs_hba_t *hba) 5294 { 5295 emlxs_port_t *port = &PPORT; 5296 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5297 uint32_t i; 5298 FCFIobj_t *fcfp; 5299 5300 for (i = 0; i < fcftab->fcfi_count; i++) { 5301 fcfp = fcftab->fcfi[i]; 5302 5303 /* Check offline timer */ 5304 if (!fcfp->offline_timer || 5305 (hba->timer_tics < fcfp->offline_timer)) { 5306 continue; 5307 } 5308 fcfp->offline_timer = 0; 5309 5310 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5311 "fcoe_fcftab_offline_timer:%x. Offlining FCFI:%d. >", 5312 fcftab->TID, 5313 fcfp->fcf_index); 5314 5315 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_OFFLINE, fcfp); 5316 } 5317 5318 return; 5319 5320 } /* emlxs_fcoe_fcftab_offline_timer() */ 5321 5322 5323 /*ARGSUSED*/ 5324 static uint32_t 5325 emlxs_fcoe_fcftab_sol_failed_action(emlxs_port_t *port, uint32_t evt, 5326 void *arg1) 5327 { 5328 emlxs_hba_t *hba = HBA; 5329 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5330 uint32_t rval = 0; 5331 5332 fcftab->attempts++; 5333 5334 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT_FAILED) { 5335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5336 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p " 5337 "attempt=%d. Invalid state. <", 5338 fcftab->TID, 5339 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5340 emlxs_fcf_event_xlate(evt), 5341 arg1, fcftab->attempts); 5342 return (1); 5343 } 5344 5345 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) || 5346 (fcftab->reason == FCF_REASON_SEND_FAILED) || 5347 (fcftab->attempts >= 3)) { 5348 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5349 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p " 5350 "attempt=%d reason=%x. Giving up.", 5351 fcftab->TID, 5352 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5353 emlxs_fcf_event_xlate(evt), arg1, 5354 fcftab->attempts, 5355 fcftab->reason); 5356 5357 rval = emlxs_fcoe_fcftab_state(port, 5358 FCOE_FCFTAB_STATE_SOLICIT_CMPL, 5359 FCF_REASON_OP_FAILED, 0, arg1); 5360 } else { 5361 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5362 "fcoe_fcftab_sol_failed_action:%x %s:%s arg=%p " 5363 "attempt=%d reason=%x. Retrying.", 5364 fcftab->TID, 5365 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5366 emlxs_fcf_event_xlate(evt), arg1, 5367 fcftab->attempts, 5368 fcftab->reason); 5369 5370 rval = emlxs_fcoe_fcftab_state(port, 5371 FCOE_FCFTAB_STATE_SOLICIT, 5372 FCF_REASON_OP_FAILED, 0, arg1); 5373 } 5374 5375 return (rval); 5376 5377 } /* emlxs_fcoe_fcftab_sol_failed_action() */ 5378 5379 5380 /*ARGSUSED*/ 5381 static uint32_t 5382 emlxs_fcoe_fcftab_sol_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 5383 { 5384 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 5385 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5386 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 5387 uint16_t TID; 5388 mbox_rsp_hdr_t *hdr_rsp; 5389 MATCHMAP *mp; 5390 uint32_t status = MGMT_STATUS_FCF_IN_USE; 5391 uint32_t xstatus = 0; 5392 uint32_t fip_mode = 1; 5393 5394 mutex_enter(&EMLXS_FCF_LOCK); 5395 TID = (uint16_t)((unsigned long)mbq->context); 5396 5397 if (mbq->nonembed) { 5398 fip_mode = 0; 5399 5400 mp = (MATCHMAP *)mbq->nonembed; 5401 mbq->nonembed = NULL; 5402 5403 hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 5404 status = hdr_rsp->status; 5405 xstatus = hdr_rsp->extra_status; 5406 5407 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 5408 } 5409 5410 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT) { 5411 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5412 "fcoe_fcftab_sol_mbcmpl:%x %s.", 5413 TID, 5414 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5415 5416 mutex_exit(&EMLXS_FCF_LOCK); 5417 return (0); 5418 } 5419 5420 if (TID != fcftab->generation) { 5421 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5422 "fcoe_fcftab_sol_mbcmpl:%x %s. " 5423 "Incorrect generation %x. Dropping.", 5424 TID, 5425 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5426 fcftab->generation); 5427 5428 mutex_exit(&EMLXS_FCF_LOCK); 5429 return (0); 5430 } 5431 5432 if (mb4->mbxStatus) { 5433 if (fip_mode) { 5434 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5435 "fcoe_fcftab_sol_mbcmpl:%x failed. %s. >", 5436 fcftab->TID, 5437 emlxs_mb_xlate_status(mb4->mbxStatus)); 5438 5439 (void) emlxs_fcoe_fcftab_state(port, 5440 FCOE_FCFTAB_STATE_SOLICIT_FAILED, 5441 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 5442 5443 mutex_exit(&EMLXS_FCF_LOCK); 5444 return (0); 5445 5446 } else if ((status == 0)||(status != MGMT_STATUS_FCF_IN_USE)) { 5447 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5448 "fcoe_fcftab_sol_mbcmpl:%x failed. %s %x,%x. >", 5449 fcftab->TID, 5450 emlxs_mb_xlate_status(mb4->mbxStatus), 5451 status, xstatus); 5452 5453 (void) emlxs_fcoe_fcftab_state(port, 5454 FCOE_FCFTAB_STATE_SOLICIT_FAILED, 5455 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 5456 5457 mutex_exit(&EMLXS_FCF_LOCK); 5458 return (0); 5459 } 5460 } 5461 5462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5463 "fcoe_fcftab_sol_mbcmpl:%x %s gen=%x. Solicit complete. >", 5464 fcftab->TID, 5465 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5466 fcftab->generation); 5467 5468 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT_CMPL, 5469 0, 0, 0); 5470 5471 mutex_exit(&EMLXS_FCF_LOCK); 5472 return (0); 5473 5474 } /* emlxs_fcoe_fcftab_sol_mbcmpl() */ 5475 5476 5477 /*ARGSUSED*/ 5478 static uint32_t 5479 emlxs_fcoe_fcftab_sol_action(emlxs_port_t *port, uint32_t evt, 5480 void *arg1) 5481 { 5482 emlxs_hba_t *hba = HBA; 5483 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5484 MAILBOXQ *mbq; 5485 MAILBOX4 *mb4; 5486 MATCHMAP *mp = NULL; 5487 uint32_t rval = 0; 5488 5489 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT) { 5490 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5491 "fcoe_fcftab_sol_action:%x %s:%s arg=%p. " 5492 "Invalid state. <", 5493 fcftab->TID, 5494 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5495 emlxs_fcf_event_xlate(evt), arg1); 5496 return (1); 5497 } 5498 5499 if ((fcftab->prev_state != FCOE_FCFTAB_STATE_SOLICIT_FAILED) || 5500 (fcftab->flag & EMLXS_FCOE_FCFTAB_SOL_REQ)) { 5501 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_SOL_REQ; 5502 fcftab->attempts = 0; 5503 } 5504 5505 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 5506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5507 "fcoe_fcftab_sol_action:%x %s:%s arg=%p gen=%d flag=%x. " 5508 "Handling request.", 5509 fcftab->TID, 5510 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5511 emlxs_fcf_event_xlate(evt), arg1, 5512 fcftab->generation, 5513 fcftab->flag); 5514 5515 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 5516 return (rval); 5517 } 5518 5519 if (fcftab->attempts == 0) { 5520 fcftab->TID = fcftab->generation; 5521 } 5522 5523 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5524 "fcoe_fcftab_sol_action:%x %s:%s arg=%p gen=%x fip=%x. " 5525 "Requesting solicit. <", 5526 fcftab->TID, 5527 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5528 emlxs_fcf_event_xlate(evt), arg1, 5529 fcftab->generation, 5530 ((hba->flag & FC_FIP_SUPPORTED)? 1:0)); 5531 5532 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 5533 rval = emlxs_fcoe_fcftab_state(port, 5534 FCOE_FCFTAB_STATE_SOLICIT_FAILED, 5535 FCF_REASON_NO_MBOX, 0, 0); 5536 return (rval); 5537 } 5538 5539 mb4 = (MAILBOX4*)mbq; 5540 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 5541 5542 if (hba->flag & FC_FIP_SUPPORTED) { 5543 IOCTL_FCOE_REDISCOVER_FCF_TABLE *fcf; 5544 5545 mbq->nonembed = NULL; 5546 mbq->mbox_cmpl = emlxs_fcoe_fcftab_sol_mbcmpl; 5547 mbq->context = (void *)((unsigned long)fcftab->TID); 5548 mbq->port = (void *)port; 5549 5550 mb4->un.varSLIConfig.be.embedded = 1; 5551 mb4->mbxCommand = MBX_SLI_CONFIG; 5552 mb4->mbxOwner = OWN_HOST; 5553 mb4->un.varSLIConfig.be.payload_length = 5554 sizeof (IOCTL_FCOE_REDISCOVER_FCF_TABLE) + 5555 IOCTL_HEADER_SZ; 5556 mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 5557 IOCTL_SUBSYSTEM_FCOE; 5558 mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 5559 FCOE_OPCODE_REDISCOVER_FCF_TABLE; 5560 mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 5561 mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 5562 sizeof (IOCTL_FCOE_REDISCOVER_FCF_TABLE); 5563 5564 fcf = (IOCTL_FCOE_REDISCOVER_FCF_TABLE *) 5565 &mb4->un.varSLIConfig.payload; 5566 fcf->params.request.fcf_count = 0; /* invalidate FCF table */ 5567 5568 } else { /* Non-FIP */ 5569 5570 /* Non-FIP uses a persistent FCF entry that */ 5571 /* we must add to the table */ 5572 5573 IOCTL_FCOE_ADD_FCF_TABLE *fcf; 5574 mbox_req_hdr_t *hdr_req; 5575 FCF_RECORD_t *fcf_rec; 5576 uint8_t bitmap[512]; 5577 uint16_t i; 5578 5579 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 5580 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 5581 5582 rval = emlxs_fcoe_fcftab_state(port, 5583 FCOE_FCFTAB_STATE_SOLICIT_FAILED, 5584 FCF_REASON_NO_BUFFER, 0, arg1); 5585 return (rval); 5586 } 5587 bzero(mp->virt, mp->size); 5588 5589 mbq->nonembed = (void *)mp; 5590 mbq->mbox_cmpl = emlxs_fcoe_fcftab_sol_mbcmpl; 5591 mbq->context = (void *)((unsigned long)fcftab->generation); 5592 mbq->port = (void *)port; 5593 5594 mb4->un.varSLIConfig.be.embedded = 0; 5595 mb4->mbxCommand = MBX_SLI_CONFIG; 5596 mb4->mbxOwner = OWN_HOST; 5597 5598 hdr_req = (mbox_req_hdr_t *)mp->virt; 5599 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 5600 hdr_req->opcode = FCOE_OPCODE_ADD_FCF_TABLE; 5601 hdr_req->timeout = 0; 5602 hdr_req->req_length = sizeof (IOCTL_FCOE_ADD_FCF_TABLE); 5603 5604 fcf = (IOCTL_FCOE_ADD_FCF_TABLE *)(hdr_req + 1); 5605 fcf->params.request.fcf_index = 0; 5606 5607 fcf_rec = &fcf->params.request.fcf_entry; 5608 fcf_rec->max_recv_size = EMLXS_FCOE_MAX_RCV_SZ; 5609 fcf_rec->fka_adv_period = 0; 5610 fcf_rec->fip_priority = 128; 5611 5612 #ifdef EMLXS_BIG_ENDIAN 5613 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC3; 5614 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC2; 5615 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC1; 5616 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC0; 5617 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC5; 5618 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC4; 5619 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[2]; 5620 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1]; 5621 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[0]; 5622 #endif /* EMLXS_BIG_ENDIAN */ 5623 #ifdef EMLXS_LITTLE_ENDIAN 5624 fcf_rec->fcf_mac_address_hi[0] = FCOE_FCF_MAC0; 5625 fcf_rec->fcf_mac_address_hi[1] = FCOE_FCF_MAC1; 5626 fcf_rec->fcf_mac_address_hi[2] = FCOE_FCF_MAC2; 5627 fcf_rec->fcf_mac_address_hi[3] = FCOE_FCF_MAC3; 5628 fcf_rec->fcf_mac_address_low[0] = FCOE_FCF_MAC4; 5629 fcf_rec->fcf_mac_address_low[1] = FCOE_FCF_MAC5; 5630 fcf_rec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[0]; 5631 fcf_rec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1]; 5632 fcf_rec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[2]; 5633 #endif /* EMLXS_LITTLE_ENDIAN */ 5634 5635 if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) { 5636 bzero((void *) bitmap, 512); 5637 i = hba->sli.sli4.cfgFCOE.VLanId; 5638 bitmap[i / 8] = (1 << (i % 8)); 5639 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512); 5640 } else { 5641 bzero((void *) bitmap, 512); 5642 bitmap[0] = 1; /* represents bit 0 */ 5643 BE_SWAP32_BCOPY(bitmap, fcf_rec->vlan_bitmap, 512); 5644 } 5645 5646 fcf_rec->fcf_valid = 1; 5647 fcf_rec->fcf_available = 1; 5648 } 5649 5650 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 5651 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 5652 if (mp) { 5653 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 5654 } 5655 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 5656 5657 rval = emlxs_fcoe_fcftab_state(port, 5658 FCOE_FCFTAB_STATE_SOLICIT_FAILED, 5659 FCF_REASON_SEND_FAILED, rval, 0); 5660 5661 return (rval); 5662 } 5663 5664 return (0); 5665 5666 } /* emlxs_fcoe_fcftab_sol_action() */ 5667 5668 5669 /*ARGSUSED*/ 5670 static uint32_t 5671 emlxs_fcoe_fcftab_sol_cmpl_action(emlxs_port_t *port, uint32_t evt, 5672 void *arg1) 5673 { 5674 emlxs_hba_t *hba = HBA; 5675 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5676 uint32_t rval = 0; 5677 emlxs_config_t *cfg = &CFG; 5678 5679 if (fcftab->state != FCOE_FCFTAB_STATE_SOLICIT_CMPL) { 5680 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5681 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p " 5682 "Invalid state. <", 5683 fcftab->TID, 5684 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5685 emlxs_fcf_event_xlate(evt), arg1); 5686 return (1); 5687 } 5688 5689 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 5690 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5691 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p gen=%d " 5692 "flag=%x. Handling request.", 5693 fcftab->TID, 5694 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5695 emlxs_fcf_event_xlate(evt), arg1, 5696 fcftab->generation, 5697 fcftab->flag); 5698 5699 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 5700 return (rval); 5701 } 5702 5703 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5704 "fcoe_fcftab_sol_cmpl_action:%x %s:%s arg=%p gen=%d. " 5705 "Starting timer (%d secs).", 5706 fcftab->TID, 5707 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5708 emlxs_fcf_event_xlate(evt), arg1, 5709 fcftab->generation, 5710 cfg[CFG_FCF_SOLICIT_DELAY].current); 5711 5712 /* Start the read timer */ 5713 fcftab->read_timer = hba->timer_tics + 5714 cfg[CFG_FCF_SOLICIT_DELAY].current; 5715 5716 return (0); 5717 5718 } /* emlxs_fcoe_fcftab_sol_cmpl_action() */ 5719 5720 5721 /*ARGSUSED*/ 5722 static uint32_t 5723 emlxs_fcoe_fcftab_read_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 5724 { 5725 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 5726 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5727 MAILBOX4 *mb4 = (MAILBOX4 *)mbq; 5728 mbox_rsp_hdr_t *hdr_rsp; 5729 IOCTL_FCOE_READ_FCF_TABLE *fcf; 5730 FCF_RECORD_t *fcfrec; 5731 FCFIobj_t *fcfp; 5732 MATCHMAP *mp; 5733 uint32_t context; 5734 uint16_t index; 5735 uint16_t TID; 5736 uint32_t event_tag; 5737 5738 mutex_enter(&EMLXS_FCF_LOCK); 5739 context = (uint32_t)((unsigned long)mbq->context); 5740 TID = (uint16_t)(context >> 16); 5741 index = (uint16_t)(context & 0xFFFF); 5742 5743 if (fcftab->state != FCOE_FCFTAB_STATE_READ) { 5744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5745 "fcoe_fcftab_read_mbcmpl:%x index=%d %s.", 5746 TID, index, 5747 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5748 5749 mutex_exit(&EMLXS_FCF_LOCK); 5750 return (0); 5751 } 5752 5753 if (TID != fcftab->generation) { 5754 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5755 "fcoe_fcftab_read_mbcmpl:%x index=%d %s. " 5756 "Incorrect generation %x. Dropping.", 5757 TID, index, 5758 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5759 fcftab->generation); 5760 5761 mutex_exit(&EMLXS_FCF_LOCK); 5762 return (0); 5763 } 5764 5765 mp = (MATCHMAP *)mbq->nonembed; 5766 hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 5767 5768 if (mb4->mbxStatus || hdr_rsp->status) { 5769 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5770 "fcoe_fcftab_read_mbcmpl:%x index=%d failed. %s %x,%x. >", 5771 fcftab->TID, index, 5772 emlxs_mb_xlate_status(mb4->mbxStatus), 5773 hdr_rsp->status, hdr_rsp->extra_status); 5774 5775 (void) emlxs_fcoe_fcftab_state(port, 5776 FCOE_FCFTAB_STATE_READ_FAILED, 5777 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 5778 (void*)((unsigned long)index)); 5779 5780 mutex_exit(&EMLXS_FCF_LOCK); 5781 return (0); 5782 } 5783 5784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5785 "fcoe_fcftab_read_mbcmpl:%x index=%d %s", 5786 fcftab->TID, index, 5787 emlxs_fcoe_fcftab_state_xlate(fcftab->state)); 5788 5789 fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_rsp + 1); 5790 fcfrec = &fcf->params.response.fcf_entry[0]; 5791 5792 #ifdef EMLXS_BIG_ENDIAN 5793 { 5794 uint32_t *iptr; 5795 uint32_t i; 5796 uint8_t j; 5797 uint16_t s; 5798 uint16_t *sptr; 5799 5800 /* Fix up data in FCF record */ 5801 SWAP32_BUFFER(&fcfrec->fabric_name_identifier[0], 8); 5802 SWAP32_BUFFER(&fcfrec->switch_name_identifier[0], 8); 5803 SWAP32_BUFFER(&fcfrec->vlan_bitmap[0], 512); 5804 5805 iptr = (uint32_t *)&fcfrec->fcf_mac_address_hi[0]; 5806 i = *iptr; 5807 *iptr = SWAP32(i); 5808 5809 sptr = (uint16_t *)&fcfrec->fcf_mac_address_low[0]; 5810 s = *sptr; 5811 *sptr = SWAP16(s); 5812 5813 j = fcfrec->fc_map[0]; 5814 fcfrec->fc_map[0] = fcfrec->fc_map[2]; 5815 fcfrec->fc_map[2] = j; 5816 } 5817 #endif /* EMLXS_BIG_ENDIAN */ 5818 5819 event_tag = fcf->params.response.event_tag; 5820 5821 /* Try to find existing fcfrec */ 5822 fcfp = emlxs_fcfi_find(port, fcfrec, 0); 5823 5824 /* If not found, allocate a new one */ 5825 if (!fcfp) { 5826 fcfp = emlxs_fcfi_alloc(port); 5827 } 5828 5829 if (!fcfp) { 5830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5831 "fcoe_fcftab_read_mbcmpl:%x index=%d failed. " 5832 "Unable to allocate fcfi. >", 5833 fcftab->TID, index); 5834 5835 (void) emlxs_fcoe_fcftab_state(port, 5836 FCOE_FCFTAB_STATE_READ_FAILED, 5837 FCF_REASON_NO_FCFI, 0, 5838 (void*)((unsigned long)index)); 5839 5840 mutex_exit(&EMLXS_FCF_LOCK); 5841 return (0); 5842 } 5843 5844 /* Update the FCFI */ 5845 emlxs_fcfi_update(port, fcfp, fcfrec, event_tag); 5846 5847 /* Check if another record needs to be acquired */ 5848 if (fcf->params.response.next_valid_fcf_index != 0xffff) { 5849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5850 "fcoe_fcftab_read_mbcmpl:%x. Read next. >", 5851 fcftab->TID); 5852 5853 (void) emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ, 5854 FCF_REASON_REENTER, 0, 5855 (void *)((unsigned long)fcf->params.response. 5856 next_valid_fcf_index)); 5857 } else { 5858 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5859 "fcoe_fcftab_read_mbcmpl:%x. Read complete. >", 5860 fcftab->TID); 5861 5862 (void) emlxs_fcoe_fcftab_state(port, 5863 FCOE_FCFTAB_STATE_READ_CMPL, 5864 0, 0, (void*)((unsigned long)index)); 5865 } 5866 5867 mutex_exit(&EMLXS_FCF_LOCK); 5868 return (0); 5869 5870 } /* emlxs_fcoe_fcftab_read_mbcmpl() */ 5871 5872 5873 /*ARGSUSED*/ 5874 static uint32_t 5875 emlxs_fcoe_fcftab_read_action(emlxs_port_t *port, uint32_t evt, 5876 void *arg1) 5877 { 5878 emlxs_hba_t *hba = HBA; 5879 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5880 MAILBOXQ *mbq; 5881 MAILBOX4 *mb4; 5882 IOCTL_FCOE_READ_FCF_TABLE *fcf; 5883 uint32_t rval = 0; 5884 MATCHMAP *mp; 5885 mbox_req_hdr_t *hdr_req; 5886 uint16_t index = (uint16_t)((unsigned long)arg1); 5887 uint32_t context; 5888 5889 if (fcftab->state != FCOE_FCFTAB_STATE_READ) { 5890 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5891 "fcoe_fcftab_read_action:%x %s:%s arg=%p. " 5892 "Invalid state. <", 5893 fcftab->TID, 5894 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5895 emlxs_fcf_event_xlate(evt), arg1); 5896 return (1); 5897 } 5898 5899 if ((fcftab->prev_state != FCOE_FCFTAB_STATE_READ_FAILED) || 5900 (fcftab->flag & EMLXS_FCOE_FCFTAB_READ_REQ)) { 5901 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_READ_REQ; 5902 fcftab->attempts = 0; 5903 } 5904 5905 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 5906 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5907 "fcoe_fcftab_read_action:%x %s:%s arg=%p flag=%x. " 5908 "Handling request.", 5909 fcftab->TID, 5910 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5911 emlxs_fcf_event_xlate(evt), arg1, 5912 fcftab->flag); 5913 5914 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 5915 return (rval); 5916 } 5917 5918 if (fcftab->attempts == 0) { 5919 fcftab->TID = fcftab->generation; 5920 } 5921 5922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 5923 "fcoe_fcftab_read_action:%x %s:%s arg=%p attempts=%d. " 5924 "Reading FCF. <", 5925 fcftab->TID, 5926 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 5927 emlxs_fcf_event_xlate(evt), arg1, 5928 fcftab->attempts); 5929 5930 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 5931 rval = emlxs_fcoe_fcftab_state(port, 5932 FCOE_FCFTAB_STATE_READ_FAILED, 5933 FCF_REASON_NO_MBOX, 0, arg1); 5934 return (rval); 5935 } 5936 mb4 = (MAILBOX4*)mbq; 5937 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 5938 5939 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 5940 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 5941 5942 rval = emlxs_fcoe_fcftab_state(port, 5943 FCOE_FCFTAB_STATE_READ_FAILED, 5944 FCF_REASON_NO_BUFFER, 0, arg1); 5945 return (rval); 5946 } 5947 bzero(mp->virt, mp->size); 5948 5949 mbq->nonembed = (void *)mp; 5950 mbq->mbox_cmpl = emlxs_fcoe_fcftab_read_mbcmpl; 5951 5952 context = ((uint32_t)fcftab->TID << 16) | (uint32_t)index; 5953 mbq->context = (void *)((unsigned long)context); 5954 mbq->port = (void *)port; 5955 5956 mb4->un.varSLIConfig.be.embedded = 0; 5957 mb4->mbxCommand = MBX_SLI_CONFIG; 5958 mb4->mbxOwner = OWN_HOST; 5959 5960 hdr_req = (mbox_req_hdr_t *)mp->virt; 5961 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 5962 hdr_req->opcode = FCOE_OPCODE_READ_FCF_TABLE; 5963 hdr_req->timeout = 0; 5964 hdr_req->req_length = sizeof (IOCTL_FCOE_READ_FCF_TABLE); 5965 5966 fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_req + 1); 5967 fcf->params.request.fcf_index = index; 5968 5969 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 5970 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 5971 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 5972 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 5973 5974 rval = emlxs_fcoe_fcftab_state(port, 5975 FCOE_FCFTAB_STATE_READ_FAILED, 5976 FCF_REASON_SEND_FAILED, rval, arg1); 5977 5978 return (rval); 5979 } 5980 5981 return (0); 5982 5983 } /* emlxs_fcoe_fcftab_read_action() */ 5984 5985 5986 /*ARGSUSED*/ 5987 static uint32_t 5988 emlxs_fcoe_fcftab_read_failed_action(emlxs_port_t *port, uint32_t evt, 5989 void *arg1) 5990 { 5991 emlxs_hba_t *hba = HBA; 5992 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 5993 uint32_t rval = 0; 5994 5995 fcftab->attempts++; 5996 5997 if (fcftab->state != FCOE_FCFTAB_STATE_READ_FAILED) { 5998 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 5999 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p " 6000 "attempt=%d. Invalid state. <", 6001 fcftab->TID, 6002 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6003 emlxs_fcf_event_xlate(evt), 6004 arg1, fcftab->attempts); 6005 return (1); 6006 } 6007 6008 if ((fcftab->reason == FCF_REASON_MBOX_FAILED) || 6009 (fcftab->reason == FCF_REASON_SEND_FAILED) || 6010 (fcftab->attempts >= 3)) { 6011 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6012 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p " 6013 "attempt=%d reason=%x. Giving up.", 6014 fcftab->TID, 6015 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6016 emlxs_fcf_event_xlate(evt), arg1, 6017 fcftab->attempts, 6018 fcftab->reason); 6019 6020 rval = emlxs_fcoe_fcftab_state(port, 6021 FCOE_FCFTAB_STATE_READ_CMPL, 6022 FCF_REASON_OP_FAILED, fcftab->attempts, arg1); 6023 } else { 6024 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6025 "fcoe_fcftab_read_failed_action:%x %s:%s arg=%p " 6026 "attempt=%d reason=%x. Retrying.", 6027 fcftab->TID, 6028 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6029 emlxs_fcf_event_xlate(evt), arg1, 6030 fcftab->attempts, 6031 fcftab->reason); 6032 6033 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_READ, 6034 FCF_REASON_OP_FAILED, fcftab->attempts, FCFTAB_READ_ALL); 6035 } 6036 6037 return (rval); 6038 6039 } /* emlxs_fcoe_fcftab_read_failed_action() */ 6040 6041 6042 /*ARGSUSED*/ 6043 static uint32_t 6044 emlxs_fcoe_fcftab_read_cmpl_action(emlxs_port_t *port, uint32_t evt, 6045 void *arg1) 6046 { 6047 emlxs_hba_t *hba = HBA; 6048 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6049 uint32_t rval = 0; 6050 FCFIobj_t *fcfp; 6051 uint32_t i; 6052 6053 if (fcftab->state != FCOE_FCFTAB_STATE_READ_CMPL) { 6054 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 6055 "fcoe_fcftab_read_cmpl_action:%x %s:%s arg=%p. " 6056 "Invalid state. <", 6057 fcftab->TID, 6058 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6059 emlxs_fcf_event_xlate(evt), arg1); 6060 return (1); 6061 } 6062 6063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6064 "fcoe_fcftab_read_cmpl_action:%x %s:%s arg=%p attempts=%d. " 6065 "Cleaning table.", 6066 fcftab->TID, 6067 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6068 emlxs_fcf_event_xlate(evt), arg1, 6069 fcftab->attempts); 6070 6071 /* Clean FCFI table */ 6072 fcfp = fcftab->table; 6073 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 6074 if (fcfp->state == FCFI_STATE_FREE) { 6075 continue; 6076 } 6077 6078 /* Adjust the freshness flag */ 6079 if (fcfp->generation == fcftab->generation) { 6080 fcfp->flag |= EMLXS_FCFI_FRESH; 6081 } else { 6082 fcfp->flag &= ~EMLXS_FCFI_FRESH; 6083 } 6084 6085 /* Clear the failed bit */ 6086 fcfp->flag &= ~EMLXS_FCFI_FAILED; 6087 6088 /* Free all stale unselected entries now */ 6089 if (!(fcfp->flag & EMLXS_FCFI_FRESH) && 6090 !(fcfp->flag & EMLXS_FCFI_SELECTED)) { 6091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6092 "fcoe_fcftab_read_cmpl_action:%x. FCF stale. " 6093 "Freeing FCFI:%d. >", 6094 fcftab->TID, 6095 fcfp->fcf_index); 6096 6097 (void) emlxs_fcfi_free(port, fcfp); 6098 continue; 6099 } 6100 } 6101 6102 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_FCFI_ONLINE, 6103 FCF_REASON_EVENT, evt, arg1); 6104 6105 return (rval); 6106 6107 } /* emlxs_fcoe_fcftab_read_cmpl_action() */ 6108 6109 6110 static FCFIobj_t * 6111 emlxs_fcoe_fcftab_fcfi_select(emlxs_port_t *port, char *fabric_wwn) 6112 { 6113 emlxs_hba_t *hba = HBA; 6114 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6115 FCFIobj_t *fcfp; 6116 FCFIobj_t *fcfp1; 6117 uint32_t mask; 6118 uint32_t viable; 6119 uint32_t i; 6120 uint32_t j; 6121 uint32_t rnum; 6122 timespec_t time; 6123 FCFIobj_t **fcf_table; 6124 uint32_t fcf_table_count; 6125 6126 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 6127 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH| 6128 EMLXS_FCFI_FAILED|EMLXS_FCFI_SELECTED); 6129 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 6130 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH); 6131 6132 /* Tag & count viable entries */ 6133 fcf_table_count = 0; 6134 fcfp = 0; 6135 fcfp1 = fcftab->table; 6136 for (i = 0; i < fcftab->table_count; i++, fcfp1++) { 6137 if (fcfp1->state == FCFI_STATE_FREE) { 6138 fcfp1->flag &= ~EMLXS_FCFI_TAGGED; 6139 continue; 6140 } 6141 6142 if ((fcfp1->flag & mask) != viable) { 6143 fcfp1->flag &= ~EMLXS_FCFI_TAGGED; 6144 continue; 6145 } 6146 6147 if (fabric_wwn && 6148 bcmp(fabric_wwn, 6149 fcfp1->fcf_rec.fabric_name_identifier, 8)) { 6150 fcfp1->flag &= ~EMLXS_FCFI_TAGGED; 6151 continue; 6152 } 6153 6154 fcfp1->flag |= EMLXS_FCFI_TAGGED; 6155 fcfp = fcfp1; 6156 fcf_table_count++; 6157 } 6158 6159 if (fcf_table_count == 0) { 6160 return (NULL); 6161 } 6162 6163 if (fcf_table_count == 1) { 6164 return (fcfp); 6165 } 6166 6167 /* We found more than one viable entry */ 6168 6169 fcf_table = (FCFIobj_t **)kmem_zalloc( 6170 (sizeof (uintptr_t) * fcf_table_count), KM_SLEEP); 6171 6172 /* Find the highest priority tagged entry(s) */ 6173 for (i = 0; i < fcf_table_count; i++) { 6174 fcfp = 0; 6175 fcfp1 = fcftab->table; 6176 for (j = 0; j < fcftab->table_count; j++, fcfp1++) { 6177 if (!(fcfp1->flag & EMLXS_FCFI_TAGGED)) { 6178 continue; 6179 } 6180 6181 if (!fcfp || 6182 (fcfp1->priority > fcfp->priority)) { 6183 fcfp = fcfp1; 6184 } 6185 } 6186 6187 if (fcf_table[0] && 6188 (fcf_table[0]->priority > fcfp->priority)) { 6189 break; 6190 } 6191 6192 fcfp->flag &= ~EMLXS_FCFI_TAGGED; 6193 fcf_table[i] = fcfp; 6194 } 6195 6196 /* If more than one entry has the highest priority, */ 6197 /* then randomly select one of the highest. */ 6198 if (i > 1) { 6199 /* Pick a random number from 0 to (i-1) */ 6200 /* This algorithm uses the lower 16 bits of the nanosecond */ 6201 /* clock to determine the value */ 6202 bzero(&time, sizeof (timespec_t)); 6203 gethrestime(&time); 6204 rnum = (uint32_t)(time.tv_nsec & 0xFFFF); 6205 6206 fcfp = fcf_table[(rnum%i)]; 6207 } else { 6208 fcfp = fcf_table[0]; 6209 } 6210 6211 /* Free the priority table */ 6212 kmem_free(fcf_table, (sizeof (uintptr_t) * fcf_table_count)); 6213 6214 return (fcfp); 6215 6216 } /* emlxs_fcoe_fcftab_fcfi_select() */ 6217 6218 6219 /*ARGSUSED*/ 6220 static void 6221 emlxs_fcoe_fcftab_process(emlxs_port_t *port) 6222 { 6223 emlxs_hba_t *hba = HBA; 6224 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6225 FCFIobj_t *fcfp; 6226 FCFIobj_t *prev_fcfp; 6227 uint32_t i; 6228 uint32_t j; 6229 uint32_t count; 6230 uint32_t mask; 6231 uint32_t viable; 6232 emlxs_config_t *cfg = &CFG; 6233 6234 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 6235 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH| 6236 EMLXS_FCFI_FAILED); 6237 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 6238 EMLXS_FCFI_CONFIGURED|EMLXS_FCFI_FRESH); 6239 6240 /* Deselection process */ 6241 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) { 6242 fcfp = fcftab->fcfi[i]; 6243 6244 if (!fcfp) { 6245 continue; 6246 } 6247 6248 /* Check if entry is viable */ 6249 if ((fcfp->flag & mask) == viable) { 6250 if (fcfp->offline_timer) { 6251 fcfp->offline_timer = 0; 6252 6253 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6254 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6255 "FCF viable. Offline timer disabled.", 6256 fcftab->TID, 6257 i, fcfp->fcf_index, 6258 emlxs_fcfi_state_xlate(fcfp->state), 6259 cfg[CFG_FCF_FAILOVER_DELAY].current); 6260 } 6261 continue; 6262 } 6263 6264 /* Previous entry is no longer viable */ 6265 6266 /* If FCF is still online */ 6267 if (fcfp->state > FCFI_STATE_OFFLINE) { 6268 if (fcfp->offline_timer == 0) { 6269 /* Set the offline timer */ 6270 fcfp->offline_timer = hba->timer_tics + 6271 cfg[CFG_FCF_FAILOVER_DELAY].current; 6272 6273 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6274 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6275 "No longer viable. " 6276 "Offlining FCF (%d secs).", 6277 fcftab->TID, 6278 i, fcfp->fcf_index, 6279 emlxs_fcfi_state_xlate(fcfp->state), 6280 cfg[CFG_FCF_FAILOVER_DELAY].current); 6281 } 6282 continue; 6283 } 6284 6285 /* Deselect it */ 6286 fcfp->flag &= ~EMLXS_FCFI_SELECTED; 6287 6288 if (!(fcfp->flag & EMLXS_FCFI_FRESH)) { 6289 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6290 "fcoe_fcftab_process:%x %d. " 6291 "No longer viable. Freeing FCFI:%d. >", 6292 fcftab->TID, 6293 i, fcfp->fcf_index); 6294 6295 (void) emlxs_fcfi_free(port, fcfp); 6296 } else { 6297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6298 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6299 "No longer viable. FCF deselected.", 6300 fcftab->TID, 6301 i, fcfp->fcf_index, 6302 emlxs_fcfi_state_xlate(fcfp->state)); 6303 } 6304 } 6305 6306 /* Reselection process */ 6307 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) { 6308 prev_fcfp = fcftab->fcfi[i]; 6309 fcftab->fcfi[i] = NULL; 6310 6311 /* If no previous selection, then make new one */ 6312 if (!prev_fcfp) { 6313 /* Select an fcf on any fabric */ 6314 fcfp = emlxs_fcoe_fcftab_fcfi_select(port, 0); 6315 6316 if (fcfp) { 6317 fcfp->flag |= EMLXS_FCFI_SELECTED; 6318 fcftab->fcfi[i] = fcfp; 6319 6320 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6321 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6322 "New FCF selected.", 6323 fcftab->TID, 6324 i, fcfp->fcf_index, 6325 emlxs_fcfi_state_xlate(fcfp->state)); 6326 } else { 6327 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6328 "fcoe_fcftab_process:%x %d. " 6329 "No FCF available.", 6330 fcftab->TID, 6331 i); 6332 } 6333 continue; 6334 } 6335 6336 /* If previous entry is still selected, keep it */ 6337 if (prev_fcfp->flag & EMLXS_FCFI_SELECTED) { 6338 fcfp = prev_fcfp; 6339 fcftab->fcfi[i] = fcfp; 6340 6341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6342 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6343 "FCF still selected.", 6344 fcftab->TID, 6345 i, fcfp->fcf_index, 6346 emlxs_fcfi_state_xlate(fcfp->state)); 6347 continue; 6348 } 6349 6350 /* Previous entry is no longer selected */ 6351 6352 /* Select a new fcf from same fabric */ 6353 fcfp = emlxs_fcoe_fcftab_fcfi_select(port, 6354 (char *)prev_fcfp->fcf_rec.fabric_name_identifier); 6355 6356 if (fcfp) { 6357 fcfp->flag |= EMLXS_FCFI_SELECTED; 6358 fcftab->fcfi[i] = fcfp; 6359 6360 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6361 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6362 "New FCF, same fabric selected.", 6363 fcftab->TID, 6364 i, fcfp->fcf_index, 6365 emlxs_fcfi_state_xlate(fcfp->state)); 6366 continue; 6367 } 6368 6369 /* Select fcf from any fabric */ 6370 fcfp = emlxs_fcoe_fcftab_fcfi_select(port, 0); 6371 6372 if (fcfp) { 6373 fcfp->flag |= EMLXS_FCFI_SELECTED; 6374 fcftab->fcfi[i] = fcfp; 6375 6376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6377 "fcoe_fcftab_process:%x %d fcfi=%d %s. " 6378 "New FCF, new fabric selected.", 6379 fcftab->TID, 6380 i, fcfp->fcf_index, 6381 emlxs_fcfi_state_xlate(fcfp->state)); 6382 continue; 6383 } 6384 6385 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6386 "fcoe_fcftab_process:%x %d. No FCF available.", 6387 fcftab->TID, 6388 i); 6389 } 6390 6391 /* Pack entries */ 6392 count = 0; 6393 for (i = 0; i < FCFTAB_MAX_FCFI_COUNT; i++) { 6394 if (fcftab->fcfi[i]) { 6395 count++; 6396 continue; 6397 } 6398 6399 for (j = i+1; j < FCFTAB_MAX_FCFI_COUNT; j++) { 6400 if (fcftab->fcfi[j] == NULL) { 6401 continue; 6402 } 6403 6404 fcftab->fcfi[i] = fcftab->fcfi[j]; 6405 fcftab->fcfi[j] = NULL; 6406 count++; 6407 break; 6408 } 6409 6410 if (j == FCFTAB_MAX_FCFI_COUNT) { 6411 break; 6412 } 6413 } 6414 fcftab->fcfi_count = count; 6415 6416 return; 6417 6418 } /* emlxs_fcoe_fcftab_process() */ 6419 6420 6421 /*ARGSUSED*/ 6422 static uint32_t 6423 emlxs_fcoe_fcftab_fcfi_online_action(emlxs_port_t *port, uint32_t evt, 6424 void *arg1) 6425 { 6426 emlxs_hba_t *hba = HBA; 6427 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6428 FCFIobj_t *fcfp; 6429 uint32_t rval = 0; 6430 uint32_t i; 6431 uint32_t offline_count = 0; 6432 uint32_t online_count = 0; 6433 6434 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_ONLINE) { 6435 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6436 "fcoe_fcftab_fcfi_online_action:%x %s:%s arg=%p. " 6437 "Invalid state. <", 6438 fcftab->TID, 6439 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6440 emlxs_fcf_event_xlate(evt), arg1); 6441 return (1); 6442 } 6443 6444 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 6445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6446 "fcoe_fcftab_fcfi_online_action:%x flag=%x. " 6447 "Handling request.", 6448 fcftab->TID, 6449 fcftab->flag); 6450 6451 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 6452 return (rval); 6453 } 6454 6455 emlxs_fcoe_fcftab_process(port); 6456 6457 for (i = 0; i < fcftab->fcfi_count; i++) { 6458 fcfp = fcftab->fcfi[i]; 6459 6460 if (fcfp->offline_timer == 0) { 6461 online_count++; 6462 6463 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6464 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d. " 6465 "Onlining FCFI:%d. >", 6466 fcftab->TID, 6467 fcftab->fcfi_count, 6468 fcfp->fcf_index); 6469 6470 (void) emlxs_fcfi_event(port, FCF_EVENT_FCFI_ONLINE, 6471 fcfp); 6472 } else { 6473 offline_count++; 6474 6475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6476 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d. " 6477 "Offlining fcfi:%d.", 6478 fcftab->TID, 6479 fcftab->fcfi_count, 6480 fcfp->fcf_index); 6481 } 6482 } 6483 6484 if (offline_count) { 6485 /* Wait for FCF's to go offline */ 6486 rval = emlxs_fcoe_fcftab_state(port, 6487 FCOE_FCFTAB_STATE_FCFI_OFFLINE, 6488 FCF_REASON_EVENT, evt, arg1); 6489 6490 /* Service timer now */ 6491 emlxs_fcoe_fcftab_offline_timer(hba); 6492 6493 return (rval); 6494 } 6495 6496 if (!online_count) { 6497 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6498 "fcoe_fcftab_fcfi_online_action:%x fcfi_count=%d.", 6499 fcftab->TID, 6500 fcftab->fcfi_count); 6501 } 6502 6503 rval = emlxs_fcoe_fcftab_state(port, 6504 FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL, 6505 FCF_REASON_EVENT, evt, arg1); 6506 6507 return (rval); 6508 6509 } /* emlxs_fcoe_fcftab_fcfi_online_action() */ 6510 6511 6512 /*ARGSUSED*/ 6513 static uint32_t 6514 emlxs_fcoe_fcftab_fcfi_online_cmpl_action(emlxs_port_t *port, uint32_t evt, 6515 void *arg1) 6516 { 6517 emlxs_hba_t *hba = HBA; 6518 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6519 uint32_t rval = 0; 6520 6521 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_ONLINE_CMPL) { 6522 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 6523 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. " 6524 "Invalid state. <", 6525 fcftab->TID, 6526 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6527 emlxs_fcf_event_xlate(evt), arg1); 6528 return (1); 6529 } 6530 6531 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 6532 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6533 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s " 6534 "arg=%p flag=%x. Handling request.", 6535 fcftab->TID, 6536 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6537 emlxs_fcf_event_xlate(evt), arg1, 6538 fcftab->flag); 6539 6540 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 6541 return (rval); 6542 } 6543 6544 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6545 "fcoe_fcftab_fcfi_online_cmpl_action:%x %s:%s arg=%p. " 6546 "Going online.", 6547 fcftab->TID, 6548 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6549 emlxs_fcf_event_xlate(evt), arg1); 6550 6551 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_ONLINE, 6552 FCF_REASON_EVENT, evt, arg1); 6553 6554 return (rval); 6555 6556 } /* emlxs_fcoe_fcftab_fcfi_online_cmpl_action() */ 6557 6558 6559 /*ARGSUSED*/ 6560 static uint32_t 6561 emlxs_fcoe_fcftab_fcfi_offline_action(emlxs_port_t *port, uint32_t evt, 6562 void *arg1) 6563 { 6564 emlxs_hba_t *hba = HBA; 6565 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6566 FCFIobj_t *fcfp; 6567 uint32_t rval = 0; 6568 int32_t i; 6569 uint32_t fcfi_offline; 6570 6571 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_OFFLINE) { 6572 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 6573 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p. " 6574 "Invalid state. <", 6575 fcftab->TID, 6576 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6577 emlxs_fcf_event_xlate(evt), arg1); 6578 return (1); 6579 } 6580 6581 /* Check for FCF's going offline */ 6582 fcfi_offline = 0; 6583 for (i = 0; i < fcftab->fcfi_count; i++) { 6584 fcfp = fcftab->fcfi[i]; 6585 6586 if (fcfp->state <= FCFI_STATE_OFFLINE) { 6587 continue; 6588 } 6589 6590 if (fcfp->offline_timer || 6591 (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) { 6592 fcfi_offline++; 6593 } 6594 } 6595 6596 if (fcfi_offline) { 6597 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6598 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p " 6599 "fcfi_offline=%d. <", 6600 fcftab->TID, 6601 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6602 emlxs_fcf_event_xlate(evt), arg1, 6603 fcfi_offline); 6604 6605 return (0); 6606 } 6607 6608 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6609 "fcoe_fcftab_fcfi_offline_action:%x %s:%s arg=%p.", 6610 fcftab->TID, 6611 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6612 emlxs_fcf_event_xlate(evt), arg1); 6613 6614 rval = emlxs_fcoe_fcftab_state(port, 6615 FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL, 6616 FCF_REASON_EVENT, evt, arg1); 6617 6618 return (rval); 6619 6620 } /* emlxs_fcoe_fcftab_fcfi_offline_action() */ 6621 6622 6623 /*ARGSUSED*/ 6624 static uint32_t 6625 emlxs_fcoe_fcftab_fcfi_offline_cmpl_action(emlxs_port_t *port, uint32_t evt, 6626 void *arg1) 6627 { 6628 emlxs_hba_t *hba = HBA; 6629 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6630 uint32_t rval = 0; 6631 6632 if (fcftab->state != FCOE_FCFTAB_STATE_FCFI_OFFLINE_CMPL) { 6633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 6634 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. " 6635 "Invalid state. <", 6636 fcftab->TID, 6637 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6638 emlxs_fcf_event_xlate(evt), arg1); 6639 return (1); 6640 } 6641 6642 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 6643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6644 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. " 6645 "Handling request.", 6646 fcftab->TID, 6647 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6648 emlxs_fcf_event_xlate(evt), arg1); 6649 6650 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 6651 return (rval); 6652 } 6653 6654 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6655 "fcoe_fcftab_fcfi_offline_cmpl_action:%x %s:%s arg=%p. " 6656 "Returning FCF(s) online.", 6657 fcftab->TID, 6658 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6659 emlxs_fcf_event_xlate(evt), arg1); 6660 6661 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_FCFI_ONLINE, 6662 FCF_REASON_EVENT, evt, arg1); 6663 6664 return (rval); 6665 6666 } /* emlxs_fcoe_fcftab_fcfi_offline_cmpl_action() */ 6667 6668 6669 /*ARGSUSED*/ 6670 static uint32_t 6671 emlxs_fcoe_fcftab_found_evt_action(emlxs_port_t *port, uint32_t evt, 6672 void *arg1) 6673 { 6674 emlxs_hba_t *hba = HBA; 6675 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6676 uint32_t fcf_index = (uint32_t)((unsigned long)arg1); 6677 FCFIobj_t *fcfp; 6678 uint32_t rval = 0; 6679 6680 if (evt != FCF_EVENT_FCF_FOUND) { 6681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6682 "fcoe_fcftab_found_evt_action:%x %s:%s fcf_index=%d. " 6683 "Invalid event type. <", 6684 fcftab->TID, 6685 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6686 emlxs_fcf_event_xlate(evt), 6687 fcf_index); 6688 6689 return (1); 6690 } 6691 6692 switch (fcftab->state) { 6693 case FCOE_FCFTAB_STATE_SOLICIT: 6694 case FCOE_FCFTAB_STATE_SOLICIT_CMPL: 6695 case FCOE_FCFTAB_STATE_READ: 6696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6697 "fcoe_fcftab_found_evt_action:%x %s:%s " 6698 "fcf_index=%d gen=%x. <", 6699 fcftab->TID, 6700 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6701 emlxs_fcf_event_xlate(evt), 6702 fcf_index, fcftab->generation); 6703 break; 6704 6705 /* case FCOE_FCFTAB_STATE_FCFI_OFFLINE: */ 6706 default: 6707 6708 /* Scan for matching fcf index in table */ 6709 fcfp = emlxs_fcfi_find(port, 0, &fcf_index); 6710 6711 if (fcfp && (fcfp->flag & EMLXS_FCFI_SELECTED)) { 6712 6713 /* Trigger table read */ 6714 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 6715 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ; 6716 fcftab->generation++; 6717 6718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6719 "fcoe_fcftab_found_evt_action:%x %s:%s " 6720 "fcf_index=%d gen=%x. Read FCF table.", 6721 fcftab->TID, 6722 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6723 emlxs_fcf_event_xlate(evt), 6724 fcf_index, fcftab->generation); 6725 6726 rval = emlxs_fcoe_fcftab_state(port, 6727 FCOE_FCFTAB_STATE_READ, 6728 FCF_REASON_EVENT, evt, arg1); 6729 6730 break; 6731 } 6732 6733 /* Check if we need more FCF's */ 6734 if (fcftab->fcfi_online < FCFTAB_MAX_FCFI_COUNT) { 6735 6736 /* Trigger table read */ 6737 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 6738 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ; 6739 fcftab->generation++; 6740 6741 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6742 "fcoe_fcftab_found_evt_action:%x %s:%s " 6743 "fcf_index=%d gen=%x fcfi_online=%d. " 6744 "Read FCF table.", 6745 fcftab->TID, 6746 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6747 emlxs_fcf_event_xlate(evt), 6748 fcf_index, fcftab->generation, 6749 fcftab->fcfi_online); 6750 6751 rval = emlxs_fcoe_fcftab_state(port, 6752 FCOE_FCFTAB_STATE_READ, 6753 FCF_REASON_EVENT, evt, arg1); 6754 6755 break; 6756 } 6757 6758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6759 "fcoe_fcftab_found_evt_action:%x %s:%s fcfi=%d. " 6760 "FCF not needed. <", 6761 fcftab->TID, 6762 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6763 emlxs_fcf_event_xlate(evt), 6764 fcf_index); 6765 6766 break; 6767 } 6768 6769 return (rval); 6770 6771 } /* emlxs_fcoe_fcftab_found_evt_action() */ 6772 6773 6774 /*ARGSUSED*/ 6775 static uint32_t 6776 emlxs_fcoe_fcftab_lost_evt_action(emlxs_port_t *port, uint32_t evt, 6777 void *arg1) 6778 { 6779 emlxs_hba_t *hba = HBA; 6780 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6781 FCFIobj_t *fcfp; 6782 uint32_t fcf_index = (uint32_t)((unsigned long)arg1); 6783 emlxs_port_t *vport; 6784 VPIobj_t *vpip; 6785 uint32_t i; 6786 uint32_t rval = 0; 6787 6788 if (evt != FCF_EVENT_FCF_LOST) { 6789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6790 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d. " 6791 "Invalid event type. <", 6792 fcftab->TID, 6793 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6794 emlxs_fcf_event_xlate(evt), 6795 fcf_index); 6796 6797 return (1); 6798 } 6799 6800 /* Scan for matching fcf index in table */ 6801 fcfp = emlxs_fcfi_find(port, 0, &fcf_index); 6802 6803 if (!fcfp) { 6804 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6805 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d. " 6806 "FCF not found. <", 6807 fcftab->TID, 6808 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6809 emlxs_fcf_event_xlate(evt), 6810 fcf_index); 6811 6812 return (0); 6813 } 6814 6815 if (!(fcfp->flag & EMLXS_FCFI_SELECTED)) { 6816 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6817 "fcoe_fcftab_changed_evt_action:%x %s:%s fcf_index=%d. " 6818 "FCF not selected. <", 6819 fcftab->TID, 6820 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6821 emlxs_fcf_event_xlate(evt), 6822 fcf_index); 6823 6824 return (0); 6825 } 6826 6827 /* Offline VPI's of this FCFI */ 6828 for (i = 0; i <= hba->vpi_max; i++) { 6829 vport = &VPORT(i); 6830 vpip = vport->vpip; 6831 6832 if ((vpip->state == VPI_STATE_OFFLINE) || 6833 (vpip->vfip->fcfp != fcfp)) { 6834 continue; 6835 } 6836 6837 /* Fabric logo is implied */ 6838 emlxs_vpi_logo_handler(port, vpip); 6839 6840 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6841 "fcoe_fcftab_lost_evt_action:%x %s:%s fcf_index=%d gen=%x. " 6842 "Offlining VPI:%d. >", 6843 fcftab->TID, 6844 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6845 emlxs_fcf_event_xlate(evt), 6846 fcf_index, fcftab->generation, 6847 vpip->VPI); 6848 6849 (void) emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 6850 } 6851 6852 switch (fcftab->state) { 6853 case FCOE_FCFTAB_STATE_SOLICIT: 6854 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6855 "fcoe_fcftab_lost_evt_action:%x %s gen=%x. " 6856 "Already soliciting. <", 6857 fcftab->TID, 6858 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6859 fcftab->generation); 6860 break; 6861 6862 default: 6863 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 6864 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ; 6865 fcftab->generation++; 6866 6867 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6868 "fcoe_fcftab_lost_evt_action:%x %s gen=%x. Soliciting.", 6869 fcftab->TID, 6870 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6871 fcftab->generation); 6872 6873 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 6874 FCF_REASON_EVENT, evt, arg1); 6875 break; 6876 } 6877 6878 return (rval); 6879 6880 } /* emlxs_fcoe_fcftab_lost_evt_action() */ 6881 6882 6883 /*ARGSUSED*/ 6884 static uint32_t 6885 emlxs_fcoe_fcftab_changed_evt_action(emlxs_port_t *port, uint32_t evt, 6886 void *arg1) 6887 { 6888 emlxs_hba_t *hba = HBA; 6889 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6890 FCFIobj_t *fcfp; 6891 uint32_t fcf_index = (uint32_t)((unsigned long)arg1); 6892 uint32_t rval = 0; 6893 6894 if (evt != FCF_EVENT_FCF_CHANGED) { 6895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6896 "fcoe_fcftab_changed_evt_action:%x %s:%s fcf_index=%d. " 6897 "Invalid event type. <", 6898 fcftab->TID, 6899 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6900 emlxs_fcf_event_xlate(evt), 6901 fcf_index); 6902 6903 return (1); 6904 } 6905 6906 switch (fcftab->state) { 6907 case FCOE_FCFTAB_STATE_SOLICIT: 6908 case FCOE_FCFTAB_STATE_SOLICIT_CMPL: 6909 case FCOE_FCFTAB_STATE_READ: 6910 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6911 "fcoe_fcftab_changed_evt_action:%x %s:%s " 6912 "fcf_index=%d gen=%x. <", 6913 fcftab->TID, 6914 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6915 emlxs_fcf_event_xlate(evt), 6916 fcf_index, fcftab->generation); 6917 break; 6918 6919 /* case FCOE_FCFTAB_STATE_FCFI_OFFLINE: */ 6920 default: 6921 6922 /* Scan for matching fcf index in table */ 6923 fcfp = emlxs_fcfi_find(port, 0, &fcf_index); 6924 6925 if (fcfp && (fcfp->flag & EMLXS_FCFI_SELECTED)) { 6926 6927 /* Trigger table read */ 6928 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 6929 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ; 6930 fcftab->generation++; 6931 6932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6933 "fcoe_fcftab_changed_evt_action:%x %s:%s " 6934 "fcf_index=%d gen=%x. Read FCF table.", 6935 fcftab->TID, 6936 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6937 emlxs_fcf_event_xlate(evt), 6938 fcf_index, fcftab->generation); 6939 6940 rval = emlxs_fcoe_fcftab_state(port, 6941 FCOE_FCFTAB_STATE_READ, 6942 FCF_REASON_EVENT, evt, arg1); 6943 6944 break; 6945 } 6946 6947 /* Check if we need more FCF's */ 6948 if (fcftab->fcfi_online < FCFTAB_MAX_FCFI_COUNT) { 6949 6950 /* Trigger table read */ 6951 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 6952 fcftab->flag |= EMLXS_FCOE_FCFTAB_READ_REQ; 6953 fcftab->generation++; 6954 6955 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6956 "fcoe_fcftab_changed_evt_action:%x %s:%s " 6957 "fcf_index=%d gen=%x fcfi_online=%d. " 6958 "Read FCF table.", 6959 fcftab->TID, 6960 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6961 emlxs_fcf_event_xlate(evt), 6962 fcf_index, fcftab->generation, 6963 fcftab->fcfi_online); 6964 6965 rval = emlxs_fcoe_fcftab_state(port, 6966 FCOE_FCFTAB_STATE_READ, 6967 FCF_REASON_EVENT, evt, arg1); 6968 6969 break; 6970 } 6971 6972 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 6973 "fcoe_fcftab_changed_evt_action:%x %s:%s fcfi=%d. " 6974 "FCF not needed. <", 6975 fcftab->TID, 6976 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 6977 emlxs_fcf_event_xlate(evt), 6978 fcf_index); 6979 6980 break; 6981 } 6982 6983 return (rval); 6984 6985 } /* emlxs_fcoe_fcftab_changed_evt_action() */ 6986 6987 6988 /*ARGSUSED*/ 6989 static uint32_t 6990 emlxs_fcoe_fcftab_fcf_delete(emlxs_port_t *port, uint32_t fcf_index) 6991 { 6992 emlxs_hba_t *hba = HBA; 6993 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 6994 MAILBOXQ *mbq; 6995 MAILBOX4 *mb4; 6996 MATCHMAP *mp = NULL; 6997 uint32_t rval = 0; 6998 6999 IOCTL_FCOE_DELETE_FCF_TABLE *fcf; 7000 mbox_req_hdr_t *hdr_req; 7001 7002 if (fcf_index >= fcftab->fcfi_count) { 7003 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7004 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. " 7005 "Out of range.", 7006 fcftab->TID, 7007 fcf_index); 7008 7009 return (1); 7010 } 7011 7012 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 7013 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7014 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. " 7015 "Unable to allocate mailbox.", 7016 fcftab->TID, 7017 fcf_index); 7018 7019 return (1); 7020 } 7021 7022 mb4 = (MAILBOX4*)mbq; 7023 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 7024 7025 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 7026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7027 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. " 7028 "Unable to allocate buffer.", 7029 fcftab->TID, 7030 fcf_index); 7031 7032 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 7033 return (1); 7034 } 7035 bzero(mp->virt, mp->size); 7036 7037 mbq->nonembed = (void *)mp; 7038 mbq->mbox_cmpl = NULL; 7039 mbq->context = (void *)((unsigned long)fcf_index); 7040 mbq->port = (void *)port; 7041 7042 mb4->un.varSLIConfig.be.embedded = 0; 7043 mb4->mbxCommand = MBX_SLI_CONFIG; 7044 mb4->mbxOwner = OWN_HOST; 7045 7046 hdr_req = (mbox_req_hdr_t *)mp->virt; 7047 hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 7048 hdr_req->opcode = FCOE_OPCODE_DELETE_FCF_TABLE; 7049 hdr_req->timeout = 0; 7050 hdr_req->req_length = sizeof (IOCTL_FCOE_DELETE_FCF_TABLE); 7051 7052 fcf = (IOCTL_FCOE_DELETE_FCF_TABLE *)(hdr_req + 1); 7053 fcf->params.request.fcf_count = 1; 7054 fcf->params.request.fcf_indexes[0] = (uint16_t)fcf_index; 7055 7056 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7057 "fcoe_fcftab_fcf_delete:%x fcfi:%d. <", 7058 fcftab->TID, 7059 fcf_index); 7060 7061 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 7062 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 7063 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7064 "fcoe_fcftab_fcf_delete:%x fcfi:%d failed. " 7065 "Unable to send request.", 7066 fcftab->TID, 7067 fcf_index); 7068 7069 if (mp) { 7070 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 7071 } 7072 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 7073 7074 return (1); 7075 } 7076 7077 return (0); 7078 7079 7080 } /* emlxs_fcoe_fcftab_fcf_delete() */ 7081 7082 7083 /*ARGSUSED*/ 7084 static uint32_t 7085 emlxs_fcoe_fcftab_full_evt_action(emlxs_port_t *port, uint32_t evt, 7086 void *arg1) 7087 { 7088 emlxs_hba_t *hba = HBA; 7089 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7090 FCFIobj_t *fcfp; 7091 uint32_t rval = 0; 7092 uint32_t mask; 7093 uint32_t viable; 7094 uint32_t i; 7095 uint32_t count; 7096 7097 if (evt != FCF_EVENT_FCFTAB_FULL) { 7098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7099 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p. " 7100 "Invalid event type. <", 7101 fcftab->TID, 7102 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7103 emlxs_fcf_event_xlate(evt), arg1); 7104 7105 return (1); 7106 } 7107 7108 if (fcftab->fcfi_online == FCFTAB_MAX_FCFI_COUNT) { 7109 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7110 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p " 7111 "fcfi_online=%d. <", 7112 fcftab->TID, 7113 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7114 emlxs_fcf_event_xlate(evt), arg1, 7115 fcftab->fcfi_online); 7116 7117 return (0); 7118 } 7119 7120 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7121 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p fcfi_online=%d. " 7122 "Cleaning table...", 7123 fcftab->TID, 7124 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7125 emlxs_fcf_event_xlate(evt), arg1, 7126 fcftab->fcfi_online); 7127 7128 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 7129 EMLXS_FCFI_CONFIGURED); 7130 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 7131 EMLXS_FCFI_CONFIGURED); 7132 7133 count = 0; 7134 fcfp = fcftab->table; 7135 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 7136 if (fcfp->state == FCFI_STATE_FREE) { 7137 continue; 7138 } 7139 7140 if (fcfp->flag & EMLXS_FCFI_SELECTED) { 7141 continue; 7142 } 7143 7144 if ((fcfp->flag & mask) == viable) { 7145 continue; 7146 } 7147 7148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7149 "fcoe_fcftab_full_evt_action:%x. " 7150 "Deleting FCFI:%d %x. >", 7151 fcftab->TID, 7152 fcfp->fcf_index, 7153 fcfp->flag); 7154 7155 (void) emlxs_fcfi_free(port, fcfp); 7156 7157 (void) emlxs_fcoe_fcftab_fcf_delete(port, fcfp->fcf_index); 7158 7159 count++; 7160 } 7161 7162 if (!count) { 7163 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7164 "fcoe_fcftab_full_evt_action:%x %s:%s arg=%p. " 7165 "All FCF's are viable. <", 7166 fcftab->TID, 7167 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7168 emlxs_fcf_event_xlate(evt), arg1); 7169 7170 return (0); 7171 } 7172 7173 switch (fcftab->state) { 7174 case FCOE_FCFTAB_STATE_SOLICIT: 7175 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7176 "fcoe_fcftab_full_evt_action:%x %s gen=%x. " 7177 "Already soliciting. <", 7178 fcftab->TID, 7179 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7180 fcftab->generation); 7181 break; 7182 7183 default: 7184 fcftab->flag &= ~EMLXS_FCFTAB_REQ_MASK; 7185 fcftab->flag |= EMLXS_FCOE_FCFTAB_SOL_REQ; 7186 fcftab->generation++; 7187 7188 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7189 "fcoe_fcftab_full_evt_action:%x %s gen=%x. Soliciting.", 7190 fcftab->TID, 7191 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7192 fcftab->generation); 7193 7194 rval = emlxs_fcoe_fcftab_state(port, FCOE_FCFTAB_STATE_SOLICIT, 7195 FCF_REASON_EVENT, evt, arg1); 7196 break; 7197 } 7198 7199 return (rval); 7200 7201 } /* emlxs_fcoe_fcftab_full_evt_action() */ 7202 7203 7204 /*ARGSUSED*/ 7205 static uint32_t 7206 emlxs_fcoe_fcftab_online_action(emlxs_port_t *port, uint32_t evt, 7207 void *arg1) 7208 { 7209 emlxs_hba_t *hba = HBA; 7210 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7211 emlxs_config_t *cfg = &CFG; 7212 FCFIobj_t *fcfp; 7213 uint32_t rval = 0; 7214 uint32_t mask; 7215 uint32_t viable; 7216 uint32_t i; 7217 uint32_t count = 0; 7218 7219 if (fcftab->state != FCOE_FCFTAB_STATE_ONLINE) { 7220 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7221 "fcoe_fcftab_online_action:%x %s:%s arg=%p. " 7222 "Invalid state. <", 7223 fcftab->TID, 7224 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7225 emlxs_fcf_event_xlate(evt), arg1); 7226 return (1); 7227 } 7228 7229 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 7230 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7231 "fcoe_fcftab_online_action:%x flag=%x. " 7232 "Handling request.", 7233 fcftab->TID, 7234 fcftab->flag); 7235 7236 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 7237 return (rval); 7238 } 7239 7240 if (fcftab->fcfi_online == 0) { 7241 mask = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 7242 EMLXS_FCFI_CONFIGURED); 7243 viable = (EMLXS_FCFI_VALID|EMLXS_FCFI_AVAILABLE| 7244 EMLXS_FCFI_CONFIGURED); 7245 7246 /* Count viable FCF's in table */ 7247 count = 0; 7248 fcfp = fcftab->table; 7249 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 7250 if (fcfp->state == FCFI_STATE_FREE) { 7251 continue; 7252 } 7253 7254 if ((fcfp->flag & mask) == viable) { 7255 count++; 7256 } 7257 } 7258 7259 if (count) { 7260 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7261 "fcoe_fcftab_online_action:%x %s:%s " 7262 "fcfi_online=0,%d,%d. Starting resolicit timer. <", 7263 fcftab->TID, 7264 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7265 emlxs_fcf_event_xlate(evt), 7266 fcftab->fcfi_count, count); 7267 7268 /* Start the solicit timer */ 7269 fcftab->sol_timer = hba->timer_tics + 7270 cfg[CFG_FCF_RESOLICIT_DELAY].current; 7271 } else { 7272 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7273 "fcoe_fcftab_online_action:%x %s:%s " 7274 "fcfi_online=0,%d,0. Wait for FCF event. <", 7275 fcftab->TID, 7276 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7277 emlxs_fcf_event_xlate(evt), 7278 fcftab->fcfi_count); 7279 } 7280 7281 emlxs_fcf_linkdown(port); 7282 7283 return (0); 7284 } 7285 7286 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7287 "fcoe_fcftab_online_action:%x flag=%x fcfi_online=%d. " 7288 "Online. <", 7289 fcftab->TID, 7290 fcftab->flag, 7291 fcftab->fcfi_online); 7292 7293 emlxs_fcf_linkup(port); 7294 7295 return (rval); 7296 7297 } /* emlxs_fcoe_fcftab_online_action() */ 7298 7299 7300 /*ARGSUSED*/ 7301 static uint32_t 7302 emlxs_fcoe_fcftab_offline_action(emlxs_port_t *port, uint32_t evt, 7303 void *arg1) 7304 { 7305 emlxs_hba_t *hba = HBA; 7306 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7307 uint32_t rval = 0; 7308 7309 if (fcftab->state != FCOE_FCFTAB_STATE_OFFLINE) { 7310 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7311 "fcoe_fcftab_offline_action:%x %s:%s arg=%p. " 7312 "Invalid state. <", 7313 fcftab->TID, 7314 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7315 emlxs_fcf_event_xlate(evt), arg1); 7316 return (1); 7317 } 7318 7319 7320 fcftab->flag &= ~EMLXS_FCOE_FCFTAB_OFFLINE_REQ; 7321 7322 if (fcftab->flag & EMLXS_FCFTAB_REQ_MASK) { 7323 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7324 "fcoe_fcftab_offline_action:%x %s:%s arg=%p flag=%x. " 7325 "Handling request.", 7326 fcftab->TID, 7327 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7328 emlxs_fcf_event_xlate(evt), arg1, 7329 fcftab->flag); 7330 7331 rval = emlxs_fcoe_fcftab_req_handler(port, arg1); 7332 return (rval); 7333 } 7334 7335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7336 "fcoe_fcftab_offline_action:%x %s:%s arg=%p fcfi_online=%d. " 7337 "Offline. <", 7338 fcftab->TID, 7339 emlxs_fcoe_fcftab_state_xlate(fcftab->state), 7340 emlxs_fcf_event_xlate(evt), arg1, 7341 fcftab->fcfi_online); 7342 7343 return (rval); 7344 7345 } /* emlxs_fcoe_fcftab_offline_action() */ 7346 7347 7348 /* ************************************************************************** */ 7349 /* FCFI */ 7350 /* ************************************************************************** */ 7351 7352 static char * 7353 emlxs_fcfi_state_xlate(uint32_t state) 7354 { 7355 static char buffer[32]; 7356 uint32_t i; 7357 uint32_t count; 7358 7359 count = sizeof (emlxs_fcfi_state_table) / sizeof (emlxs_table_t); 7360 for (i = 0; i < count; i++) { 7361 if (state == emlxs_fcfi_state_table[i].code) { 7362 return (emlxs_fcfi_state_table[i].string); 7363 } 7364 } 7365 7366 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 7367 return (buffer); 7368 7369 } /* emlxs_fcfi_state_xlate() */ 7370 7371 7372 static uint32_t 7373 emlxs_fcfi_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 7374 void *arg1) 7375 { 7376 uint32_t rval = 0; 7377 uint32_t(*func) (emlxs_port_t *, FCFIobj_t *, uint32_t, void *); 7378 uint32_t index; 7379 uint32_t events; 7380 uint16_t state; 7381 7382 /* Convert event to action table index */ 7383 switch (evt) { 7384 case FCF_EVENT_STATE_ENTER: 7385 index = 0; 7386 break; 7387 case FCF_EVENT_FCFI_ONLINE: 7388 index = 1; 7389 break; 7390 case FCF_EVENT_FCFI_OFFLINE: 7391 index = 2; 7392 break; 7393 case FCF_EVENT_FCFI_PAUSE: 7394 index = 3; 7395 break; 7396 case FCF_EVENT_VFI_ONLINE: 7397 index = 4; 7398 break; 7399 case FCF_EVENT_VFI_OFFLINE: 7400 index = 5; 7401 break; 7402 default: 7403 return (1); 7404 } 7405 7406 events = FCFI_ACTION_EVENTS; 7407 state = fcfp->state; 7408 7409 index += (state * events); 7410 func = (uint32_t(*) (emlxs_port_t *, FCFIobj_t *, uint32_t, void *)) 7411 emlxs_fcfi_action_table[index]; 7412 7413 if (!func) { 7414 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 7415 "fcfi_action:%d %s:%s arg=%p. No action. <", 7416 fcfp->fcf_index, 7417 emlxs_fcfi_state_xlate(fcfp->state), 7418 emlxs_fcf_event_xlate(evt), arg1); 7419 7420 return (1); 7421 } 7422 7423 rval = (func)(port, fcfp, evt, arg1); 7424 7425 return (rval); 7426 7427 } /* emlxs_fcfi_action() */ 7428 7429 7430 static uint32_t 7431 emlxs_fcfi_event(emlxs_port_t *port, uint32_t evt, 7432 void *arg1) 7433 { 7434 FCFIobj_t *fcfp = NULL; 7435 VFIobj_t *vfip = NULL; 7436 uint32_t rval = 0; 7437 7438 /* Filter events and acquire fcfi context */ 7439 switch (evt) { 7440 case FCF_EVENT_VFI_ONLINE: 7441 case FCF_EVENT_VFI_OFFLINE: 7442 vfip = (VFIobj_t *)arg1; 7443 7444 if (!vfip) { 7445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 7446 "fcfi_event: %s arg=%p. Null VFI found. <", 7447 emlxs_fcf_event_xlate(evt), arg1); 7448 7449 return (1); 7450 } 7451 7452 fcfp = vfip->fcfp; 7453 if (!fcfp) { 7454 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 7455 "fcfi_event: %s arg=%p. FCF not found. <", 7456 emlxs_fcf_event_xlate(evt), arg1); 7457 7458 return (1); 7459 } 7460 break; 7461 7462 case FCF_EVENT_FCFI_ONLINE: 7463 case FCF_EVENT_FCFI_OFFLINE: 7464 case FCF_EVENT_FCFI_PAUSE: 7465 fcfp = (FCFIobj_t *)arg1; 7466 if (!fcfp) { 7467 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 7468 "fcfi_event: %s arg=%p. Null FCFI found. <", 7469 emlxs_fcf_event_xlate(evt), arg1); 7470 7471 return (1); 7472 } 7473 break; 7474 7475 default: 7476 return (1); 7477 } 7478 7479 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 7480 "fcfi_event:%d %s:%s arg=%p", 7481 fcfp->fcf_index, 7482 emlxs_fcfi_state_xlate(fcfp->state), 7483 emlxs_fcf_event_xlate(evt), arg1); 7484 7485 rval = emlxs_fcfi_action(port, fcfp, evt, arg1); 7486 7487 return (rval); 7488 7489 } /* emlxs_fcfi_event() */ 7490 7491 7492 /* EMLXS_FCF_LOCK must be held to enter */ 7493 /*ARGSUSED*/ 7494 static uint32_t 7495 emlxs_fcfi_state(emlxs_port_t *port, FCFIobj_t *fcfp, uint16_t state, 7496 uint16_t reason, uint32_t explain, void *arg1) 7497 { 7498 uint32_t rval = 0; 7499 7500 if (state >= FCFI_ACTION_STATES) { 7501 return (1); 7502 } 7503 7504 if ((fcfp->state == state) && 7505 (reason != FCF_REASON_REENTER)) { 7506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7507 "fcfi_state:%d %s:%s:0x%x arg=%p. " 7508 "State not changed. <", 7509 fcfp->fcf_index, 7510 emlxs_fcfi_state_xlate(state), 7511 emlxs_fcf_reason_xlate(reason), 7512 explain, arg1); 7513 return (1); 7514 } 7515 7516 if (!reason) { 7517 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 7518 "fcfi_state:%d %s-->%s arg=%p", 7519 fcfp->fcf_index, 7520 emlxs_fcfi_state_xlate(fcfp->state), 7521 emlxs_fcfi_state_xlate(state), arg1); 7522 } else if (reason == FCF_REASON_EVENT) { 7523 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 7524 "fcfi_state:%d %s-->%s:%s:%s arg=%p", 7525 fcfp->fcf_index, 7526 emlxs_fcfi_state_xlate(fcfp->state), 7527 emlxs_fcfi_state_xlate(state), 7528 emlxs_fcf_reason_xlate(reason), 7529 emlxs_fcf_event_xlate(explain), arg1); 7530 } else if (explain) { 7531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 7532 "fcfi_state:%d %s-->%s:%s:0x%x arg=%p", 7533 fcfp->fcf_index, 7534 emlxs_fcfi_state_xlate(fcfp->state), 7535 emlxs_fcfi_state_xlate(state), 7536 emlxs_fcf_reason_xlate(reason), 7537 explain, arg1); 7538 } else { 7539 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 7540 "fcfi_state:%d %s-->%s:%s arg=%p", 7541 fcfp->fcf_index, 7542 emlxs_fcfi_state_xlate(fcfp->state), 7543 emlxs_fcfi_state_xlate(state), 7544 emlxs_fcf_reason_xlate(reason), arg1); 7545 } 7546 7547 fcfp->prev_state = fcfp->state; 7548 fcfp->prev_reason = fcfp->reason; 7549 fcfp->state = state; 7550 fcfp->reason = reason; 7551 7552 rval = emlxs_fcfi_action(port, fcfp, FCF_EVENT_STATE_ENTER, arg1); 7553 7554 return (rval); 7555 7556 } /* emlxs_fcfi_state() */ 7557 7558 7559 static FCFIobj_t * 7560 emlxs_fcfi_alloc(emlxs_port_t *port) 7561 { 7562 emlxs_hba_t *hba = HBA; 7563 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7564 uint16_t i; 7565 FCFIobj_t *fcfp; 7566 7567 fcfp = fcftab->table; 7568 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 7569 if (fcfp->state == FCFI_STATE_FREE) { 7570 7571 bzero(fcfp, sizeof (FCFIobj_t)); 7572 fcfp->index = i; 7573 fcfp->FCFI = 0xFFFF; 7574 7575 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7576 "fcfi_alloc:%d. Allocating FCFI. >", 7577 fcfp->index); 7578 7579 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE, 7580 0, 0, 0); 7581 return (fcfp); 7582 } 7583 } 7584 7585 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7586 "fcfi_alloc: Out of FCFI objects.", 7587 fcfp->index); 7588 7589 return (NULL); 7590 7591 } /* emlxs_fcfi_alloc() */ 7592 7593 7594 static uint32_t 7595 emlxs_fcfi_free(emlxs_port_t *port, FCFIobj_t *fcfp) 7596 { 7597 uint32_t rval = 0; 7598 7599 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_FREE, 0, 0, 0); 7600 7601 return (rval); 7602 7603 } /* emlxs_fcfi_free() */ 7604 7605 7606 static FCFIobj_t * 7607 emlxs_fcfi_find(emlxs_port_t *port, FCF_RECORD_t *fcfrec, uint32_t *fcf_index) 7608 { 7609 emlxs_hba_t *hba = HBA; 7610 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7611 uint32_t i; 7612 uint32_t index; 7613 FCFIobj_t *fcfp; 7614 7615 if (fcfrec) { 7616 /* Check for a matching FCF index, fabric name, */ 7617 /* and mac address */ 7618 fcfp = fcftab->table; 7619 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 7620 if (fcfp->state == FCFI_STATE_FREE) { 7621 continue; 7622 } 7623 7624 if ((fcfp->fcf_index == fcfrec->fcf_index) && 7625 (bcmp((char *)fcfrec->fabric_name_identifier, 7626 fcfp->fcf_rec.fabric_name_identifier, 8) == 0) && 7627 (bcmp((char *)fcfrec->fcf_mac_address_hi, 7628 fcfp->fcf_rec.fcf_mac_address_hi, 4) == 0) && 7629 (bcmp((char *)fcfrec->fcf_mac_address_low, 7630 fcfp->fcf_rec.fcf_mac_address_low, 2) == 0)) { 7631 return (fcfp); 7632 } 7633 } 7634 7635 } else if (fcf_index) { 7636 /* Check for a matching FCF index only */ 7637 index = *fcf_index; 7638 fcfp = fcftab->table; 7639 for (i = 0; i < fcftab->table_count; i++, fcfp++) { 7640 if (fcfp->state == FCFI_STATE_FREE) { 7641 continue; 7642 } 7643 7644 if (fcfp->fcf_index == index) { 7645 return (fcfp); 7646 } 7647 } 7648 } 7649 7650 return (NULL); 7651 7652 } /* emlxs_fcfi_find() */ 7653 7654 7655 /*ARGSUSED*/ 7656 static uint32_t 7657 emlxs_fcfi_free_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 7658 void *arg1) 7659 { 7660 7661 if (fcfp->state != FCFI_STATE_FREE) { 7662 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7663 "fcfi_free_action:%d %s:%s arg=%p. " 7664 "Invalid state. <", 7665 fcfp->fcf_index, 7666 emlxs_fcfi_state_xlate(fcfp->state), 7667 emlxs_fcf_event_xlate(evt), arg1); 7668 return (1); 7669 } 7670 7671 if (fcfp->vfi_online) { 7672 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7673 "fcfi_free_action:%d flag=%x vfi_online=%d", 7674 fcfp->fcf_index, 7675 fcfp->flag, 7676 fcfp->vfi_online); 7677 } 7678 7679 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7680 "fcfi_free_action:%d flag=%x. FCF freed. <", 7681 fcfp->fcf_index, 7682 fcfp->flag); 7683 7684 fcfp->flag = 0; 7685 7686 return (0); 7687 7688 } /* emlxs_fcfi_free_action() */ 7689 7690 7691 /*ARGSUSED*/ 7692 static uint32_t 7693 emlxs_fcfi_offline_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 7694 void *arg1) 7695 { 7696 emlxs_hba_t *hba = HBA; 7697 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 7698 uint32_t rval = 0; 7699 7700 if (fcfp->state != FCFI_STATE_OFFLINE) { 7701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7702 "fcfi_offline_action:%d %s:%s arg=%p. " 7703 "Invalid state. <", 7704 fcfp->fcf_index, 7705 emlxs_fcfi_state_xlate(fcfp->state), 7706 emlxs_fcf_event_xlate(evt), arg1); 7707 return (1); 7708 } 7709 7710 fcfp->flag &= ~(EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ); 7711 7712 if (fcfp->prev_state == FCFI_STATE_FREE) { 7713 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7714 "fcfi_offline_action:%d fcfi_online=%d. <", 7715 fcfp->fcf_index, 7716 fcftab->fcfi_online); 7717 7718 return (0); 7719 } 7720 7721 if (fcfp->vfi_online) { 7722 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7723 "fcfi_offline_action:%d vfi_online=%d.", 7724 fcfp->fcf_index, 7725 fcfp->vfi_online); 7726 } 7727 7728 if (fcfp->flag & EMLXS_FCFI_FCFTAB) { 7729 fcfp->flag &= ~EMLXS_FCFI_FCFTAB; 7730 7731 if (fcftab->fcfi_online) { 7732 fcftab->fcfi_online--; 7733 } 7734 } 7735 7736 /* Check if online was requested */ 7737 if (fcfp->flag & EMLXS_FCFI_ONLINE_REQ) { 7738 7739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7740 "fcfi_offline_action:%d fcfi_online=%d. " 7741 "Online requested.", 7742 fcfp->fcf_index, 7743 fcftab->fcfi_online); 7744 7745 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG, 7746 FCF_REASON_REQUESTED, 0, arg1); 7747 return (rval); 7748 } 7749 7750 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7751 "fcfi_offline_action:%d fcfi_online=%d. " 7752 "FCFI offline. Notifying fcftab. >", 7753 fcfp->fcf_index, 7754 fcftab->fcfi_online); 7755 7756 /* Notify FCFTAB */ 7757 rval = emlxs_fcftab_event(port, FCF_EVENT_FCFI_OFFLINE, fcfp); 7758 7759 return (rval); 7760 7761 } /* emlxs_fcfi_offline_action() */ 7762 7763 7764 /*ARGSUSED*/ 7765 static uint32_t 7766 emlxs_fcfi_vfi_online_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, 7767 uint32_t evt, void *arg1) 7768 { 7769 uint32_t rval = 0; 7770 7771 if (evt != FCF_EVENT_VFI_ONLINE) { 7772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7773 "fcfi_vfi_online_evt_action:%d %s:%s arg=%p flag=%x. " 7774 "Invalid event type. <", 7775 fcfp->fcf_index, 7776 emlxs_fcfi_state_xlate(fcfp->state), 7777 emlxs_fcf_event_xlate(evt), arg1, 7778 fcfp->flag); 7779 return (1); 7780 } 7781 7782 switch (fcfp->state) { 7783 case FCFI_STATE_ONLINE: 7784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7785 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. " 7786 "Reentering online.", 7787 fcfp->fcf_index, 7788 fcfp->flag, 7789 fcfp->vfi_online); 7790 7791 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE, 7792 FCF_REASON_REENTER, evt, arg1); 7793 break; 7794 7795 case FCFI_STATE_VFI_ONLINE: 7796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7797 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. " 7798 "Online cmpl.", 7799 fcfp->fcf_index, 7800 fcfp->flag, 7801 fcfp->vfi_online); 7802 7803 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE_CMPL, 7804 FCF_REASON_EVENT, evt, arg1); 7805 break; 7806 7807 default: 7808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7809 "fcfi_vfi_online_evt_action:%d flag=%x vfi_online=%d. <", 7810 fcfp->fcf_index, 7811 fcfp->flag, 7812 fcfp->vfi_online); 7813 return (0); 7814 } 7815 7816 return (rval); 7817 7818 } /* emlxs_fcfi_vfi_online_evt_action() */ 7819 7820 7821 /*ARGSUSED*/ 7822 static uint32_t 7823 emlxs_fcfi_offline_handler(emlxs_port_t *port, FCFIobj_t *fcfp, void *arg1) 7824 { 7825 uint32_t rval = 0; 7826 7827 if (!(fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) { 7828 return (0); 7829 } 7830 7831 if (fcfp->vfi_online) { 7832 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) { 7833 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_PAUSED, 7834 FCF_REASON_REQUESTED, 0, arg1); 7835 } else { 7836 rval = emlxs_fcfi_state(port, fcfp, 7837 FCFI_STATE_VFI_OFFLINE, FCF_REASON_REQUESTED, 7838 0, arg1); 7839 } 7840 7841 } else if (fcfp->flag & EMLXS_FCFI_REG) { 7842 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG, 7843 FCF_REASON_REQUESTED, 0, arg1); 7844 7845 } else { 7846 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE, 7847 FCF_REASON_REQUESTED, 0, arg1); 7848 } 7849 7850 return (rval); 7851 7852 } /* emlxs_fcfi_offline_handler() */ 7853 7854 7855 /*ARGSUSED*/ 7856 static uint32_t 7857 emlxs_fcfi_vfi_offline_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, 7858 uint32_t evt, void *arg1) 7859 { 7860 uint32_t rval = 0; 7861 VFIobj_t *vfip; 7862 7863 if (evt != FCF_EVENT_VFI_OFFLINE) { 7864 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7865 "fcfi_vfi_offline_evt_action:%d %s:%s arg=%p flag=%x. " 7866 "Invalid event type. <", 7867 fcfp->fcf_index, 7868 emlxs_fcfi_state_xlate(fcfp->state), 7869 emlxs_fcf_event_xlate(evt), arg1, 7870 fcfp->flag); 7871 return (1); 7872 } 7873 7874 vfip = (VFIobj_t *)arg1; 7875 vfip->fcfp = NULL; 7876 7877 switch (fcfp->state) { 7878 case FCFI_STATE_VFI_ONLINE: 7879 case FCFI_STATE_ONLINE: 7880 if (fcfp->vfi_online == 0) { 7881 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7882 "fcfi_vfi_offline_evt_action:%d flag=%x " 7883 "vfi_online=%d. Offlining.", 7884 fcfp->fcf_index, 7885 fcfp->flag, fcfp->vfi_online); 7886 7887 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 7888 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 7889 7890 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 7891 } else { 7892 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7893 "fcfi_vfi_offline_evt_action:%d flag=%x " 7894 "vfi_online=%d. <", 7895 fcfp->fcf_index, 7896 fcfp->flag, fcfp->vfi_online); 7897 } 7898 break; 7899 7900 case FCFI_STATE_PAUSED: 7901 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7902 "fcfi_vfi_offline_evt_action:%d flag=%x vfi_online=%d. <", 7903 fcfp->fcf_index, 7904 fcfp->flag, fcfp->vfi_online); 7905 break; 7906 7907 case FCFI_STATE_VFI_OFFLINE: 7908 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7909 "fcfi_vfi_offline_evt_action:%d flag=%x. Offline cmpl.", 7910 fcfp->fcf_index, 7911 fcfp->flag); 7912 7913 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_OFFLINE_CMPL, 7914 FCF_REASON_EVENT, evt, arg1); 7915 break; 7916 7917 case FCFI_STATE_VFI_OFFLINE_CMPL: 7918 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7919 "fcfi_vfi_offline_evt_action:%d flag=%x. Offline cmpl.", 7920 fcfp->fcf_index, 7921 fcfp->flag); 7922 7923 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_OFFLINE_CMPL, 7924 FCF_REASON_REENTER, evt, arg1); 7925 break; 7926 7927 default: 7928 if (fcfp->vfi_online == 0) { 7929 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7930 "fcfi_vfi_offline_evt_action:%d flag=%x " 7931 "vfi_online=%d. Offline requested. <", 7932 fcfp->fcf_index, 7933 fcfp->flag, fcfp->vfi_online); 7934 7935 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 7936 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 7937 } else { 7938 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7939 "fcfi_vfi_offline_evt_action:%d flag = %x " 7940 "vfi_online=%d. <", 7941 fcfp->fcf_index, 7942 fcfp->flag, fcfp->vfi_online); 7943 } 7944 return (0); 7945 } 7946 7947 return (rval); 7948 7949 } /* emlxs_fcfi_vfi_offline_evt_action() */ 7950 7951 7952 /*ARGSUSED*/ 7953 static uint32_t 7954 emlxs_fcfi_online_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, 7955 uint32_t evt, void *arg1) 7956 { 7957 uint32_t rval = 0; 7958 7959 if (evt != FCF_EVENT_FCFI_ONLINE) { 7960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 7961 "fcfi_online_evt_action:%d %s:%s arg=%p. " 7962 "Invalid event type. <", 7963 fcfp->fcf_index, 7964 emlxs_fcfi_state_xlate(fcfp->state), 7965 emlxs_fcf_event_xlate(evt), arg1); 7966 return (1); 7967 } 7968 7969 if (fcfp->flag & EMLXS_FCFI_ONLINE_REQ) { 7970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7971 "fcfi_online_evt_action:%d. " 7972 "Online already requested. <", 7973 fcfp->fcf_index); 7974 return (1); 7975 } 7976 7977 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 7978 fcfp->flag |= EMLXS_FCFI_ONLINE_REQ; 7979 7980 switch (fcfp->state) { 7981 case FCFI_STATE_OFFLINE: 7982 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7983 "fcfi_online_evt_action:%d flag=%x. Initiating online.", 7984 fcfp->fcf_index, 7985 fcfp->flag); 7986 7987 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG, 7988 FCF_REASON_EVENT, evt, arg1); 7989 break; 7990 7991 case FCFI_STATE_VFI_OFFLINE: 7992 case FCFI_STATE_PAUSED: 7993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 7994 "fcfi_online_evt_action:%d flag=%x. Initiating online.", 7995 fcfp->fcf_index, 7996 fcfp->flag); 7997 7998 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE, 7999 FCF_REASON_EVENT, evt, arg1); 8000 break; 8001 8002 case FCFI_STATE_ONLINE: 8003 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8004 "fcfi_online_evt_action:%d flag=%x. Reentering online.", 8005 fcfp->fcf_index, 8006 fcfp->flag); 8007 8008 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE, 8009 FCF_REASON_REENTER, evt, arg1); 8010 break; 8011 8012 default: 8013 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8014 "fcfi_online_evt_action:%d flag=%x. <", 8015 fcfp->fcf_index, 8016 fcfp->flag); 8017 break; 8018 } 8019 8020 return (rval); 8021 8022 } /* emlxs_fcfi_online_evt_action() */ 8023 8024 8025 /*ARGSUSED*/ 8026 static uint32_t 8027 emlxs_fcfi_vfi_online_action(emlxs_port_t *port, FCFIobj_t *fcfp, 8028 uint32_t evt, void *arg1) 8029 { 8030 emlxs_hba_t *hba = HBA; 8031 uint32_t i; 8032 uint32_t rval = 0; 8033 VFIobj_t *vfip; 8034 8035 if (fcfp->state != FCFI_STATE_VFI_ONLINE) { 8036 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8037 "fcfi_vfi_online_action:%d %s:%s arg=%p. " 8038 "Invalid state. <", 8039 fcfp->fcf_index, 8040 emlxs_fcfi_state_xlate(fcfp->state), 8041 emlxs_fcf_event_xlate(evt), arg1); 8042 return (1); 8043 } 8044 8045 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) { 8046 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8047 "fcfi_vfi_online_action:%d. Offline requested.", 8048 fcfp->fcf_index); 8049 8050 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8051 return (rval); 8052 } 8053 8054 if (fcfp->vfi_online > 0) { 8055 /* Waking up out after being paused */ 8056 8057 /* Find first VFI of this FCFI */ 8058 vfip = hba->sli.sli4.VFI_table; 8059 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) { 8060 if (vfip->fcfp == fcfp) { 8061 break; 8062 } 8063 } 8064 8065 } else { 8066 8067 /* Find first available VFI */ 8068 vfip = hba->sli.sli4.VFI_table; 8069 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) { 8070 if (vfip->fcfp == NULL) { 8071 vfip->fcfp = fcfp; 8072 break; 8073 } 8074 } 8075 } 8076 8077 if (i == hba->sli.sli4.VFICount) { 8078 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8079 "fcfi_vfi_online_action:%d vfi_online=%d. " 8080 "No VFI found. Offlining.", 8081 fcfp->fcf_index, 8082 fcfp->vfi_online); 8083 8084 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8085 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 8086 8087 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8088 return (rval); 8089 } 8090 8091 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8092 "fcfi_vfi_online_action:%d vfi_online=%d. Onlining VFI:%d. >", 8093 fcfp->fcf_index, 8094 fcfp->vfi_online, 8095 vfip->VFI); 8096 8097 rval = emlxs_vfi_event(port, FCF_EVENT_VFI_ONLINE, vfip); 8098 8099 /* Wait for FCF_EVENT_VFI_ONLINE in return */ 8100 8101 return (rval); 8102 8103 } /* emlxs_fcfi_vfi_online_action() */ 8104 8105 8106 /*ARGSUSED*/ 8107 static uint32_t 8108 emlxs_fcfi_vfi_online_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, 8109 uint32_t evt, void *arg1) 8110 { 8111 uint32_t rval = 0; 8112 8113 if (fcfp->state != FCFI_STATE_VFI_ONLINE_CMPL) { 8114 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8115 "fcfi_vfi_online_cmpl_action:%d %s:%s arg=%p. " 8116 "Invalid state. <", 8117 fcfp->fcf_index, 8118 emlxs_fcfi_state_xlate(fcfp->state), 8119 emlxs_fcf_event_xlate(evt), arg1); 8120 return (1); 8121 } 8122 8123 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8124 "fcfi_vfi_online_cmpl_action:%d. Going online.", 8125 fcfp->fcf_index); 8126 8127 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_ONLINE, 8128 FCF_REASON_EVENT, evt, arg1); 8129 8130 return (rval); 8131 8132 } /* emlxs_fcfi_vfi_online_cmpl_action() */ 8133 8134 8135 /*ARGSUSED*/ 8136 static uint32_t 8137 emlxs_fcfi_vfi_offline_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8138 void *arg1) 8139 { 8140 emlxs_hba_t *hba = HBA; 8141 VFIobj_t *vfip; 8142 uint32_t rval = 0; 8143 int32_t i; 8144 8145 if (fcfp->state != FCFI_STATE_VFI_OFFLINE) { 8146 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8147 "fcfi_vfi_offline_action:%d %s:%s arg=%p. " 8148 "Invalid state. <", 8149 fcfp->fcf_index, 8150 emlxs_fcfi_state_xlate(fcfp->state), 8151 emlxs_fcf_event_xlate(evt), arg1); 8152 8153 return (1); 8154 } 8155 8156 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) { 8157 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8158 "fcfi_vfi_offline_action:%d vfi_online=%d. Pausing.", 8159 fcfp->fcf_index, 8160 fcfp->vfi_online); 8161 8162 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_PAUSED, 8163 FCF_REASON_EVENT, evt, arg1); 8164 8165 return (rval); 8166 } 8167 8168 if (fcfp->vfi_online == 0) { 8169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8170 "fcfi_vfi_offline_action:%d. " 8171 "VFI already offline. Skipping VFI offline.", 8172 fcfp->fcf_index); 8173 8174 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG, 8175 FCF_REASON_EVENT, evt, arg1); 8176 8177 return (rval); 8178 } 8179 8180 /* Offline VFI's of this FCFI */ 8181 for (i = (hba->sli.sli4.VFICount-1); i >= 0; i--) { 8182 vfip = &hba->sli.sli4.VFI_table[i]; 8183 8184 if ((vfip->fcfp != fcfp) || 8185 (vfip->state == VFI_STATE_OFFLINE) || 8186 (vfip->flag & EMLXS_VFI_OFFLINE_REQ)) { 8187 continue; 8188 } 8189 8190 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8191 "fcfi_vfi_offline_action:%d. Offlining VFI:%d >", 8192 fcfp->fcf_index, 8193 vfip->VFI); 8194 8195 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_OFFLINE, vfip); 8196 } 8197 8198 /* Wait for FCF_EVENT_VFI_OFFLINE in return */ 8199 8200 return (0); 8201 8202 } /* emlxs_fcfi_vfi_offline_action() */ 8203 8204 8205 /*ARGSUSED*/ 8206 static uint32_t 8207 emlxs_fcfi_paused_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8208 void *arg1) 8209 { 8210 emlxs_hba_t *hba = HBA; 8211 VFIobj_t *vfip; 8212 int32_t i; 8213 8214 if (fcfp->state != FCFI_STATE_PAUSED) { 8215 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8216 "fcfi_paused_action:%d %s:%s arg=%p. " 8217 "Invalid state. <", 8218 fcfp->fcf_index, 8219 emlxs_fcfi_state_xlate(fcfp->state), 8220 emlxs_fcf_event_xlate(evt), arg1); 8221 8222 return (1); 8223 } 8224 8225 fcfp->flag &= ~(EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ); 8226 8227 /* Pause all VFI's of this FCFI */ 8228 for (i = (hba->sli.sli4.VFICount-1); i >= 0; i--) { 8229 vfip = &hba->sli.sli4.VFI_table[i]; 8230 8231 if ((vfip->state == VFI_STATE_OFFLINE) || 8232 (vfip->state == VFI_STATE_PAUSED) || 8233 (vfip->fcfp != fcfp)) { 8234 continue; 8235 } 8236 8237 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8238 "fcfi_paused_action:%d vfi_online=%d. Pausing VFI:%d. >", 8239 fcfp->fcf_index, 8240 fcfp->vfi_online, 8241 vfip->VFI); 8242 8243 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_PAUSE, vfip); 8244 } 8245 8246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8247 "fcfi_paused_action:%d vfi_online=%d. FCFI paused. <", 8248 fcfp->fcf_index, 8249 fcfp->vfi_online); 8250 8251 return (0); 8252 8253 } /* emlxs_fcfi_paused_action() */ 8254 8255 8256 /*ARGSUSED*/ 8257 static uint32_t 8258 emlxs_fcfi_vfi_offline_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, 8259 uint32_t evt, void *arg1) 8260 { 8261 uint32_t rval = 0; 8262 8263 if (fcfp->state != FCFI_STATE_VFI_OFFLINE_CMPL) { 8264 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8265 "fcfi_vfi_offline_cmpl_action:%d %s:%s arg=%p. " 8266 "Invalid state. <", 8267 fcfp->fcf_index, 8268 emlxs_fcfi_state_xlate(fcfp->state), 8269 emlxs_fcf_event_xlate(evt), arg1); 8270 return (1); 8271 } 8272 8273 if ((fcfp->vfi_online == 0) && 8274 (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ)) { 8275 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8276 "fcfi_vfi_offline_cmpl_action:%d vfi_online=%d. " 8277 "Unregistering.", 8278 fcfp->fcf_index, 8279 fcfp->vfi_online); 8280 8281 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG, 8282 FCF_REASON_EVENT, evt, arg1); 8283 } else { 8284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8285 "fcfi_vfi_offline_cmpl_action:%d vfi_online=%d. <", 8286 fcfp->fcf_index, 8287 fcfp->vfi_online); 8288 } 8289 8290 return (rval); 8291 8292 } /* emlxs_fcfi_vfi_offline_cmpl_action() */ 8293 8294 8295 /*ARGSUSED*/ 8296 static uint32_t 8297 emlxs_fcfi_offline_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8298 void *arg1) 8299 { 8300 uint32_t rval = 0; 8301 8302 if (evt != FCF_EVENT_FCFI_OFFLINE) { 8303 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8304 "fcfi_offline_evt_action:%d %s:%s arg=%p. " 8305 "Invalid event type. <", 8306 fcfp->fcf_index, 8307 emlxs_fcfi_state_xlate(fcfp->state), 8308 emlxs_fcf_event_xlate(evt), arg1); 8309 return (1); 8310 } 8311 8312 if ((fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) && 8313 !(fcfp->flag & EMLXS_FCFI_PAUSE_REQ)) { 8314 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8315 "fcfi_offline_evt_action:%d. Offline already requested. <", 8316 fcfp->fcf_index); 8317 return (1); 8318 } 8319 8320 switch (fcfp->state) { 8321 case FCFI_STATE_OFFLINE: 8322 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8323 "fcfi_offline_evt_action:%d flag=%x. Already offline. <", 8324 fcfp->fcf_index, 8325 fcfp->flag); 8326 break; 8327 8328 /* Wait states */ 8329 case FCFI_STATE_VFI_ONLINE: 8330 case FCFI_STATE_VFI_OFFLINE: 8331 case FCFI_STATE_REG: 8332 case FCFI_STATE_ONLINE: 8333 case FCFI_STATE_PAUSED: 8334 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8335 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 8336 8337 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8338 "fcfi_offline_evt_action:%d flag=%x. Handling offline.", 8339 fcfp->fcf_index, 8340 fcfp->flag); 8341 8342 /* Handle offline now */ 8343 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8344 break; 8345 8346 /* Transitional states */ 8347 default: 8348 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8349 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 8350 8351 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8352 "fcfi_offline_evt_action:%d. " 8353 "Invalid state. <", 8354 fcfp->fcf_index); 8355 break; 8356 } 8357 8358 return (rval); 8359 8360 } /* emlxs_fcfi_offline_evt_action() */ 8361 8362 8363 /*ARGSUSED*/ 8364 static uint32_t 8365 emlxs_fcfi_pause_evt_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8366 void *arg1) 8367 { 8368 uint32_t rval = 0; 8369 8370 if (evt != FCF_EVENT_FCFI_PAUSE) { 8371 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8372 "fcfi_pause_evt_action:%d %s:%s arg=%p. " 8373 "Invalid event type. <", 8374 fcfp->fcf_index, 8375 emlxs_fcfi_state_xlate(fcfp->state), 8376 emlxs_fcf_event_xlate(evt), arg1); 8377 return (1); 8378 } 8379 8380 if (fcfp->flag & EMLXS_FCFI_PAUSE_REQ) { 8381 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8382 "fcfi_pause_evt_action:%d. Pause already requested. <", 8383 fcfp->fcf_index); 8384 return (1); 8385 } 8386 8387 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) { 8388 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8389 "fcfi_pause_evt_action:%d. Offline already requested. <", 8390 fcfp->fcf_index); 8391 return (1); 8392 } 8393 8394 switch (fcfp->state) { 8395 case FCFI_STATE_OFFLINE: 8396 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8397 "fcfi_pause_evt_action:%d flag=%x. Already offline. <", 8398 fcfp->fcf_index, 8399 fcfp->flag); 8400 break; 8401 8402 case FCFI_STATE_PAUSED: 8403 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8404 "fcfi_pause_evt_action:%d flag=%x. Already paused. <", 8405 fcfp->fcf_index, 8406 fcfp->flag); 8407 break; 8408 8409 /* Wait states */ 8410 case FCFI_STATE_VFI_ONLINE: 8411 case FCFI_STATE_VFI_OFFLINE: 8412 case FCFI_STATE_REG: 8413 case FCFI_STATE_ONLINE: 8414 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8415 fcfp->flag |= (EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ); 8416 8417 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8418 "fcfi_pause_evt_action:%d flag=%x. Handle pause request.", 8419 fcfp->fcf_index, 8420 fcfp->flag); 8421 8422 /* Handle offline now */ 8423 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8424 break; 8425 8426 /* Transitional states */ 8427 default: 8428 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8429 fcfp->flag |= (EMLXS_FCFI_OFFLINE_REQ | EMLXS_FCFI_PAUSE_REQ); 8430 8431 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8432 "fcfi_pause_evt_action:%d. " 8433 "Invalid state. <", 8434 fcfp->fcf_index); 8435 break; 8436 } 8437 8438 return (rval); 8439 8440 } /* emlxs_fcfi_pause_evt_action() */ 8441 8442 8443 /*ARGSUSED*/ 8444 static uint32_t 8445 emlxs_fcfi_unreg_failed_action(emlxs_port_t *port, FCFIobj_t *fcfp, 8446 uint32_t evt, void *arg1) 8447 { 8448 uint32_t rval = 0; 8449 8450 fcfp->attempts++; 8451 8452 if (fcfp->state != FCFI_STATE_UNREG_FAILED) { 8453 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8454 "fcfi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 8455 "Invalid state. <", 8456 fcfp->fcf_index, 8457 emlxs_fcfi_state_xlate(fcfp->state), 8458 emlxs_fcf_event_xlate(evt), 8459 arg1, fcfp->attempts); 8460 return (1); 8461 } 8462 8463 if ((fcfp->reason == FCF_REASON_SEND_FAILED) || 8464 (fcfp->attempts >= 3)) { 8465 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8466 "fcfi_unreg_failed_action:%d attempt=%d reason=%x. " 8467 "Unreg cmpl.", 8468 fcfp->fcf_index, 8469 fcfp->attempts, 8470 fcfp->reason); 8471 8472 fcfp->flag &= ~EMLXS_FCFI_REG; 8473 8474 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_CMPL, 8475 FCF_REASON_OP_FAILED, fcfp->attempts, arg1); 8476 } else { 8477 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8478 "fcfi_unreg_failed_action:%d attempt=%d. Unregistering.", 8479 fcfp->fcf_index, 8480 arg1, fcfp->attempts); 8481 8482 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG, 8483 FCF_REASON_OP_FAILED, fcfp->attempts, arg1); 8484 } 8485 8486 return (rval); 8487 8488 } /* emlxs_fcfi_unreg_failed_action() */ 8489 8490 8491 /*ARGSUSED*/ 8492 static uint32_t 8493 emlxs_fcfi_reg_failed_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8494 void *arg1) 8495 { 8496 uint32_t rval = 0; 8497 8498 fcfp->attempts++; 8499 8500 if (fcfp->state != FCFI_STATE_REG_FAILED) { 8501 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8502 "fcfi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 8503 "Invalid state. <", 8504 fcfp->fcf_index, 8505 emlxs_fcfi_state_xlate(fcfp->state), 8506 emlxs_fcf_event_xlate(evt), arg1, 8507 fcfp->attempts); 8508 return (1); 8509 } 8510 8511 if ((fcfp->reason == FCF_REASON_SEND_FAILED) || 8512 (fcfp->attempts >= 3)) { 8513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8514 "fcfi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.", 8515 fcfp->fcf_index, 8516 fcfp->attempts, 8517 fcfp->reason); 8518 8519 fcfp->flag &= ~EMLXS_FCFI_REQ_MASK; 8520 fcfp->flag |= EMLXS_FCFI_OFFLINE_REQ; 8521 8522 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_CMPL, 8523 FCF_REASON_OP_FAILED, fcfp->attempts, arg1); 8524 } else { 8525 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8526 "fcfi_reg_failed_action:%d attempt=%d. Registering.", 8527 fcfp->fcf_index, 8528 fcfp->attempts); 8529 8530 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG, 8531 FCF_REASON_OP_FAILED, fcfp->attempts, arg1); 8532 } 8533 8534 return (rval); 8535 8536 } /* emlxs_fcfi_reg_failed_action() */ 8537 8538 8539 /*ARGSUSED*/ 8540 static uint32_t 8541 emlxs_fcfi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 8542 { 8543 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 8544 MAILBOX4 *mb4; 8545 FCFIobj_t *fcfp; 8546 8547 fcfp = (FCFIobj_t *)mbq->context; 8548 mb4 = (MAILBOX4 *)mbq; 8549 8550 mutex_enter(&EMLXS_FCF_LOCK); 8551 8552 if (fcfp->state != FCFI_STATE_REG) { 8553 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8554 "fcfi_reg_mbcmpl:%d state=%s.", 8555 fcfp->fcf_index, 8556 emlxs_fcfi_state_xlate(fcfp->state)); 8557 8558 mutex_exit(&EMLXS_FCF_LOCK); 8559 return (0); 8560 } 8561 8562 if (mb4->mbxStatus) { 8563 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8564 "fcfi_reg_mbcmpl:%d failed. %s. >", 8565 fcfp->fcf_index, 8566 emlxs_mb_xlate_status(mb4->mbxStatus)); 8567 8568 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED, 8569 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 8570 8571 mutex_exit(&EMLXS_FCF_LOCK); 8572 return (0); 8573 } 8574 8575 fcfp->FCFI = mb4->un.varRegFCFI.FCFI; 8576 8577 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8578 "fcfi_reg_mbcmpl:%d FCFI=%d. Reg complete. >", 8579 fcfp->fcf_index, 8580 fcfp->FCFI); 8581 8582 fcfp->flag |= EMLXS_FCFI_REG; 8583 8584 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_CMPL, 8585 0, 0, 0); 8586 mutex_exit(&EMLXS_FCF_LOCK); 8587 return (0); 8588 8589 } /* emlxs_fcfi_reg_mbcmpl() */ 8590 8591 8592 /*ARGSUSED*/ 8593 static uint32_t 8594 emlxs_fcfi_reg_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8595 void *arg1) 8596 { 8597 emlxs_hba_t *hba = HBA; 8598 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 8599 MAILBOX4 *mb4; 8600 MAILBOXQ *mbq; 8601 uint32_t rval = 0; 8602 8603 if (fcfp->state != FCFI_STATE_REG) { 8604 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8605 "fcfi_reg_action:%d %s:%s arg=%p. " 8606 "Invalid state. <", 8607 fcfp->fcf_index, 8608 emlxs_fcfi_state_xlate(fcfp->state), 8609 emlxs_fcf_event_xlate(evt), arg1); 8610 return (1); 8611 } 8612 8613 if (!(fcfp->flag & EMLXS_FCFI_FCFTAB)) { 8614 fcfp->flag |= EMLXS_FCFI_FCFTAB; 8615 fcftab->fcfi_online++; 8616 } 8617 8618 if (fcfp->prev_state != FCFI_STATE_REG_FAILED) { 8619 fcfp->attempts = 0; 8620 } 8621 8622 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) { 8623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8624 "fcfi_reg_action:%d attempts=%d. Offline requested.", 8625 fcfp->fcf_index, 8626 fcfp->attempts); 8627 8628 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8629 return (rval); 8630 } 8631 8632 if (fcfp->flag & EMLXS_FCFI_REG) { 8633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8634 "fcfi_reg_action:%d. Already registered. " 8635 "Skipping REG_FCFI update.", 8636 fcfp->fcf_index); 8637 8638 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE, 8639 FCF_REASON_EVENT, evt, arg1); 8640 return (rval); 8641 } 8642 8643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8644 "fcfi_reg_action:%d attempts=%d. Sending REG_FCFI. <", 8645 fcfp->fcf_index, 8646 fcfp->attempts); 8647 8648 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 8649 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED, 8650 FCF_REASON_NO_MBOX, 0, arg1); 8651 8652 return (rval); 8653 } 8654 mb4 = (MAILBOX4*)mbq; 8655 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 8656 8657 mbq->mbox_cmpl = emlxs_fcfi_reg_mbcmpl; 8658 mbq->context = (void *)fcfp; 8659 mbq->port = (void *)port; 8660 8661 mb4->mbxCommand = MBX_REG_FCFI; 8662 mb4->mbxOwner = OWN_HOST; 8663 mb4->un.varRegFCFI.FCFI = 0; /* FCFI will be returned by firmware */ 8664 mb4->un.varRegFCFI.InfoIndex = fcfp->fcf_index; 8665 8666 mb4->un.varRegFCFI.RQId0 = hba->sli.sli4.rq[EMLXS_FCFI_RQ0_INDEX].qid; 8667 mb4->un.varRegFCFI.Id0_rctl_mask = EMLXS_FCFI_RQ0_RMASK; 8668 mb4->un.varRegFCFI.Id0_rctl = EMLXS_FCFI_RQ0_RCTL; 8669 mb4->un.varRegFCFI.Id0_type_mask = EMLXS_FCFI_RQ0_TMASK; 8670 mb4->un.varRegFCFI.Id0_type = EMLXS_FCFI_RQ0_TYPE; 8671 8672 mb4->un.varRegFCFI.RQId1 = 0xffff; 8673 mb4->un.varRegFCFI.RQId2 = 0xffff; 8674 mb4->un.varRegFCFI.RQId3 = 0xffff; 8675 8676 if (fcfp->flag & EMLXS_FCFI_VLAN_ID) { 8677 mb4->un.varRegFCFI.vv = 1; 8678 mb4->un.varRegFCFI.vlanTag = fcfp->vlan_id; 8679 } 8680 8681 /* Ignore the fcf record and force FPMA */ 8682 mb4->un.varRegFCFI.mam = EMLXS_REG_FCFI_MAM_FPMA; 8683 8684 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 8685 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 8686 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 8687 8688 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_REG_FAILED, 8689 FCF_REASON_SEND_FAILED, rval, arg1); 8690 8691 return (rval); 8692 } 8693 8694 return (0); 8695 8696 } /* emlxs_fcfi_reg_action() */ 8697 8698 8699 /*ARGSUSED*/ 8700 static uint32_t 8701 emlxs_fcfi_reg_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8702 void *arg1) 8703 { 8704 uint32_t rval = 0; 8705 8706 if (fcfp->state != FCFI_STATE_REG_CMPL) { 8707 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8708 "fcfi_reg_cmpl_action:%d %s:%s arg=%p. " 8709 "Invalid state. <", 8710 fcfp->fcf_index, 8711 emlxs_fcfi_state_xlate(fcfp->state), 8712 emlxs_fcf_event_xlate(evt), arg1); 8713 return (1); 8714 } 8715 8716 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) { 8717 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8718 "fcfi_reg_cmpl_action:%d. Offline requested.", 8719 fcfp->fcf_index); 8720 8721 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8722 return (rval); 8723 } 8724 8725 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8726 "fcfi_reg_cmpl_action:%d attempts=%d. Reg cmpl.", 8727 fcfp->fcf_index, 8728 fcfp->attempts); 8729 8730 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_VFI_ONLINE, 8731 FCF_REASON_EVENT, evt, arg1); 8732 8733 return (rval); 8734 8735 } /* emlxs_fcfi_reg_cmpl_action() */ 8736 8737 8738 /*ARGSUSED*/ 8739 static uint32_t 8740 emlxs_fcfi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 8741 { 8742 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 8743 MAILBOX4 *mb4; 8744 FCFIobj_t *fcfp; 8745 8746 fcfp = (FCFIobj_t *)mbq->context; 8747 mb4 = (MAILBOX4 *)mbq; 8748 8749 mutex_enter(&EMLXS_FCF_LOCK); 8750 8751 if (fcfp->state != FCFI_STATE_UNREG) { 8752 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8753 "fcfi_unreg_mbcmpl:%d state=%s.", 8754 fcfp->fcf_index, 8755 emlxs_fcfi_state_xlate(fcfp->state)); 8756 8757 mutex_exit(&EMLXS_FCF_LOCK); 8758 return (0); 8759 } 8760 8761 if (mb4->mbxStatus) { 8762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8763 "fcfi_unreg_mbcmpl:%d failed. %s. >", 8764 fcfp->fcf_index, 8765 emlxs_mb_xlate_status(mb4->mbxStatus)); 8766 8767 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED, 8768 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 8769 8770 mutex_exit(&EMLXS_FCF_LOCK); 8771 return (0); 8772 } 8773 8774 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8775 "fcfi_unreg_mbcmpl:%d. Unreg complete. >", 8776 fcfp->fcf_index); 8777 8778 fcfp->flag &= ~EMLXS_FCFI_REG; 8779 (void) emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_CMPL, 8780 0, 0, 0); 8781 8782 mutex_exit(&EMLXS_FCF_LOCK); 8783 return (0); 8784 8785 } /* emlxs_fcfi_unreg_mbcmpl() */ 8786 8787 8788 /*ARGSUSED*/ 8789 static uint32_t 8790 emlxs_fcfi_unreg_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8791 void *arg1) 8792 { 8793 emlxs_hba_t *hba = HBA; 8794 MAILBOX4 *mb4; 8795 MAILBOXQ *mbq; 8796 uint32_t rval = 0; 8797 8798 if (fcfp->state != FCFI_STATE_UNREG) { 8799 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8800 "fcfi_unreg_action:%d %s:%s arg=%p. " 8801 "Invalid state. <", 8802 fcfp->fcf_index, 8803 emlxs_fcfi_state_xlate(fcfp->state), 8804 emlxs_fcf_event_xlate(evt), arg1); 8805 return (1); 8806 } 8807 8808 if (!(fcfp->flag & EMLXS_FCFI_REG)) { 8809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8810 "fcfi_unreg_action:%d. Not registered. " 8811 "Skipping UNREG_FCFI.", 8812 fcfp->fcf_index); 8813 8814 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE, 8815 FCF_REASON_EVENT, evt, arg1); 8816 return (rval); 8817 } 8818 8819 if (fcfp->prev_state != FCFI_STATE_UNREG_FAILED) { 8820 fcfp->attempts = 0; 8821 } 8822 8823 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8824 "fcfi_unreg_action:%d attempts=%d. Sending UNREG_FCFI. <", 8825 fcfp->fcf_index, 8826 fcfp->attempts); 8827 8828 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 8829 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED, 8830 FCF_REASON_NO_MBOX, 0, arg1); 8831 return (rval); 8832 } 8833 mb4 = (MAILBOX4*)mbq; 8834 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 8835 8836 mbq->mbox_cmpl = emlxs_fcfi_unreg_mbcmpl; 8837 mbq->context = (void *)fcfp; 8838 mbq->port = (void *)port; 8839 8840 mb4->mbxCommand = MBX_UNREG_FCFI; 8841 mb4->mbxOwner = OWN_HOST; 8842 mb4->un.varUnRegFCFI.FCFI = fcfp->FCFI; 8843 8844 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 8845 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 8846 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 8847 8848 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_UNREG_FAILED, 8849 FCF_REASON_SEND_FAILED, rval, arg1); 8850 8851 return (rval); 8852 } 8853 8854 return (0); 8855 8856 } /* emlxs_fcfi_unreg_action() */ 8857 8858 8859 /*ARGSUSED*/ 8860 static uint32_t 8861 emlxs_fcfi_unreg_cmpl_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8862 void *arg1) 8863 { 8864 uint32_t rval = 0; 8865 8866 if (fcfp->state != FCFI_STATE_UNREG_CMPL) { 8867 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8868 "fcfi_unreg_cmpl_action:%d %s:%s arg=%p. " 8869 "Invalid state. <", 8870 fcfp->fcf_index, 8871 emlxs_fcfi_state_xlate(fcfp->state), 8872 emlxs_fcf_event_xlate(evt), arg1); 8873 return (1); 8874 } 8875 8876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8877 "fcfi_unreg_cmpl_action:%d attempts=%d. Going offline.", 8878 fcfp->fcf_index, 8879 emlxs_fcfi_state_xlate(fcfp->state), 8880 emlxs_fcf_event_xlate(evt), arg1, 8881 fcfp->attempts); 8882 8883 rval = emlxs_fcfi_state(port, fcfp, FCFI_STATE_OFFLINE, 8884 FCF_REASON_EVENT, evt, arg1); 8885 8886 return (rval); 8887 8888 } /* emlxs_fcfi_unreg_cmpl_action() */ 8889 8890 8891 /*ARGSUSED*/ 8892 static uint32_t 8893 emlxs_fcfi_online_action(emlxs_port_t *port, FCFIobj_t *fcfp, uint32_t evt, 8894 void *arg1) 8895 { 8896 emlxs_hba_t *hba = HBA; 8897 uint32_t rval = 0; 8898 VFIobj_t *vfip; 8899 uint32_t i; 8900 8901 if (fcfp->state != FCFI_STATE_ONLINE) { 8902 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 8903 "fcfi_online_action:%d %s:%s arg=%p. " 8904 "Invalid state. <", 8905 fcfp->fcf_index, 8906 emlxs_fcfi_state_xlate(fcfp->state), 8907 emlxs_fcf_event_xlate(evt), arg1); 8908 return (1); 8909 } 8910 8911 fcfp->flag &= ~EMLXS_FCFI_ONLINE_REQ; 8912 8913 if (fcfp->flag & EMLXS_FCFI_OFFLINE_REQ) { 8914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8915 "fcfi_online_action:%d attempts=%d. Offline requested.", 8916 fcfp->fcf_index, 8917 fcfp->attempts); 8918 8919 rval = emlxs_fcfi_offline_handler(port, fcfp, arg1); 8920 return (rval); 8921 } 8922 8923 /* Online remaining VFI's for this FCFI */ 8924 vfip = hba->sli.sli4.VFI_table; 8925 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip++) { 8926 if (vfip->fcfp != fcfp) { 8927 continue; 8928 } 8929 8930 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8931 "fcfi_online_action:%d vfi_online=%d. Onlining VFI:%d. >", 8932 fcfp->fcf_index, 8933 fcfp->vfi_online, 8934 vfip->VFI); 8935 8936 (void) emlxs_vfi_event(port, FCF_EVENT_VFI_ONLINE, vfip); 8937 } 8938 8939 if (fcfp->prev_state != FCFI_STATE_ONLINE) { 8940 /* Perform VSAN discovery check when first VFI goes online */ 8941 if (fcfp->vfi_online < FCFI_MAX_VFI_COUNT) { 8942 8943 /* Perform VSAN Discovery (TBD) */ 8944 /* For now we only need 1 VFI */ 8945 8946 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8947 "fcfi_online_action:%d vfi_online=%d. " 8948 "VSAN discovery required.", 8949 fcfp->fcf_index, 8950 fcfp->vfi_online); 8951 } 8952 } 8953 8954 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 8955 "fcfi_online_action:%d vfi_online=%d. " 8956 "FCFI online. Notifying fcftab. >", 8957 fcfp->fcf_index, 8958 fcfp->vfi_online); 8959 8960 /* Notify FCFTAB */ 8961 rval = emlxs_fcftab_event(port, FCF_EVENT_FCFI_ONLINE, fcfp); 8962 8963 return (rval); 8964 8965 } /* emlxs_fcfi_online_action() */ 8966 8967 8968 /*ARGSUSED*/ 8969 static int 8970 emlxs_fcf_configured(emlxs_port_t *port, FCFIobj_t *fcfp) 8971 { 8972 emlxs_hba_t *hba = HBA; 8973 int i; 8974 uint32_t entry_count; 8975 uint32_t valid_entry; 8976 uint32_t match_found; 8977 uint16_t VLanId; 8978 FCF_RECORD_t *fcfrec = &fcfp->fcf_rec; 8979 uint32_t j; 8980 uint32_t k; 8981 8982 /* Init the primary flag, we may set it later */ 8983 fcfp->flag &= ~(EMLXS_FCFI_PRIMARY|EMLXS_FCFI_BOOT); 8984 8985 if (!(hba->flag & FC_FIP_SUPPORTED)) { 8986 if (!hba->sli.sli4.cfgFCOE.length) { 8987 /* Nothing specified, so everything matches */ 8988 /* For nonFIP only use index 0 */ 8989 if (fcfrec->fcf_index == 0) { 8990 return (1); /* success */ 8991 } 8992 return (0); 8993 } 8994 8995 /* Just check FCMap for now */ 8996 if (bcmp((char *)fcfrec->fc_map, 8997 hba->sli.sli4.cfgFCOE.FCMap, 3) == 0) { 8998 return (1); /* success */ 8999 } 9000 return (0); 9001 } 9002 9003 /* For FIP mode, the FCF record must match Config Region 23 */ 9004 9005 entry_count = (hba->sli.sli4.cfgFCF.length * sizeof (uint32_t)) / 9006 sizeof (tlv_fcfconnectentry_t); 9007 valid_entry = 0; 9008 match_found = 0; 9009 9010 for (i = 0; i < entry_count; i++) { 9011 9012 if (!hba->sli.sli4.cfgFCF.entry[i].Valid) { 9013 continue; 9014 } 9015 9016 if (hba->sli.sli4.cfgFCF.entry[i].FabricNameValid) { 9017 valid_entry = 1; 9018 9019 if (bcmp((char *)fcfrec->fabric_name_identifier, 9020 hba->sli.sli4.cfgFCF.entry[i].FabricName, 8)) { 9021 match_found = 0; 9022 continue; 9023 } 9024 9025 match_found = 1; 9026 } 9027 9028 if (hba->sli.sli4.cfgFCF.entry[i].SwitchNameValid) { 9029 valid_entry = 1; 9030 9031 if (bcmp((char *)fcfrec->switch_name_identifier, 9032 hba->sli.sli4.cfgFCF.entry[i].SwitchName, 8)) { 9033 match_found = 0; 9034 continue; 9035 } 9036 9037 match_found = 1; 9038 } 9039 9040 if (hba->sli.sli4.cfgFCF.entry[i].VLanValid) { 9041 valid_entry = 1; 9042 9043 if (!(fcfp->flag & EMLXS_FCFI_VLAN_ID)) { 9044 match_found = 0; 9045 continue; 9046 } 9047 9048 VLanId = hba->sli.sli4.cfgFCF.entry[i].VLanId; 9049 j = VLanId / 8; 9050 k = 1 << (VLanId % 8); 9051 9052 if (!(fcfrec->vlan_bitmap[j] & k)) { 9053 match_found = 0; 9054 continue; 9055 } 9056 9057 /* Assign requested vlan_id to this FCF */ 9058 fcfp->vlan_id = VLanId; 9059 9060 match_found = 1; 9061 } 9062 9063 /* If a match was found */ 9064 if (match_found) { 9065 if (hba->sli.sli4.cfgFCF.entry[i].Primary) { 9066 fcfp->flag |= EMLXS_FCFI_PRIMARY; 9067 } 9068 if (hba->sli.sli4.cfgFCF.entry[i].Boot) { 9069 fcfp->flag |= EMLXS_FCFI_BOOT; 9070 } 9071 return (1); 9072 } 9073 } 9074 9075 /* If no valid entries found, then allow any fabric */ 9076 if (!valid_entry) { 9077 return (1); 9078 } 9079 9080 return (0); 9081 9082 } /* emlxs_fcf_configured() */ 9083 9084 9085 static void 9086 emlxs_fcfi_update(emlxs_port_t *port, FCFIobj_t *fcfp, FCF_RECORD_t *fcf_rec, 9087 uint32_t event_tag) 9088 { 9089 emlxs_hba_t *hba = HBA; 9090 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 9091 uint16_t i; 9092 9093 bcopy((char *)fcf_rec, &fcfp->fcf_rec, sizeof (FCF_RECORD_t)); 9094 fcfp->fcf_index = fcf_rec->fcf_index; 9095 9096 /* Clear VLAN info */ 9097 fcfp->vlan_id = 0; 9098 fcfp->flag &= ~EMLXS_FCFI_VLAN_ID; 9099 9100 /* Check if fcf is a member of a VLAN */ 9101 for (i = 0; i < 4096; i++) { 9102 if (fcf_rec->vlan_bitmap[i / 8] & (1 << (i % 8))) { 9103 /* For now assign the VLAN id of the first VLAN found */ 9104 fcfp->vlan_id = i; 9105 fcfp->flag |= EMLXS_FCFI_VLAN_ID; 9106 break; 9107 } 9108 } 9109 9110 if (fcf_rec->fcf_available) { 9111 fcfp->flag |= EMLXS_FCFI_AVAILABLE; 9112 } else { 9113 fcfp->flag &= ~EMLXS_FCFI_AVAILABLE; 9114 } 9115 9116 if (fcf_rec->fcf_valid && !fcf_rec->fcf_sol) { 9117 fcfp->flag |= EMLXS_FCFI_VALID; 9118 } else { 9119 fcfp->flag &= ~EMLXS_FCFI_VALID; 9120 } 9121 9122 /* Check config region 23 */ 9123 /* Also sets BOOT and PRIMARY cfg bits as needed */ 9124 if (emlxs_fcf_configured(port, fcfp)) { 9125 fcfp->flag |= EMLXS_FCFI_CONFIGURED; 9126 } else { 9127 fcfp->flag &= ~EMLXS_FCFI_CONFIGURED; 9128 } 9129 9130 /* Set fcfp priority. Used by selection alogithm */ 9131 /* Combination of BOOT:PRIMARY:~fip_priority */ 9132 fcfp->priority = (fcfp->flag & EMLXS_FCFI_BOOT)? 0x200:0; 9133 fcfp->priority |= (fcfp->flag & EMLXS_FCFI_PRIMARY)? 0x100:0; 9134 fcfp->priority |= ~(fcf_rec->fip_priority & 0xff); 9135 9136 fcfp->event_tag = event_tag; 9137 fcfp->generation = fcftab->generation; 9138 fcfp->flag |= EMLXS_FCFI_FRESH; 9139 9140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9141 "fcfi:%d gen=%x iotag=%d flag=%x sol=%x avl=%x val=%x state=%x " 9142 "map=%x pri=%x vid=%x", 9143 fcf_rec->fcf_index, 9144 fcfp->generation, 9145 fcfp->event_tag, 9146 fcfp->flag, 9147 fcf_rec->fcf_sol, 9148 fcf_rec->fcf_available, 9149 fcf_rec->fcf_valid, 9150 fcf_rec->fcf_state, 9151 fcf_rec->mac_address_provider, 9152 fcfp->priority, 9153 fcfp->vlan_id); 9154 9155 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9156 "fcfi:%d mac=%02x:%02x:%02x:%02x:%02x:%02x " 9157 "fabric=%02x%02x%02x%02x%02x%02x%02x%02x " 9158 "switch=%02x%02x%02x%02x%02x%02x%02x%02x", 9159 fcfp->fcf_index, 9160 fcf_rec->fcf_mac_address_hi[0], 9161 fcf_rec->fcf_mac_address_hi[1], 9162 fcf_rec->fcf_mac_address_hi[2], 9163 fcf_rec->fcf_mac_address_hi[3], 9164 fcf_rec->fcf_mac_address_low[0], 9165 fcf_rec->fcf_mac_address_low[1], 9166 9167 fcf_rec->fabric_name_identifier[0], 9168 fcf_rec->fabric_name_identifier[1], 9169 fcf_rec->fabric_name_identifier[2], 9170 fcf_rec->fabric_name_identifier[3], 9171 fcf_rec->fabric_name_identifier[4], 9172 fcf_rec->fabric_name_identifier[5], 9173 fcf_rec->fabric_name_identifier[6], 9174 fcf_rec->fabric_name_identifier[7], 9175 9176 fcf_rec->switch_name_identifier[0], 9177 fcf_rec->switch_name_identifier[1], 9178 fcf_rec->switch_name_identifier[2], 9179 fcf_rec->switch_name_identifier[3], 9180 fcf_rec->switch_name_identifier[4], 9181 fcf_rec->switch_name_identifier[5], 9182 fcf_rec->switch_name_identifier[6], 9183 fcf_rec->switch_name_identifier[7]); 9184 9185 return; 9186 9187 } /* emlxs_fcfi_update() */ 9188 9189 9190 /* ************************************************************************** */ 9191 /* VFI */ 9192 /* ************************************************************************** */ 9193 9194 static char * 9195 emlxs_vfi_state_xlate(uint32_t state) 9196 { 9197 static char buffer[32]; 9198 uint32_t i; 9199 uint32_t count; 9200 9201 count = sizeof (emlxs_vfi_state_table) / sizeof (emlxs_table_t); 9202 for (i = 0; i < count; i++) { 9203 if (state == emlxs_vfi_state_table[i].code) { 9204 return (emlxs_vfi_state_table[i].string); 9205 } 9206 } 9207 9208 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 9209 return (buffer); 9210 9211 } /* emlxs_vfi_state_xlate() */ 9212 9213 9214 static uint32_t 9215 emlxs_vfi_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9216 void *arg1) 9217 { 9218 uint32_t rval = 0; 9219 uint32_t(*func) (emlxs_port_t *, VFIobj_t *, uint32_t, void *); 9220 uint32_t index; 9221 uint32_t events; 9222 uint16_t state; 9223 9224 /* Convert event to action table index */ 9225 switch (evt) { 9226 case FCF_EVENT_STATE_ENTER: 9227 index = 0; 9228 break; 9229 case FCF_EVENT_VFI_ONLINE: 9230 index = 1; 9231 break; 9232 case FCF_EVENT_VFI_OFFLINE: 9233 index = 2; 9234 break; 9235 case FCF_EVENT_VFI_PAUSE: 9236 index = 3; 9237 break; 9238 case FCF_EVENT_VPI_ONLINE: 9239 index = 4; 9240 break; 9241 case FCF_EVENT_VPI_OFFLINE: 9242 index = 5; 9243 break; 9244 default: 9245 return (1); 9246 } 9247 9248 events = VFI_ACTION_EVENTS; 9249 state = vfip->state; 9250 9251 index += (state * events); 9252 func = (uint32_t(*) (emlxs_port_t *, VFIobj_t *, uint32_t, void *)) 9253 emlxs_vfi_action_table[index]; 9254 9255 if (!func) { 9256 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 9257 "vfi_action:%d %s:%s arg=%p. No action. <", 9258 vfip->VFI, 9259 emlxs_vfi_state_xlate(state), 9260 emlxs_fcf_event_xlate(evt), arg1); 9261 9262 return (1); 9263 } 9264 9265 rval = (func)(port, vfip, evt, arg1); 9266 9267 return (rval); 9268 9269 } /* emlxs_vfi_action() */ 9270 9271 9272 static uint32_t 9273 emlxs_vfi_event(emlxs_port_t *port, uint32_t evt, 9274 void *arg1) 9275 { 9276 VPIobj_t *vpip = NULL; 9277 VFIobj_t *vfip = NULL; 9278 uint32_t rval = 0; 9279 9280 /* Filter events and acquire fcfi context */ 9281 switch (evt) { 9282 case FCF_EVENT_VPI_ONLINE: 9283 case FCF_EVENT_VPI_OFFLINE: 9284 vpip = (VPIobj_t *)arg1; 9285 9286 if (!vpip) { 9287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 9288 "vfi_event: %s arg=%p. Null VPI found. <", 9289 emlxs_fcf_event_xlate(evt), arg1); 9290 9291 return (1); 9292 } 9293 9294 vfip = vpip->vfip; 9295 9296 if (!vfip) { 9297 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 9298 "vfi_event: %s arg=%p. VFI not found. <", 9299 emlxs_fcf_event_xlate(evt), arg1); 9300 9301 return (1); 9302 } 9303 break; 9304 9305 case FCF_EVENT_VFI_ONLINE: 9306 case FCF_EVENT_VFI_OFFLINE: 9307 case FCF_EVENT_VFI_PAUSE: 9308 vfip = (VFIobj_t *)arg1; 9309 9310 if (!vfip) { 9311 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 9312 "vfi_event: %s arg=%p. VFI not found. <", 9313 emlxs_fcf_event_xlate(evt), arg1); 9314 9315 return (1); 9316 } 9317 break; 9318 9319 default: 9320 return (1); 9321 } 9322 9323 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 9324 "vfi_event:%d %s:%s arg=%p", 9325 vfip->VFI, 9326 emlxs_vfi_state_xlate(vfip->state), 9327 emlxs_fcf_event_xlate(evt), arg1); 9328 9329 rval = emlxs_vfi_action(port, vfip, evt, arg1); 9330 9331 return (rval); 9332 9333 } /* emlxs_vfi_event() */ 9334 9335 9336 /*ARGSUSED*/ 9337 static uint32_t 9338 emlxs_vfi_state(emlxs_port_t *port, VFIobj_t *vfip, uint16_t state, 9339 uint16_t reason, uint32_t explain, void *arg1) 9340 { 9341 uint32_t rval = 0; 9342 9343 if (state >= VFI_ACTION_STATES) { 9344 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9345 "vfi_state:%d %s. " 9346 "Invalid state. <", 9347 vfip->VFI, 9348 emlxs_vfi_state_xlate(vfip->state)); 9349 return (1); 9350 } 9351 9352 if ((vfip->state == state) && 9353 (reason != FCF_REASON_REENTER)) { 9354 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9355 "vfi_state:%d %s:%s:0x%x arg=%p. " 9356 "State not changed. <", 9357 vfip->VFI, 9358 emlxs_vfi_state_xlate(vfip->state), 9359 emlxs_fcf_reason_xlate(reason), 9360 explain, arg1); 9361 9362 return (1); 9363 } 9364 9365 if (!reason) { 9366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 9367 "vfi_state:%d %s-->%s arg=%p", 9368 vfip->VFI, 9369 emlxs_vfi_state_xlate(vfip->state), 9370 emlxs_vfi_state_xlate(state), arg1); 9371 } else if (reason == FCF_REASON_EVENT) { 9372 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 9373 "vfi_state:%d %s-->%s:%s:%s arg=%p", 9374 vfip->VFI, 9375 emlxs_vfi_state_xlate(vfip->state), 9376 emlxs_vfi_state_xlate(state), 9377 emlxs_fcf_reason_xlate(reason), 9378 emlxs_fcf_event_xlate(explain), arg1); 9379 } else if (explain) { 9380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 9381 "vfi_state:%d %s-->%s:%s:0x%x arg=%p", 9382 vfip->VFI, 9383 emlxs_vfi_state_xlate(vfip->state), 9384 emlxs_vfi_state_xlate(state), 9385 emlxs_fcf_reason_xlate(reason), 9386 explain, arg1); 9387 } else { 9388 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 9389 "vfi_state:%d %s-->%s:%s arg=%p", 9390 vfip->VFI, 9391 emlxs_vfi_state_xlate(vfip->state), 9392 emlxs_vfi_state_xlate(state), 9393 emlxs_fcf_reason_xlate(reason), arg1); 9394 } 9395 9396 vfip->prev_state = vfip->state; 9397 vfip->prev_reason = vfip->reason; 9398 vfip->state = state; 9399 vfip->reason = reason; 9400 9401 rval = emlxs_vfi_action(port, vfip, FCF_EVENT_STATE_ENTER, arg1); 9402 9403 return (rval); 9404 9405 } /* emlxs_vfi_state() */ 9406 9407 9408 /*ARGSUSED*/ 9409 static uint32_t 9410 emlxs_vfi_vpi_online_evt_action(emlxs_port_t *port, VFIobj_t *vfip, 9411 uint32_t evt, void *arg1) 9412 { 9413 uint32_t rval = 0; 9414 9415 if (evt != FCF_EVENT_VPI_ONLINE) { 9416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9417 "vfi_vpi_online_evt_action:%d %s:%s arg=%p flag=%x. " 9418 "Invalid event type. <", 9419 vfip->VFI, 9420 emlxs_vfi_state_xlate(vfip->state), 9421 emlxs_fcf_event_xlate(evt), arg1, 9422 vfip->flag); 9423 return (1); 9424 } 9425 9426 switch (vfip->state) { 9427 case VFI_STATE_ONLINE: 9428 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9429 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. " 9430 "Reentering online.", 9431 vfip->VFI, 9432 vfip->flag, 9433 vfip->vpi_online); 9434 9435 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE, 9436 FCF_REASON_REENTER, evt, arg1); 9437 break; 9438 9439 case VFI_STATE_VPI_ONLINE: 9440 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9441 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. " 9442 "Online cmpl.", 9443 vfip->VFI, 9444 vfip->flag, 9445 vfip->vpi_online); 9446 9447 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE_CMPL, 9448 FCF_REASON_EVENT, evt, arg1); 9449 break; 9450 9451 default: 9452 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9453 "vfi_vpi_online_evt_action:%d flag=%x vpi_online=%d. <", 9454 vfip->VFI, 9455 vfip->flag, 9456 vfip->vpi_online); 9457 9458 return (1); 9459 } 9460 9461 return (rval); 9462 9463 } /* emlxs_vfi_vpi_online_evt_action() */ 9464 9465 9466 /*ARGSUSED*/ 9467 static uint32_t 9468 emlxs_vfi_offline_handler(emlxs_port_t *port, VFIobj_t *vfip, void *arg1) 9469 { 9470 uint32_t rval = 0; 9471 9472 if (!(vfip->flag & EMLXS_VFI_OFFLINE_REQ)) { 9473 return (0); 9474 } 9475 9476 if (vfip->vpi_online) { 9477 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) { 9478 rval = emlxs_vfi_state(port, vfip, VFI_STATE_PAUSED, 9479 FCF_REASON_REQUESTED, 0, arg1); 9480 } else { 9481 rval = emlxs_vfi_state(port, vfip, 9482 VFI_STATE_VPI_OFFLINE, FCF_REASON_REQUESTED, 9483 0, arg1); 9484 } 9485 9486 } else if (vfip->flag & EMLXS_VFI_REG) { 9487 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG, 9488 FCF_REASON_REQUESTED, 0, arg1); 9489 9490 } else if (vfip->flag & EMLXS_VFI_INIT) { 9491 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG, 9492 FCF_REASON_REQUESTED, 0, arg1); 9493 9494 } else { 9495 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE, 9496 FCF_REASON_REQUESTED, 0, arg1); 9497 } 9498 9499 return (rval); 9500 9501 } /* emlxs_vfi_offline_handler() */ 9502 9503 9504 /*ARGSUSED*/ 9505 static uint32_t 9506 emlxs_vfi_vpi_offline_evt_action(emlxs_port_t *port, VFIobj_t *vfip, 9507 uint32_t evt, void *arg1) 9508 { 9509 uint32_t rval = 0; 9510 VPIobj_t *vpip; 9511 9512 if (evt != FCF_EVENT_VPI_OFFLINE) { 9513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9514 "vfi_vpi_offline_evt_action:%d %s:%s arg=%p flag=%x. " 9515 "Invalid event type. <", 9516 vfip->VFI, 9517 emlxs_vfi_state_xlate(vfip->state), 9518 emlxs_fcf_event_xlate(evt), arg1, 9519 vfip->flag); 9520 return (1); 9521 } 9522 9523 /* Disconnect VPI object from VFI */ 9524 vpip = (VPIobj_t *)arg1; 9525 vpip->vfip = NULL; 9526 9527 switch (vfip->state) { 9528 case VFI_STATE_ONLINE: 9529 case VFI_STATE_VPI_ONLINE: 9530 if (vfip->vpi_online == 0) { 9531 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9532 "vfi_vpi_offline_evt_action:%d flag=%x " 9533 "vpi_online=%d. Offlining.", 9534 vfip->VFI, 9535 vfip->flag, vfip->vpi_online); 9536 9537 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9538 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 9539 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 9540 } else { 9541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9542 "vfi_vpi_offline_evt_action:%d flag=%x " 9543 "vpi_online=%d. <", 9544 vfip->VFI, 9545 vfip->flag, vfip->vpi_online); 9546 } 9547 break; 9548 9549 case VFI_STATE_PAUSED: 9550 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9551 "vfi_vpi_offline_evt_action:%d flag=%x vpi_online=%d. <", 9552 vfip->VFI, 9553 vfip->flag, vfip->vpi_online); 9554 break; 9555 9556 case VFI_STATE_VPI_OFFLINE: 9557 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9558 "vfi_vpi_offline_evt_action:%d flag=%x. VPI offline cmpl.", 9559 vfip->VFI, 9560 vfip->flag); 9561 9562 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_OFFLINE_CMPL, 9563 FCF_REASON_EVENT, evt, arg1); 9564 break; 9565 9566 case VFI_STATE_VPI_OFFLINE_CMPL: 9567 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9568 "vfi_vpi_offline_evt_action:%d flag=%x. VPI offline cmpl.", 9569 vfip->VFI, 9570 vfip->flag); 9571 9572 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_OFFLINE_CMPL, 9573 FCF_REASON_REENTER, evt, arg1); 9574 break; 9575 9576 default: 9577 if (vfip->vpi_online == 0) { 9578 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9579 "vfi_vpi_offline_evt_action:%d flag=%x " 9580 "vpi_online=%d. Requesting offline. <", 9581 vfip->VFI, 9582 vfip->flag, vfip->vpi_online); 9583 9584 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9585 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 9586 } else { 9587 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9588 "vfi_vpi_offline_evt_action:%d flag=%x " 9589 "vpi_online=%d. <", 9590 vfip->VFI, 9591 vfip->flag, vfip->vpi_online); 9592 } 9593 return (1); 9594 } 9595 9596 return (rval); 9597 9598 } /* emlxs_vfi_vpi_offline_evt_action() */ 9599 9600 9601 /*ARGSUSED*/ 9602 static uint32_t 9603 emlxs_vfi_online_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9604 void *arg1) 9605 { 9606 emlxs_hba_t *hba = HBA; 9607 emlxs_port_t *vport; 9608 VPIobj_t *vpip; 9609 uint32_t rval = 0; 9610 uint32_t i; 9611 9612 if (evt != FCF_EVENT_VFI_ONLINE) { 9613 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9614 "vfi_online_evt_action:%d %s:%s arg=%p flag=%x. " 9615 "Invalid event type. <", 9616 vfip->VFI, 9617 emlxs_vfi_state_xlate(vfip->state), 9618 emlxs_fcf_event_xlate(evt), arg1, 9619 vfip->flag); 9620 return (1); 9621 } 9622 9623 if (vfip->flag & EMLXS_VFI_ONLINE_REQ) { 9624 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9625 "vfi_online_evt_action:%d flag=%x. " 9626 "Online already requested. <", 9627 vfip->VFI, 9628 vfip->flag); 9629 return (0); 9630 } 9631 9632 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9633 9634 switch (vfip->state) { 9635 case VFI_STATE_OFFLINE: 9636 vfip->flag |= EMLXS_VFI_ONLINE_REQ; 9637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9638 "vfi_online_evt_action:%d flag=%x. Initiating online.", 9639 vfip->VFI, 9640 vfip->flag); 9641 9642 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT, 9643 FCF_REASON_EVENT, evt, arg1); 9644 break; 9645 9646 case VFI_STATE_VPI_OFFLINE: 9647 case VFI_STATE_PAUSED: 9648 vfip->flag |= EMLXS_VFI_ONLINE_REQ; 9649 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9650 "vfi_online_evt_action:%d flag=%x. Initiating online.", 9651 vfip->VFI, 9652 vfip->flag); 9653 9654 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE, 9655 FCF_REASON_EVENT, evt, arg1); 9656 break; 9657 9658 case VFI_STATE_ONLINE: 9659 /* Online all VPI's belonging to this vfi */ 9660 for (i = 0; i <= hba->vpi_max; i++) { 9661 vport = &VPORT(i); 9662 vpip = vport->vpip; 9663 9664 if (!(vport->flag & EMLXS_PORT_BOUND) || 9665 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 9666 continue; 9667 } 9668 9669 if (vpip->vfip != vfip) { 9670 continue; 9671 } 9672 9673 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9674 "vfi_online_evt_action:%d. Onlining VPI:%d >", 9675 vfip->VFI, 9676 vpip->VPI); 9677 9678 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_ONLINE, 9679 vpip); 9680 } 9681 break; 9682 9683 default: 9684 vfip->flag |= EMLXS_VFI_ONLINE_REQ; 9685 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9686 "vfi_online_evt_action:%d flag=%x. <", 9687 vfip->VFI, 9688 vfip->flag); 9689 return (1); 9690 } 9691 9692 return (rval); 9693 9694 } /* emlxs_vfi_online_evt_action() */ 9695 9696 9697 /*ARGSUSED*/ 9698 static uint32_t 9699 emlxs_vfi_offline_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9700 void *arg1) 9701 { 9702 uint32_t rval = 0; 9703 9704 if (evt != FCF_EVENT_VFI_OFFLINE) { 9705 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9706 "vfi_offline_evt_action:%d %s:%s arg=%p flag=%x. " 9707 "Invalid event type. <", 9708 vfip->VFI, 9709 emlxs_vfi_state_xlate(vfip->state), 9710 emlxs_fcf_event_xlate(evt), arg1, 9711 vfip->flag); 9712 return (1); 9713 } 9714 9715 if ((vfip->flag & EMLXS_VFI_OFFLINE_REQ) && 9716 !(vfip->flag & EMLXS_VFI_PAUSE_REQ)) { 9717 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9718 "vfi_offline_evt_action:%d flag=%x. " 9719 "Offline already requested. <", 9720 vfip->VFI, 9721 vfip->flag); 9722 return (0); 9723 } 9724 9725 switch (vfip->state) { 9726 case VFI_STATE_OFFLINE: 9727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9728 "vfi_offline_evt_action:%d flag=%x. " 9729 "Already offline. <", 9730 vfip->VFI, 9731 vfip->flag); 9732 break; 9733 9734 /* Wait states */ 9735 case VFI_STATE_VPI_ONLINE: 9736 case VFI_STATE_VPI_OFFLINE: 9737 case VFI_STATE_VPI_OFFLINE_CMPL: 9738 case VFI_STATE_INIT: 9739 case VFI_STATE_REG: 9740 case VFI_STATE_ONLINE: 9741 case VFI_STATE_PAUSED: 9742 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9743 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 9744 9745 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9746 "vfi_offline_evt_action:%d flag=%x. Handling offline.", 9747 vfip->VFI, 9748 vfip->flag); 9749 9750 /* Handle offline now */ 9751 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 9752 break; 9753 9754 default: 9755 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9756 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 9757 9758 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9759 "vfi_offline_evt_action:%d flag=%x. <", 9760 vfip->VFI, 9761 vfip->flag); 9762 break; 9763 } 9764 9765 return (rval); 9766 9767 } /* emlxs_vfi_offline_evt_action() */ 9768 9769 9770 /*ARGSUSED*/ 9771 static uint32_t 9772 emlxs_vfi_pause_evt_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9773 void *arg1) 9774 { 9775 uint32_t rval = 0; 9776 9777 if (evt != FCF_EVENT_VFI_PAUSE) { 9778 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9779 "vfi_pause_evt_action:%d %s:%s arg=%p flag=%x. " 9780 "Invalid event type. <", 9781 vfip->VFI, 9782 emlxs_vfi_state_xlate(vfip->state), 9783 emlxs_fcf_event_xlate(evt), arg1, 9784 vfip->flag); 9785 return (1); 9786 } 9787 9788 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) { 9789 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9790 "vfi_pause_evt_action:%d flag=%x. " 9791 "Pause already requested. <", 9792 vfip->VFI, 9793 vfip->flag); 9794 return (0); 9795 } 9796 9797 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 9798 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9799 "vfi_pause_evt_action:%d flag=%x. " 9800 "Offline already requested. <", 9801 vfip->VFI, 9802 vfip->flag); 9803 return (0); 9804 } 9805 9806 switch (vfip->state) { 9807 case VFI_STATE_OFFLINE: 9808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9809 "vfi_pause_evt_action:%d flag=%x. " 9810 "Already offline. <", 9811 vfip->VFI, 9812 vfip->flag); 9813 break; 9814 9815 case VFI_STATE_PAUSED: 9816 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9817 "vfi_pause_evt_action:%d flag=%x. " 9818 "Already paused. <", 9819 vfip->VFI, 9820 vfip->flag); 9821 break; 9822 9823 /* Wait states */ 9824 case VFI_STATE_VPI_ONLINE: 9825 case VFI_STATE_VPI_OFFLINE_CMPL: 9826 case VFI_STATE_INIT: 9827 case VFI_STATE_REG: 9828 case VFI_STATE_ONLINE: 9829 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9830 vfip->flag |= (EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ); 9831 9832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9833 "vfi_pause_evt_action:%d flag=%x. Handling offline.", 9834 vfip->VFI, 9835 vfip->flag); 9836 9837 /* Handle offline now */ 9838 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 9839 break; 9840 9841 default: 9842 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 9843 vfip->flag |= (EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ); 9844 9845 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9846 "vfi_pause_evt_action:%d flag=%x. <", 9847 vfip->VFI, 9848 vfip->flag); 9849 break; 9850 } 9851 9852 return (rval); 9853 9854 } /* emlxs_vfi_pause_evt_action() */ 9855 9856 9857 /*ARGSUSED*/ 9858 static uint32_t 9859 emlxs_vfi_offline_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9860 void *arg1) 9861 { 9862 uint32_t rval = 0; 9863 9864 if (vfip->state != VFI_STATE_OFFLINE) { 9865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9866 "vfi_offline_action:%d %s:%s arg=%p. " 9867 "Invalid state. <", 9868 vfip->VFI, 9869 emlxs_vfi_state_xlate(vfip->state), 9870 emlxs_fcf_event_xlate(evt), arg1); 9871 return (1); 9872 } 9873 9874 if (!vfip->fcfp) { 9875 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9876 "vfi_offline_action:%d %s:%s arg=%p flag=%x. " 9877 "Null fcfp found. <", 9878 vfip->VFI, 9879 emlxs_vfi_state_xlate(vfip->state), 9880 emlxs_fcf_event_xlate(evt), arg1, 9881 vfip->flag); 9882 return (1); 9883 } 9884 9885 vfip->flag &= ~(EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ); 9886 9887 if (vfip->prev_state == VFI_STATE_OFFLINE) { 9888 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9889 "vfi_offline_action:%d vfi_online=%d. <", 9890 vfip->VFI, 9891 vfip->fcfp->vfi_online); 9892 9893 return (0); 9894 } 9895 9896 if (vfip->vpi_online) { 9897 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 9898 "vfi_offline_action:%d vpi_online=%d. VPI's still online.", 9899 vfip->VFI, 9900 vfip->vpi_online); 9901 } 9902 9903 if (vfip->flag & EMLXS_VFI_FCFI) { 9904 vfip->flag &= ~EMLXS_VFI_FCFI; 9905 9906 if (vfip->fcfp->vfi_online) { 9907 vfip->fcfp->vfi_online--; 9908 } 9909 } 9910 9911 /* Check if online was requested */ 9912 if (vfip->flag & EMLXS_VFI_ONLINE_REQ) { 9913 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9914 "vfi_offline_action:%d vfi_online=%d. Online requested.", 9915 vfip->VFI, 9916 vfip->fcfp->vfi_online); 9917 9918 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT, 9919 FCF_REASON_REQUESTED, 0, arg1); 9920 return (rval); 9921 } 9922 9923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9924 "vfi_offline_action:%d vfi_online=%d. " 9925 "VFI offline. Notifying FCFI:%d >", 9926 vfip->VFI, 9927 vfip->fcfp->vfi_online, 9928 vfip->fcfp->fcf_index); 9929 9930 /* Notify FCFI */ 9931 rval = emlxs_fcfi_event(port, FCF_EVENT_VFI_OFFLINE, vfip); 9932 9933 return (rval); 9934 9935 } /* emlxs_vfi_offline_action() */ 9936 9937 9938 /*ARGSUSED*/ 9939 static uint32_t 9940 emlxs_vfi_init_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 9941 { 9942 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 9943 VFIobj_t *vfip; 9944 MAILBOX4 *mb4; 9945 9946 vfip = (VFIobj_t *)mbq->context; 9947 mb4 = (MAILBOX4 *)mbq; 9948 9949 mutex_enter(&EMLXS_FCF_LOCK); 9950 9951 if (vfip->state != VFI_STATE_INIT) { 9952 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9953 "vfi_init_mbcmpl:%d %s.", 9954 vfip->VFI, 9955 emlxs_vfi_state_xlate(vfip->state)); 9956 9957 mutex_exit(&EMLXS_FCF_LOCK); 9958 return (0); 9959 } 9960 9961 if (mb4->mbxStatus) { 9962 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9963 "vfi_init_mbcmpl:%d failed. %s. >", 9964 vfip->VFI, 9965 emlxs_mb_xlate_status(mb4->mbxStatus)); 9966 9967 (void) emlxs_vfi_state(port, vfip, VFI_STATE_INIT_FAILED, 9968 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 9969 9970 mutex_exit(&EMLXS_FCF_LOCK); 9971 return (0); 9972 } 9973 9974 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 9975 "vfi_init_mbcmpl:%d. Init complete. >", 9976 vfip->VFI, 9977 mb4->mbxStatus); 9978 9979 vfip->flag |= EMLXS_VFI_INIT; 9980 (void) emlxs_vfi_state(port, vfip, VFI_STATE_INIT_CMPL, 0, 0, 0); 9981 9982 mutex_exit(&EMLXS_FCF_LOCK); 9983 return (0); 9984 9985 } /* emlxs_vfi_init_mbcmpl() */ 9986 9987 9988 /*ARGSUSED*/ 9989 static uint32_t 9990 emlxs_vfi_init_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 9991 void *arg1) 9992 { 9993 emlxs_hba_t *hba = HBA; 9994 MAILBOXQ *mbq; 9995 MAILBOX4 *mb4; 9996 uint32_t rval = 0; 9997 9998 if (vfip->state != VFI_STATE_INIT) { 9999 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10000 "vfi_init_action:%d %s:%s arg=%p. " 10001 "Invalid state. <", 10002 vfip->VFI, 10003 emlxs_vfi_state_xlate(vfip->state), 10004 emlxs_fcf_event_xlate(evt), arg1); 10005 return (1); 10006 } 10007 10008 if (!(vfip->flag & EMLXS_VFI_FCFI)) { 10009 vfip->flag |= EMLXS_VFI_FCFI; 10010 vfip->fcfp->vfi_online++; 10011 } 10012 10013 if (vfip->prev_state != VFI_STATE_INIT_FAILED) { 10014 vfip->attempts = 0; 10015 } 10016 10017 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 10018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10019 "vfi_init_action:%d attempts=%d. Offline requested.", 10020 vfip->VFI, 10021 vfip->attempts); 10022 10023 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10024 return (rval); 10025 } 10026 10027 if (vfip->flag & EMLXS_VFI_INIT) { 10028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10029 "vfi_init_action:%d flag=%x. " 10030 "Already init'd. Skipping INIT_VFI.", 10031 vfip->VFI); 10032 10033 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE, 10034 FCF_REASON_EVENT, evt, arg1); 10035 return (rval); 10036 } 10037 10038 if (((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) == 10039 SLI_INTF_IF_TYPE_0) && (vfip->fcfp->vfi_online == 1)) { 10040 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10041 "vfi_init_action:%d. First VFI. Skipping INIT_VFI.", 10042 vfip->VFI); 10043 10044 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE, 10045 FCF_REASON_EVENT, evt, arg1); 10046 return (rval); 10047 } 10048 10049 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10050 "vfi_init_action:%d vfi_online=%d attempts=%d. Sending INIT_VFI. <", 10051 vfip->VFI, 10052 vfip->fcfp->vfi_online, 10053 vfip->attempts); 10054 10055 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 10056 rval = emlxs_vfi_state(port, vfip, FCFI_STATE_REG_FAILED, 10057 FCF_REASON_NO_MBOX, 0, arg1); 10058 return (rval); 10059 } 10060 mb4 = (MAILBOX4*)mbq; 10061 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 10062 10063 mbq->nonembed = NULL; 10064 mbq->mbox_cmpl = emlxs_vfi_init_mbcmpl; 10065 mbq->context = (void *)vfip; 10066 mbq->port = (void *)port; 10067 10068 mb4->mbxCommand = MBX_INIT_VFI; 10069 mb4->mbxOwner = OWN_HOST; 10070 mb4->un.varInitVFI4.fcfi = vfip->fcfp->FCFI; 10071 mb4->un.varInitVFI4.vfi = vfip->VFI; 10072 10073 /* ??? This function is untested and incomplete */ 10074 10075 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 10076 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 10077 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 10078 10079 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT_FAILED, 10080 FCF_REASON_SEND_FAILED, rval, arg1); 10081 10082 return (rval); 10083 } 10084 10085 return (0); 10086 10087 } /* emlxs_vfi_init_action() */ 10088 10089 10090 /*ARGSUSED*/ 10091 static uint32_t 10092 emlxs_vfi_init_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10093 void *arg1) 10094 { 10095 uint32_t rval = 0; 10096 10097 vfip->attempts++; 10098 10099 if (vfip->state != VFI_STATE_INIT_FAILED) { 10100 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10101 "vfi_init_action:%d %s:%s arg=%p attempt=%d. " 10102 "Invalid state. <", 10103 vfip->VFI, 10104 emlxs_vfi_state_xlate(vfip->state), 10105 emlxs_fcf_event_xlate(evt), arg1, 10106 vfip->attempts); 10107 return (1); 10108 } 10109 10110 if ((vfip->reason == FCF_REASON_SEND_FAILED) || 10111 (vfip->attempts >= 3)) { 10112 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10113 "vfi_init_action:%d attempt=%d reason=%x. Init cmpl.", 10114 vfip->VFI, 10115 vfip->attempts, 10116 vfip->reason); 10117 10118 vfip->flag &= ~(EMLXS_VFI_REG | EMLXS_VFI_INIT); 10119 10120 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 10121 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 10122 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT_CMPL, 10123 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10124 } else { 10125 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10126 "vfi_init_action:%d attempt=%d. Initializing.", 10127 vfip->VFI, 10128 vfip->attempts); 10129 10130 rval = emlxs_vfi_state(port, vfip, VFI_STATE_INIT, 10131 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10132 } 10133 10134 return (rval); 10135 10136 } /* emlxs_vfi_init_failed_action() */ 10137 10138 10139 /*ARGSUSED*/ 10140 static uint32_t 10141 emlxs_vfi_init_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10142 void *arg1) 10143 { 10144 uint32_t rval = 0; 10145 10146 if (vfip->state != VFI_STATE_INIT_CMPL) { 10147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10148 "vfi_init_cmpl_action:%d %s:%s arg=%p. " 10149 "Invalid state. <", 10150 vfip->VFI, 10151 emlxs_vfi_state_xlate(vfip->state), 10152 emlxs_fcf_event_xlate(evt), arg1); 10153 return (1); 10154 } 10155 10156 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10157 "vfi_init_cmpl_action:%d attempts=%d. Init cmpl.", 10158 vfip->VFI, 10159 vfip->attempts); 10160 10161 rval = emlxs_vfi_state(port, vfip, VFI_STATE_VPI_ONLINE, 10162 FCF_REASON_EVENT, evt, arg1); 10163 10164 return (rval); 10165 10166 } /* emlxs_vfi_init_cmpl_action() */ 10167 10168 10169 /*ARGSUSED*/ 10170 static uint32_t 10171 emlxs_vfi_vpi_online_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10172 void *arg1) 10173 { 10174 emlxs_hba_t *hba = HBA; 10175 uint32_t rval = 0; 10176 uint32_t i; 10177 emlxs_port_t *vport; 10178 VPIobj_t *vpip; 10179 10180 if (vfip->state != VFI_STATE_VPI_ONLINE) { 10181 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10182 "vfi_vpi_online_action:%d %s:%s arg=%p. " 10183 "Invalid state. <", 10184 vfip->VFI, 10185 emlxs_vfi_state_xlate(vfip->state), 10186 emlxs_fcf_event_xlate(evt), arg1); 10187 return (1); 10188 } 10189 10190 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 10191 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10192 "vfi_vpi_online_action:%d. Offline requested.", 10193 vfip->VFI); 10194 10195 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10196 return (rval); 10197 } 10198 10199 if (vfip->logi_count) { 10200 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10201 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. " 10202 "VPI already logged in.", 10203 vfip->VFI, 10204 vfip->vpi_online, 10205 vfip->logi_count); 10206 } 10207 10208 if (vfip->vpi_online) { 10209 /* Waking up after being paused */ 10210 10211 /* Find first VPI of this VFI */ 10212 for (i = 0; i <= hba->vpi_max; i++) { 10213 vport = &VPORT(i); 10214 vpip = vport->vpip; 10215 10216 if (!(vport->flag & EMLXS_PORT_BOUND) || 10217 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 10218 continue; 10219 } 10220 10221 if (vpip->vfip == vfip) { 10222 break; 10223 } 10224 } 10225 10226 } else { 10227 10228 /* Find first available VPI */ 10229 for (i = 0; i <= hba->vpi_max; i++) { 10230 vport = &VPORT(i); 10231 vpip = vport->vpip; 10232 10233 if (!(vport->flag & EMLXS_PORT_BOUND) || 10234 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 10235 continue; 10236 } 10237 10238 if (vpip->vfip == NULL) { 10239 vpip->vfip = vfip; 10240 break; 10241 } 10242 } 10243 } 10244 10245 if (i > hba->vpi_max) { 10246 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10247 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. " 10248 "No VPI found. Offlining.", 10249 vfip->VFI, 10250 vfip->vpi_online, 10251 vfip->logi_count); 10252 10253 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 10254 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 10255 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10256 return (rval); 10257 } 10258 10259 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10260 "vfi_vpi_online_action:%d vpi_online=%d logi_count=%d. " 10261 "Onlining VPI:%d >", 10262 vfip->VFI, 10263 vfip->vpi_online, 10264 vfip->logi_count, 10265 vpip->VPI); 10266 10267 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_ONLINE, vpip); 10268 10269 /* Wait for FCF_EVENT_VPI_ONLINE in return */ 10270 10271 return (rval); 10272 10273 } /* emlxs_vfi_vpi_online_action() */ 10274 10275 10276 /*ARGSUSED*/ 10277 static uint32_t 10278 emlxs_vfi_vpi_online_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, 10279 uint32_t evt, void *arg1) 10280 { 10281 uint32_t rval = 0; 10282 VPIobj_t *vpip = (VPIobj_t *)arg1; 10283 10284 if (vfip->state != VFI_STATE_VPI_ONLINE_CMPL) { 10285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10286 "vfi_vpi_online_cmpl_action:%d %s:%s arg=%p. " 10287 "Invalid state. <", 10288 vfip->VFI, 10289 emlxs_vfi_state_xlate(vfip->state), 10290 emlxs_fcf_event_xlate(evt), arg1); 10291 return (1); 10292 } 10293 10294 if (vpip == vfip->flogi_vpip) { 10295 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10296 "vfi_vpi_online_cmpl_action:%d flag=%x vpi_online=%d " 10297 "logi_count=%d. flogi_vpi. Registering.", 10298 vfip->VFI, 10299 vfip->flag, 10300 vfip->vpi_online, 10301 vfip->logi_count); 10302 10303 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG, 10304 FCF_REASON_EVENT, evt, arg1); 10305 } else { 10306 /* Waking up after pause */ 10307 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10308 "vfi_vpi_online_cmpl_action:%d flag=%x vpi_online=%d " 10309 "logi_count=%d. Going online.", 10310 vfip->VFI, 10311 vfip->flag, 10312 vfip->vpi_online, 10313 vfip->logi_count); 10314 10315 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE, 10316 FCF_REASON_EVENT, evt, arg1); 10317 } 10318 10319 return (rval); 10320 10321 } /* emlxs_vfi_vpi_online_cmpl_action() */ 10322 10323 10324 /*ARGSUSED*/ 10325 static uint32_t 10326 emlxs_vfi_vpi_offline_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, 10327 uint32_t evt, void *arg1) 10328 { 10329 uint32_t rval = 0; 10330 10331 if (vfip->state != VFI_STATE_VPI_OFFLINE_CMPL) { 10332 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10333 "vfi_vpi_offline_cmpl_action:%d %s:%s arg=%p. " 10334 "Invalid state. <", 10335 vfip->VFI, 10336 emlxs_vfi_state_xlate(vfip->state), 10337 emlxs_fcf_event_xlate(evt), arg1); 10338 return (1); 10339 } 10340 10341 if ((vfip->vpi_online == 0) && 10342 (vfip->flag & EMLXS_VFI_OFFLINE_REQ)) { 10343 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10344 "vfi_vpi_offline_cmpl_action:%d vpi_online=%d. " 10345 "Unregistering.", 10346 vfip->VFI, 10347 vfip->vpi_online); 10348 10349 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG, 10350 FCF_REASON_EVENT, evt, arg1); 10351 } else { 10352 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10353 "vfi_vpi_offline_cmpl_action:%d vpi_online=%d. <", 10354 vfip->VFI, 10355 vfip->vpi_online); 10356 } 10357 10358 return (rval); 10359 10360 } /* emlxs_vfi_vpi_offline_cmpl_action() */ 10361 10362 10363 /*ARGSUSED*/ 10364 static uint32_t 10365 emlxs_vfi_vpi_offline_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10366 void *arg1) 10367 { 10368 emlxs_hba_t *hba = HBA; 10369 emlxs_port_t *vport; 10370 uint32_t rval = 0; 10371 int32_t i; 10372 VPIobj_t *vpip; 10373 10374 if (vfip->state != VFI_STATE_VPI_OFFLINE) { 10375 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10376 "vfi_vpi_offline_action:%d %s:%s arg=%p. " 10377 "Invalid state. <", 10378 vfip->VFI, 10379 emlxs_vfi_state_xlate(vfip->state), 10380 emlxs_fcf_event_xlate(evt), arg1); 10381 return (1); 10382 } 10383 10384 if (vfip->flag & EMLXS_VFI_PAUSE_REQ) { 10385 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10386 "vfi_vpi_offline_action:%d vpi_online=%d. Pausing.", 10387 vfip->VFI, 10388 vfip->vpi_online); 10389 10390 rval = emlxs_vfi_state(port, vfip, VFI_STATE_PAUSED, 10391 FCF_REASON_EVENT, evt, arg1); 10392 10393 return (rval); 10394 } 10395 10396 if (vfip->vpi_online == 0) { 10397 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10398 "vfi_vpi_offline_action:%d vpi_online=%d. " 10399 "VPI already offline. Skipping VPI offline.", 10400 vfip->VFI, 10401 vfip->vpi_online); 10402 10403 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG, 10404 FCF_REASON_EVENT, evt, arg1); 10405 10406 return (rval); 10407 } 10408 10409 /* Offline all VPI's of this VFI */ 10410 for (i = hba->vpi_max; i >= 0; i--) { 10411 vport = &VPORT(i); 10412 vpip = vport->vpip; 10413 10414 if ((vpip->state == VPI_STATE_OFFLINE) || 10415 (vpip->vfip != vfip)) { 10416 continue; 10417 } 10418 10419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10420 "vfi_vpi_offline_action:%d. Offlining VPI:%d. >", 10421 vfip->VFI, 10422 vpip->VPI); 10423 10424 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_OFFLINE, vpip); 10425 } 10426 10427 /* Wait for FCF_EVENT_VPI_OFFLINE in return */ 10428 10429 return (0); 10430 10431 } /* emlxs_vfi_vpi_offline_action() */ 10432 10433 10434 /*ARGSUSED*/ 10435 static uint32_t 10436 emlxs_vfi_paused_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10437 void *arg1) 10438 { 10439 emlxs_hba_t *hba = HBA; 10440 emlxs_port_t *vport; 10441 int32_t i; 10442 VPIobj_t *vpip; 10443 10444 if (vfip->state != VFI_STATE_PAUSED) { 10445 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10446 "vfi_paused_action:%d %s:%s arg=%p. " 10447 "Invalid state. <", 10448 vfip->VFI, 10449 emlxs_vfi_state_xlate(vfip->state), 10450 emlxs_fcf_event_xlate(evt), arg1); 10451 return (1); 10452 } 10453 10454 vfip->flag &= ~(EMLXS_VFI_OFFLINE_REQ | EMLXS_VFI_PAUSE_REQ); 10455 10456 /* Pause all VPI's of this VFI */ 10457 for (i = hba->vpi_max; i >= 0; i--) { 10458 vport = &VPORT(i); 10459 vpip = vport->vpip; 10460 10461 if ((vpip->state == VPI_STATE_PAUSED) || 10462 (vpip->vfip != vfip)) { 10463 continue; 10464 } 10465 10466 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10467 "vfi_paused_action:%d vpi_online=%d. Pausing VPI:%d. >", 10468 vfip->VFI, 10469 vfip->vpi_online, 10470 vpip->VPI); 10471 10472 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_PAUSE, vpip); 10473 } 10474 10475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10476 "vfi_paused_action:%d vpi_online=%d. VFI paused. <", 10477 vfip->VFI, 10478 vfip->vpi_online); 10479 10480 return (0); 10481 10482 } /* emlxs_vfi_paused_action() */ 10483 10484 10485 /*ARGSUSED*/ 10486 static uint32_t 10487 emlxs_vfi_unreg_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10488 void *arg1) 10489 { 10490 uint32_t rval = 0; 10491 10492 vfip->attempts++; 10493 10494 if (vfip->state != VFI_STATE_UNREG_FAILED) { 10495 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10496 "vfi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 10497 "Invalid state. <", 10498 vfip->VFI, 10499 emlxs_vfi_state_xlate(vfip->state), 10500 emlxs_fcf_event_xlate(evt), arg1, 10501 vfip->attempts); 10502 return (1); 10503 } 10504 10505 if (vfip->attempts >= 3) { 10506 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10507 "vfi_unreg_failed_action:%d attempt=%d. Unreg cmpl.", 10508 vfip->VFI, 10509 vfip->attempts); 10510 10511 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 10512 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 10513 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_CMPL, 10514 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10515 } else { 10516 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10517 "vfi_unreg_failed_action:%d attempt=%d. Unregistering.", 10518 vfip->VFI, 10519 vfip->attempts); 10520 10521 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG, 10522 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10523 } 10524 10525 return (rval); 10526 10527 } /* emlxs_vfi_unreg_failed_action() */ 10528 10529 10530 /*ARGSUSED*/ 10531 static uint32_t 10532 emlxs_vfi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 10533 { 10534 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 10535 MAILBOX4 *mb4; 10536 VFIobj_t *vfip; 10537 10538 vfip = (VFIobj_t *)mbq->context; 10539 mb4 = (MAILBOX4 *)mbq; 10540 10541 mutex_enter(&EMLXS_FCF_LOCK); 10542 10543 if (vfip->state != VFI_STATE_UNREG) { 10544 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10545 "vfi_unreg_mbcmpl:%d state=%s.", 10546 vfip->VFI, 10547 emlxs_vfi_state_xlate(vfip->state)); 10548 10549 mutex_exit(&EMLXS_FCF_LOCK); 10550 return (0); 10551 } 10552 10553 if (mb4->mbxStatus) { 10554 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10555 "vfi_unreg_mbcmpl:%d failed. %s. >", 10556 vfip->VFI, 10557 emlxs_mb_xlate_status(mb4->mbxStatus)); 10558 10559 (void) emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED, 10560 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 10561 10562 mutex_exit(&EMLXS_FCF_LOCK); 10563 return (0); 10564 } 10565 10566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10567 "vfi_unreg_mbcmpl:%d. Unreg complete. >", 10568 vfip->VFI); 10569 10570 vfip->flag &= ~(EMLXS_VFI_REG | EMLXS_VFI_INIT); 10571 (void) emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_CMPL, 10572 0, 0, 0); 10573 10574 mutex_exit(&EMLXS_FCF_LOCK); 10575 return (0); 10576 10577 } /* emlxs_vfi_unreg_mbcmpl() */ 10578 10579 10580 /*ARGSUSED*/ 10581 static uint32_t 10582 emlxs_vfi_unreg_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10583 void *arg1) 10584 { 10585 emlxs_hba_t *hba = HBA; 10586 MAILBOX4 *mb4; 10587 MAILBOXQ *mbq; 10588 uint32_t rval = 0; 10589 10590 if (vfip->state != VFI_STATE_UNREG) { 10591 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10592 "vfi_unreg_action:%d %s:%s arg=%p. " 10593 "Invalid state. <", 10594 vfip->VFI, 10595 emlxs_vfi_state_xlate(vfip->state), 10596 emlxs_fcf_event_xlate(evt), arg1); 10597 return (1); 10598 } 10599 10600 if (!(vfip->flag & EMLXS_VFI_REG)) { 10601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10602 "vfi_unreg_action:%d. Not registered. Skipping UNREG_VFI.", 10603 vfip->VFI); 10604 10605 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE, 10606 FCF_REASON_EVENT, evt, arg1); 10607 return (rval); 10608 } 10609 10610 if (vfip->prev_state != VFI_STATE_UNREG_FAILED) { 10611 vfip->attempts = 0; 10612 } 10613 10614 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10615 "vfi_unreg_action:%d attempts=%d. Sending UNREG_VFI. <", 10616 vfip->VFI, 10617 vfip->attempts); 10618 10619 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 10620 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED, 10621 FCF_REASON_NO_MBOX, 0, arg1); 10622 10623 return (rval); 10624 } 10625 mb4 = (MAILBOX4*)mbq; 10626 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 10627 10628 mbq->nonembed = NULL; 10629 mbq->mbox_cmpl = emlxs_vfi_unreg_mbcmpl; 10630 mbq->context = (void *)vfip; 10631 mbq->port = (void *)port; 10632 10633 mb4->un.varUnRegVFI4.vfi = vfip->VFI; 10634 mb4->mbxCommand = MBX_UNREG_VFI; 10635 mb4->mbxOwner = OWN_HOST; 10636 10637 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 10638 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 10639 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 10640 10641 rval = emlxs_vfi_state(port, vfip, VFI_STATE_UNREG_FAILED, 10642 FCF_REASON_SEND_FAILED, rval, arg1); 10643 10644 return (rval); 10645 } 10646 10647 return (0); 10648 10649 } /* emlxs_vfi_unreg_action() */ 10650 10651 10652 /*ARGSUSED*/ 10653 static uint32_t 10654 emlxs_vfi_unreg_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10655 void *arg1) 10656 { 10657 uint32_t rval = 0; 10658 10659 if (vfip->state != VFI_STATE_UNREG_CMPL) { 10660 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10661 "vfi_unreg_cmpl_action:%d %s:%s arg=%p. " 10662 "Invalid state. <", 10663 vfip->VFI, 10664 emlxs_vfi_state_xlate(vfip->state), 10665 emlxs_fcf_event_xlate(evt), arg1); 10666 return (1); 10667 } 10668 10669 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10670 "vfi_unreg_cmpl_action:%d attempts=%d. Going offline.", 10671 vfip->VFI, 10672 vfip->attempts); 10673 10674 rval = emlxs_vfi_state(port, vfip, VFI_STATE_OFFLINE, 10675 FCF_REASON_EVENT, evt, arg1); 10676 10677 return (rval); 10678 10679 } /* emlxs_vfi_unreg_cmpl_action() */ 10680 10681 10682 /*ARGSUSED*/ 10683 static uint32_t 10684 emlxs_vfi_reg_failed_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10685 void *arg1) 10686 { 10687 uint32_t rval = 0; 10688 10689 vfip->attempts++; 10690 10691 if (vfip->state != VFI_STATE_REG_FAILED) { 10692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10693 "vfi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 10694 "Invalid state. <", 10695 vfip->VFI, 10696 emlxs_vfi_state_xlate(vfip->state), 10697 emlxs_fcf_event_xlate(evt), arg1, 10698 vfip->attempts); 10699 return (1); 10700 } 10701 10702 if ((vfip->reason == FCF_REASON_SEND_FAILED) || 10703 (vfip->attempts >= 3)) { 10704 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10705 "vfi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.", 10706 vfip->VFI, 10707 vfip->attempts, 10708 vfip->reason); 10709 10710 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 10711 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 10712 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_CMPL, 10713 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10714 } else { 10715 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10716 "vfi_reg_failed_action:%d attempt=%d. Registering.", 10717 vfip->VFI, 10718 vfip->attempts); 10719 10720 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG, 10721 FCF_REASON_OP_FAILED, vfip->attempts, arg1); 10722 } 10723 10724 return (rval); 10725 10726 } /* emlxs_vfi_reg_failed_action() */ 10727 10728 10729 /*ARGSUSED*/ 10730 static uint32_t 10731 emlxs_vfi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 10732 { 10733 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 10734 MAILBOX4 *mb4; 10735 VFIobj_t *vfip; 10736 MATCHMAP *mp; 10737 10738 vfip = (VFIobj_t *)mbq->context; 10739 mb4 = (MAILBOX4 *)mbq; 10740 10741 mutex_enter(&EMLXS_FCF_LOCK); 10742 10743 if (vfip->state != VFI_STATE_REG) { 10744 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10745 "vfi_reg_mbcmpl:%d state=%s.", 10746 vfip->VFI, 10747 emlxs_vfi_state_xlate(vfip->state)); 10748 10749 mutex_exit(&EMLXS_FCF_LOCK); 10750 return (0); 10751 } 10752 10753 if (mb4->mbxStatus) { 10754 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10755 "vfi_reg_mbcmpl:%d failed. %s. >", 10756 vfip->VFI, 10757 emlxs_mb_xlate_status(mb4->mbxStatus)); 10758 10759 (void) emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED, 10760 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 10761 10762 mutex_exit(&EMLXS_FCF_LOCK); 10763 return (0); 10764 } 10765 10766 /* Archive a copy of the sparams in case we need them later */ 10767 mp = (MATCHMAP *)mbq->bp; 10768 bcopy((uint32_t *)mp->virt, (uint32_t *)&vfip->sparam, 10769 sizeof (SERV_PARM)); 10770 10771 if (vfip->flogi_vpip) { 10772 if (mb4->un.varRegVFI4.vp == 1) { 10773 vfip->flogi_vpip->flag |= EMLXS_VPI_REG; 10774 } 10775 vfip->flogi_vpip = NULL; 10776 } 10777 10778 vfip->flag |= EMLXS_VFI_REG; 10779 10780 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10781 "vfi_reg_mbcmpl:%d. Reg complete. >", 10782 vfip->VFI); 10783 10784 (void) emlxs_vfi_state(port, vfip, VFI_STATE_REG_CMPL, 0, 0, 0); 10785 10786 mutex_exit(&EMLXS_FCF_LOCK); 10787 return (0); 10788 10789 } /* emlxs_vfi_reg_mbcmpl() */ 10790 10791 10792 /*ARGSUSED*/ 10793 static uint32_t 10794 emlxs_vfi_reg_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10795 void *arg1) 10796 { 10797 emlxs_hba_t *hba = HBA; 10798 MAILBOX4 *mb4; 10799 MAILBOXQ *mbq; 10800 MATCHMAP *mp; 10801 uint32_t rval = 0; 10802 uint32_t edtov; 10803 uint32_t ratov; 10804 SERV_PARM *flogi_sparam; 10805 uint32_t *wwpn; 10806 10807 if (vfip->state != VFI_STATE_REG) { 10808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10809 "vfi_reg_action:%d %s:%s arg=%p. " 10810 "Invalid state. <", 10811 vfip->VFI, 10812 emlxs_vfi_state_xlate(vfip->state), 10813 emlxs_fcf_event_xlate(evt), arg1); 10814 return (1); 10815 } 10816 10817 if (vfip->prev_state != VFI_STATE_REG_FAILED) { 10818 vfip->attempts = 0; 10819 } 10820 10821 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 10822 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10823 "vfi_reg_action:%d %attempts=%d. Offline requested.", 10824 vfip->VFI, 10825 vfip->attempts); 10826 10827 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10828 return (rval); 10829 } 10830 10831 if (!vfip->flogi_vpip) { 10832 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10833 "vfi_reg_action:%d %attempts=%d. No flogi_vpi found.", 10834 vfip->VFI, 10835 vfip->attempts); 10836 10837 vfip->flag &= ~EMLXS_VFI_REQ_MASK; 10838 vfip->flag |= EMLXS_VFI_OFFLINE_REQ; 10839 10840 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10841 return (rval); 10842 } 10843 10844 if ((hba->model_info.chip & EMLXS_BE_CHIPS) && 10845 (vfip->flag & EMLXS_VFI_REG)) { 10846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10847 "vfi_reg_action:%d flag=%x. " 10848 "Already registered. Skipping REG_VFI update.", 10849 vfip->VFI); 10850 10851 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE, 10852 FCF_REASON_EVENT, evt, arg1); 10853 return (rval); 10854 } 10855 10856 /* Get the flogi_vpip's fabric_rpip's service parameters */ 10857 flogi_sparam = &vfip->flogi_vpip->fabric_rpip->sparam; 10858 10859 if (flogi_sparam->cmn.edtovResolution) { 10860 edtov = (LE_SWAP32(flogi_sparam->cmn.e_d_tov) + 999999) / 10861 1000000; 10862 } else { 10863 edtov = LE_SWAP32(flogi_sparam->cmn.e_d_tov); 10864 } 10865 10866 ratov = (LE_SWAP32(flogi_sparam->cmn.w2.r_a_tov) + 999) / 1000; 10867 10868 if (vfip->flag & EMLXS_VFI_REG) { 10869 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10870 "vfi_reg_action:%d attempts=%d edtov=%d ratov=%d. " 10871 "Updating REG_VFI. <", 10872 vfip->VFI, 10873 vfip->attempts, 10874 edtov, ratov); 10875 } else { 10876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10877 "vfi_reg_action:%d attempts=%d edtov=%d ratov=%d. " 10878 "Sending REG_VFI. <", 10879 vfip->VFI, 10880 vfip->attempts, 10881 edtov, ratov); 10882 } 10883 10884 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 10885 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED, 10886 FCF_REASON_NO_MBOX, 0, arg1); 10887 10888 return (rval); 10889 } 10890 mb4 = (MAILBOX4*)mbq; 10891 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 10892 10893 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 10894 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 10895 10896 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED, 10897 FCF_REASON_NO_BUFFER, 0, arg1); 10898 10899 return (1); 10900 } 10901 10902 mbq->bp = (void *)mp; 10903 mbq->nonembed = NULL; 10904 10905 mbq->mbox_cmpl = emlxs_vfi_reg_mbcmpl; 10906 mbq->context = (void *)vfip; 10907 mbq->port = (void *)port; 10908 10909 mb4->mbxCommand = MBX_REG_VFI; 10910 mb4->mbxOwner = OWN_HOST; 10911 10912 mb4->un.varRegVFI4.vfi = vfip->VFI; 10913 mb4->un.varRegVFI4.upd = (vfip->flag & EMLXS_VFI_REG)? 1:0; 10914 10915 /* If the flogi_vpip was not previously registered, */ 10916 /* perform the REG_VPI now */ 10917 if (!(vfip->flogi_vpip->flag & EMLXS_VPI_REG)) { 10918 mb4->un.varRegVFI4.vp = 1; 10919 mb4->un.varRegVFI4.vpi = vfip->flogi_vpip->VPI; 10920 } 10921 10922 mb4->un.varRegVFI4.fcfi = vfip->fcfp->FCFI; 10923 wwpn = (uint32_t *)&port->wwpn; 10924 mb4->un.varRegVFI4.portname[0] = BE_SWAP32(*wwpn); 10925 wwpn++; 10926 mb4->un.varRegVFI4.portname[1] = BE_SWAP32(*wwpn); 10927 mb4->un.varRegVFI4.sid = port->did; 10928 mb4->un.varRegVFI4.edtov = edtov; 10929 mb4->un.varRegVFI4.ratov = ratov; 10930 mb4->un.varRegVFI4.bde.tus.f.bdeSize = sizeof (SERV_PARM); 10931 mb4->un.varRegVFI4.bde.addrHigh = PADDR_HI(mp->phys); 10932 mb4->un.varRegVFI4.bde.addrLow = PADDR_LO(mp->phys); 10933 bcopy((uint32_t *)flogi_sparam, (uint32_t *)mp->virt, 10934 sizeof (SERV_PARM)); 10935 10936 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 10937 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 10938 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 10939 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 10940 10941 rval = emlxs_vfi_state(port, vfip, VFI_STATE_REG_FAILED, 10942 FCF_REASON_SEND_FAILED, rval, arg1); 10943 10944 return (rval); 10945 } 10946 10947 return (0); 10948 10949 } /* emlxs_vfi_reg_action() */ 10950 10951 10952 /*ARGSUSED*/ 10953 static uint32_t 10954 emlxs_vfi_reg_cmpl_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10955 void *arg1) 10956 { 10957 uint32_t rval = 0; 10958 10959 if (vfip->state != VFI_STATE_REG_CMPL) { 10960 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 10961 "vfi_reg_cmpl_action:%d %s:%s arg=%p. " 10962 "Invalid state. <", 10963 vfip->VFI, 10964 emlxs_vfi_state_xlate(vfip->state), 10965 emlxs_fcf_event_xlate(evt), arg1); 10966 return (1); 10967 } 10968 10969 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 10970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10971 "vfi_reg_cmpl_action:%d attempts=%d. Offline requested.", 10972 vfip->VFI, 10973 vfip->attempts); 10974 10975 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 10976 return (rval); 10977 } 10978 10979 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 10980 "vfi_reg_cmpl_action:%d attempts=%d. Going online.", 10981 vfip->VFI, 10982 vfip->attempts); 10983 10984 rval = emlxs_vfi_state(port, vfip, VFI_STATE_ONLINE, 10985 FCF_REASON_EVENT, evt, arg1); 10986 10987 return (rval); 10988 10989 } /* emlxs_vfi_reg_cmpl_action() */ 10990 10991 10992 /*ARGSUSED*/ 10993 static uint32_t 10994 emlxs_vfi_online_action(emlxs_port_t *port, VFIobj_t *vfip, uint32_t evt, 10995 void *arg1) 10996 { 10997 emlxs_hba_t *hba = HBA; 10998 uint32_t i; 10999 uint32_t rval = 0; 11000 VPIobj_t *vpip = port->vpip; 11001 emlxs_port_t *vport; 11002 11003 if (vfip->state != VFI_STATE_ONLINE) { 11004 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11005 "vfi_online_action:%d %s:%s arg=%p. " 11006 "Invalid state. <", 11007 vfip->VFI, 11008 emlxs_vfi_state_xlate(vfip->state), 11009 emlxs_fcf_event_xlate(evt), arg1); 11010 return (1); 11011 } 11012 11013 vfip->flag &= ~EMLXS_VFI_ONLINE_REQ; 11014 11015 if (vfip->flag & EMLXS_VFI_OFFLINE_REQ) { 11016 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11017 "vfi_online_action:%d attempts=%d. Offline requested.", 11018 vfip->VFI, 11019 vfip->attempts); 11020 11021 rval = emlxs_vfi_offline_handler(port, vfip, arg1); 11022 return (rval); 11023 } 11024 11025 /* Take the port's Fabric RPI online now */ 11026 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11027 "vfi_online_action:%d. Onlining Fabric RPI. >", 11028 vfip->VFI); 11029 11030 /* This will complete the FLOGI/FDISC back to Leadville */ 11031 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_ONLINE, 11032 vpip->fabric_rpip); 11033 11034 /* FLOGI/FDISC has been completed back to Leadville */ 11035 /* It is now safe to accept unsolicited requests */ 11036 vpip->flag |= EMLXS_VPI_PORT_ENABLED; 11037 11038 /* Online remaining VPI's */ 11039 for (i = 0; i <= hba->vpi_max; i++) { 11040 vport = &VPORT(i); 11041 vpip = vport->vpip; 11042 11043 if (!(vport->flag & EMLXS_PORT_BOUND) || 11044 (vpip->flag & EMLXS_VPI_PORT_UNBIND)) { 11045 continue; 11046 } 11047 11048 if ((vpip->state == VPI_STATE_ONLINE) || 11049 (vpip->flag & EMLXS_VPI_ONLINE_REQ)) { 11050 continue; 11051 } 11052 11053 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11054 "vfi_online_action:%d vpi_online=%d logi_count=%d. " 11055 "Onlining VPI:%d >", 11056 vfip->VFI, 11057 vfip->vpi_online, 11058 vfip->logi_count, 11059 vpip->VPI); 11060 11061 vpip->vfip = vfip; 11062 (void) emlxs_vpi_event(vport, FCF_EVENT_VPI_ONLINE, vpip); 11063 } 11064 11065 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11066 "vfi_online_action:%d vpi_online=%d logi_count=%d. " 11067 "VFI online. Notifying FCFI:%d. >", 11068 vfip->VFI, 11069 vfip->vpi_online, 11070 vfip->logi_count, 11071 vfip->fcfp->fcf_index); 11072 11073 /* Notify FCFI */ 11074 rval = emlxs_fcfi_event(port, FCF_EVENT_VFI_ONLINE, vfip); 11075 11076 return (rval); 11077 11078 } /* emlxs_vfi_online_action() */ 11079 11080 11081 /* ************************************************************************** */ 11082 /* VPI */ 11083 /* ************************************************************************** */ 11084 11085 static char * 11086 emlxs_vpi_state_xlate(uint32_t state) 11087 { 11088 static char buffer[32]; 11089 uint32_t i; 11090 uint32_t count; 11091 11092 count = sizeof (emlxs_vpi_state_table) / sizeof (emlxs_table_t); 11093 for (i = 0; i < count; i++) { 11094 if (state == emlxs_vpi_state_table[i].code) { 11095 return (emlxs_vpi_state_table[i].string); 11096 } 11097 } 11098 11099 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 11100 return (buffer); 11101 11102 } /* emlxs_vpi_state_xlate() */ 11103 11104 11105 static uint32_t 11106 emlxs_vpi_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 11107 void *arg1) 11108 { 11109 uint32_t rval = 0; 11110 uint32_t(*func) (emlxs_port_t *, VPIobj_t *, uint32_t, void *); 11111 uint32_t index; 11112 uint32_t events; 11113 uint16_t state; 11114 11115 /* Convert event to action table index */ 11116 switch (evt) { 11117 case FCF_EVENT_STATE_ENTER: 11118 index = 0; 11119 break; 11120 case FCF_EVENT_VPI_ONLINE: 11121 index = 1; 11122 break; 11123 case FCF_EVENT_VPI_OFFLINE: 11124 index = 2; 11125 break; 11126 case FCF_EVENT_VPI_PAUSE: 11127 index = 3; 11128 break; 11129 case FCF_EVENT_RPI_ONLINE: 11130 index = 4; 11131 break; 11132 case FCF_EVENT_RPI_OFFLINE: 11133 index = 5; 11134 break; 11135 case FCF_EVENT_RPI_PAUSE: 11136 index = 6; 11137 break; 11138 default: 11139 return (1); 11140 } 11141 11142 events = VPI_ACTION_EVENTS; 11143 state = vpip->state; 11144 11145 index += (state * events); 11146 func = (uint32_t(*) (emlxs_port_t *, VPIobj_t *, uint32_t, void *)) 11147 emlxs_vpi_action_table[index]; 11148 11149 if (!func) { 11150 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 11151 "vpi_action:%d %s:%s arg=%p. No action. <", 11152 vpip->VPI, 11153 emlxs_vpi_state_xlate(vpip->state), 11154 emlxs_fcf_event_xlate(evt), arg1); 11155 11156 return (1); 11157 } 11158 11159 rval = (func)(port, vpip, evt, arg1); 11160 11161 return (rval); 11162 11163 } /* emlxs_vpi_action() */ 11164 11165 11166 static uint32_t 11167 emlxs_vpi_event(emlxs_port_t *port, uint32_t evt, 11168 void *arg1) 11169 { 11170 VPIobj_t *vpip = NULL; 11171 RPIobj_t *rpip; 11172 uint32_t rval = 0; 11173 11174 /* Filter events and acquire fcfi context */ 11175 switch (evt) { 11176 case FCF_EVENT_RPI_ONLINE: 11177 case FCF_EVENT_RPI_OFFLINE: 11178 case FCF_EVENT_RPI_PAUSE: 11179 rpip = (RPIobj_t *)arg1; 11180 11181 if (!rpip) { 11182 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 11183 "vpi_event: %s arg=%p. Null RPI found. <", 11184 emlxs_fcf_event_xlate(evt), arg1); 11185 11186 return (1); 11187 } 11188 11189 vpip = rpip->vpip; 11190 break; 11191 11192 case FCF_EVENT_VPI_ONLINE: 11193 case FCF_EVENT_VPI_PAUSE: 11194 case FCF_EVENT_VPI_OFFLINE: 11195 vpip = (VPIobj_t *)arg1; 11196 11197 if (!vpip) { 11198 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 11199 "vpi_event: %s arg=%p. Null VPI found. <", 11200 emlxs_fcf_event_xlate(evt), arg1); 11201 11202 return (1); 11203 } 11204 11205 break; 11206 11207 default: 11208 return (1); 11209 } 11210 11211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 11212 "vpi_event:%d %s:%s arg=%p", 11213 vpip->VPI, 11214 emlxs_vpi_state_xlate(vpip->state), 11215 emlxs_fcf_event_xlate(evt), arg1); 11216 11217 rval = emlxs_vpi_action(port, vpip, evt, arg1); 11218 11219 return (rval); 11220 11221 } /* emlxs_vpi_event() */ 11222 11223 11224 /*ARGSUSED*/ 11225 static uint32_t 11226 emlxs_vpi_state(emlxs_port_t *port, VPIobj_t *vpip, uint16_t state, 11227 uint16_t reason, uint32_t explain, void *arg1) 11228 { 11229 uint32_t rval = 0; 11230 11231 if (state >= VPI_ACTION_STATES) { 11232 return (1); 11233 } 11234 11235 if ((vpip->state == state) && 11236 (reason != FCF_REASON_REENTER)) { 11237 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11238 "vpi_state:%d %s:%s:0x%x arg=%p. " 11239 "State not changed. <", 11240 vpip->VPI, 11241 emlxs_vpi_state_xlate(vpip->state), 11242 emlxs_fcf_reason_xlate(reason), 11243 explain, arg1); 11244 return (1); 11245 } 11246 11247 if (!reason) { 11248 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 11249 "vpi_state:%d %s-->%s arg=%p", 11250 vpip->VPI, 11251 emlxs_vpi_state_xlate(vpip->state), 11252 emlxs_vpi_state_xlate(state), arg1); 11253 } else if (reason == FCF_REASON_EVENT) { 11254 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 11255 "vpi_state:%d %s-->%s:%s:%s arg=%p", 11256 vpip->VPI, 11257 emlxs_vpi_state_xlate(vpip->state), 11258 emlxs_vpi_state_xlate(state), 11259 emlxs_fcf_reason_xlate(reason), 11260 emlxs_fcf_event_xlate(explain), arg1); 11261 } else if (explain) { 11262 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 11263 "vpi_state:%d %s-->%s:%s:0x%x arg=%p", 11264 vpip->VPI, 11265 emlxs_vpi_state_xlate(vpip->state), 11266 emlxs_vpi_state_xlate(state), 11267 emlxs_fcf_reason_xlate(reason), 11268 explain, arg1); 11269 } else { 11270 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 11271 "vpi_state:%d %s-->%s:%s arg=%p", 11272 vpip->VPI, 11273 emlxs_vpi_state_xlate(vpip->state), 11274 emlxs_vpi_state_xlate(state), 11275 emlxs_fcf_reason_xlate(reason), arg1); 11276 } 11277 11278 vpip->prev_state = vpip->state; 11279 vpip->prev_reason = vpip->reason; 11280 vpip->state = state; 11281 vpip->reason = reason; 11282 11283 rval = emlxs_vpi_action(port, vpip, FCF_EVENT_STATE_ENTER, arg1); 11284 11285 return (rval); 11286 11287 } /* emlxs_vpi_state() */ 11288 11289 11290 extern uint32_t 11291 emlxs_vpi_port_bind_notify(emlxs_port_t *port) 11292 { 11293 emlxs_hba_t *hba = HBA; 11294 VPIobj_t *vpip = port->vpip; 11295 FCFTable_t *fcftab = &hba->sli.sli4.fcftab; 11296 uint32_t rval = 0; 11297 VFIobj_t *vfip; 11298 VFIobj_t *vfip1; 11299 uint32_t i = 0; 11300 FCFIobj_t *fcfp; 11301 FCFIobj_t *fcfp1; 11302 11303 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 11304 return (1); 11305 } 11306 11307 if (hba->state < FC_LINK_UP) { 11308 if (port->vpi == 0) { 11309 (void) emlxs_reset_link(hba, 1, 0); 11310 11311 /* Wait for VPI to go online */ 11312 while ((vpip->state != VPI_STATE_PORT_ONLINE) && 11313 (hba->state != FC_ERROR)) { 11314 delay(drv_usectohz(500000)); 11315 if (i++ > 30) { 11316 break; 11317 } 11318 } 11319 } 11320 return (0); 11321 } 11322 11323 mutex_enter(&EMLXS_FCF_LOCK); 11324 11325 if (vpip->vfip) { 11326 vfip = vpip->vfip; 11327 fcfp = vfip->fcfp; 11328 goto done; 11329 } 11330 11331 /* We need to select a VFI for this VPI */ 11332 11333 /* First find a selected Fabric */ 11334 fcfp = NULL; 11335 for (i = 0; i < fcftab->fcfi_count; i++) { 11336 fcfp1 = fcftab->fcfi[i]; 11337 11338 if (fcfp1->flag & EMLXS_FCFI_SELECTED) { 11339 fcfp = fcfp1; 11340 break; 11341 } 11342 } 11343 11344 if (!fcfp) { 11345 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11346 "vpi_port_bind_notify:%d %s. " 11347 "No FCF available yet.", 11348 vpip->VPI, 11349 emlxs_vpi_state_xlate(vpip->state)); 11350 11351 mutex_exit(&EMLXS_FCF_LOCK); 11352 return (0); 11353 } 11354 11355 /* Find first available VFI for this FCFI */ 11356 vfip = NULL; 11357 vfip1 = hba->sli.sli4.VFI_table; 11358 for (i = 0; i < hba->sli.sli4.VFICount; i++, vfip1++) { 11359 if (vfip1->fcfp == fcfp) { 11360 vfip = vfip1; 11361 break; 11362 } 11363 } 11364 11365 if (!vfip) { 11366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11367 "vpi_port_bind_notify:%d %s fcfi:%d. " 11368 "No VFI available yet.", 11369 vpip->VPI, 11370 emlxs_vpi_state_xlate(vpip->state), 11371 fcfp->fcf_index); 11372 11373 mutex_exit(&EMLXS_FCF_LOCK); 11374 return (0); 11375 } 11376 11377 vpip->vfip = vfip; 11378 done: 11379 11380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11381 "vpi_port_bind_notify:%d %s fcfi:%d vfi:%d. Onlining VPI:%d >", 11382 vpip->VPI, 11383 emlxs_vpi_state_xlate(vpip->state), 11384 fcfp->fcf_index, 11385 vfip->VFI, 11386 vpip->VPI); 11387 11388 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_ONLINE, vpip); 11389 11390 mutex_exit(&EMLXS_FCF_LOCK); 11391 11392 return (rval); 11393 11394 } /* emlxs_vpi_port_bind_notify() */ 11395 11396 11397 extern uint32_t 11398 emlxs_vpi_port_unbind_notify(emlxs_port_t *port, uint32_t wait) 11399 { 11400 emlxs_hba_t *hba = HBA; 11401 VPIobj_t *vpip = port->vpip; 11402 uint32_t rval = 0; 11403 VFIobj_t *vfip; 11404 uint32_t i; 11405 FCFIobj_t *fcfp; 11406 11407 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 11408 return (1); 11409 } 11410 11411 if (!(hba->sli.sli4.flag & EMLXS_SLI4_FCF_INIT)) { 11412 return (0); 11413 } 11414 11415 mutex_enter(&EMLXS_FCF_LOCK); 11416 11417 if (vpip->state == VPI_STATE_OFFLINE) { 11418 mutex_exit(&EMLXS_FCF_LOCK); 11419 return (0); 11420 } 11421 11422 /* 11423 * Set flag to indicate that emlxs_vpi_port_unbind_notify 11424 * has been called 11425 */ 11426 vpip->flag |= EMLXS_VPI_PORT_UNBIND; 11427 11428 vfip = vpip->vfip; 11429 fcfp = vfip->fcfp; 11430 11431 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11432 "vpi_port_unbind_notify:%d %s fcfi:%d vfi:%d. " 11433 "Offlining VPI:%d,%d >", 11434 vpip->VPI, 11435 emlxs_vpi_state_xlate(vpip->state), 11436 fcfp->fcf_index, 11437 vfip->VFI, 11438 vpip->index, vpip->VPI); 11439 11440 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 11441 11442 if (wait && (rval == 0)) { 11443 /* Wait for VPI to go offline */ 11444 i = 0; 11445 while (i++ < 120) { 11446 if (vpip->state == VPI_STATE_OFFLINE) { 11447 break; 11448 } 11449 11450 mutex_exit(&EMLXS_FCF_LOCK); 11451 BUSYWAIT_MS(1000); 11452 mutex_enter(&EMLXS_FCF_LOCK); 11453 } 11454 11455 if (i >= 120) { 11456 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11457 "vpi_port_unbind_notify:%d %s fcfi:%d vfi:%d " 11458 "rpi_online=%d,%d. Offline timeout.", 11459 vpip->VPI, 11460 emlxs_vpi_state_xlate(vpip->state), 11461 fcfp->fcf_index, 11462 vfip->VFI, 11463 vpip->rpi_online, vpip->rpi_paused); 11464 } 11465 } 11466 11467 vpip->flag &= ~EMLXS_VPI_PORT_UNBIND; 11468 11469 mutex_exit(&EMLXS_FCF_LOCK); 11470 11471 return (rval); 11472 11473 } /* emlxs_vpi_port_unbind_notify() */ 11474 11475 11476 /*ARGSUSED*/ 11477 static uint32_t 11478 emlxs_vpi_rpi_offline_evt_action(emlxs_port_t *port, VPIobj_t *vpip, 11479 uint32_t evt, void *arg1) 11480 { 11481 uint32_t rval = 0; 11482 RPIobj_t *rpip = (RPIobj_t *)arg1; 11483 11484 if (evt != FCF_EVENT_RPI_OFFLINE) { 11485 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11486 "vpi_rpi_offline_evt_action:%d %s:%s arg=%p flag=%x. " 11487 "Invalid event type. <", 11488 vpip->VPI, 11489 emlxs_vpi_state_xlate(vpip->state), 11490 emlxs_fcf_event_xlate(evt), arg1, 11491 vpip->flag); 11492 return (1); 11493 } 11494 11495 switch (vpip->state) { 11496 case VPI_STATE_LOGO: 11497 /* rpi_online will be checked when LOGO is complete */ 11498 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11499 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x " 11500 "rpi=%d. Waiting for LOGO. <", 11501 vpip->VPI, 11502 vpip->rpi_online, vpip->rpi_paused, 11503 rpip->did, rpip->RPI); 11504 11505 rval = 0; 11506 break; 11507 11508 case VPI_STATE_PORT_OFFLINE: 11509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11510 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x " 11511 "rpi=%d.", 11512 vpip->VPI, 11513 vpip->rpi_online, vpip->rpi_paused, 11514 rpip->did, rpip->RPI); 11515 11516 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 11517 FCF_REASON_REENTER, evt, arg1); 11518 break; 11519 11520 case VPI_STATE_PAUSED: 11521 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11522 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x " 11523 "rpi=%d. VPI paused. <", 11524 vpip->VPI, 11525 vpip->rpi_online, vpip->rpi_paused, 11526 rpip->did, rpip->RPI); 11527 11528 rval = 0; 11529 break; 11530 11531 case VPI_STATE_ONLINE: 11532 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11533 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x " 11534 "rpi=%d. <", 11535 vpip->VPI, 11536 vpip->rpi_online, vpip->rpi_paused, 11537 rpip->did, rpip->RPI); 11538 11539 rval = 0; 11540 break; 11541 11542 default: 11543 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11544 "vpi_rpi_offline_evt_action:%d rpi_online=%d,%d did=%x " 11545 "rpi=%d. " 11546 "Invalid state. <", 11547 vpip->VPI, 11548 vpip->rpi_online, vpip->rpi_paused, 11549 rpip->did, rpip->RPI); 11550 11551 rval = 1; 11552 break; 11553 } 11554 11555 return (rval); 11556 11557 } /* emlxs_vpi_rpi_offline_evt_action() */ 11558 11559 11560 /*ARGSUSED*/ 11561 static uint32_t 11562 emlxs_vpi_rpi_pause_evt_action(emlxs_port_t *port, VPIobj_t *vpip, 11563 uint32_t evt, void *arg1) 11564 { 11565 uint32_t rval = 0; 11566 RPIobj_t *rpip = (RPIobj_t *)arg1; 11567 11568 if (evt != FCF_EVENT_RPI_PAUSE) { 11569 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11570 "vpi_rpi_pause_evt_action:%d %s:%s arg=%p flag=%x. " 11571 "Invalid event type. <", 11572 vpip->VPI, 11573 emlxs_vpi_state_xlate(vpip->state), 11574 emlxs_fcf_event_xlate(evt), arg1, 11575 vpip->flag); 11576 return (1); 11577 } 11578 11579 switch (vpip->state) { 11580 case VPI_STATE_LOGO: 11581 /* rpi_online will be checked when LOGO is complete */ 11582 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11583 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x " 11584 "rpi=%d. Waiting for LOGO. <", 11585 vpip->VPI, 11586 vpip->rpi_online, vpip->rpi_paused, 11587 rpip->did, rpip->RPI); 11588 11589 rval = 0; 11590 break; 11591 11592 case VPI_STATE_PORT_OFFLINE: 11593 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11594 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x " 11595 "rpi=%d.", 11596 vpip->VPI, 11597 vpip->rpi_online, vpip->rpi_paused, 11598 rpip->did, rpip->RPI); 11599 11600 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 11601 FCF_REASON_REENTER, 0, 0); 11602 break; 11603 11604 case VPI_STATE_PAUSED: 11605 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11606 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x " 11607 "rpi=%d. VPI already paused. <", 11608 vpip->VPI, 11609 vpip->rpi_online, vpip->rpi_paused, 11610 rpip->did, rpip->RPI); 11611 11612 rval = 0; 11613 break; 11614 11615 default: 11616 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11617 "vpi_rpi_pause_evt_action:%d rpi_online=%d,%d did=%x " 11618 "rpi=%d. " 11619 "Invalid state. <", 11620 vpip->VPI, 11621 vpip->rpi_online, vpip->rpi_paused, 11622 rpip->did, rpip->RPI); 11623 11624 rval = 1; 11625 break; 11626 } 11627 11628 return (rval); 11629 11630 } /* emlxs_vpi_rpi_pause_evt_action() */ 11631 11632 11633 /*ARGSUSED*/ 11634 static uint32_t 11635 emlxs_vpi_rpi_online_evt_action(emlxs_port_t *port, VPIobj_t *vpip, 11636 uint32_t evt, void *arg1) 11637 { 11638 RPIobj_t *rpip = (RPIobj_t *)arg1; 11639 11640 if (evt != FCF_EVENT_RPI_ONLINE) { 11641 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11642 "vpi_rpi_online_evt_action:%d %s:%s arg=%p flag=%x. " 11643 "Invalid event type. <", 11644 vpip->VPI, 11645 emlxs_vpi_state_xlate(vpip->state), 11646 emlxs_fcf_event_xlate(evt), arg1, 11647 vpip->flag); 11648 return (1); 11649 } 11650 11651 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11652 "vpi_rpi_online_evt_action:%d rpi_online=%d,%d did=%x rpi=%d. <", 11653 vpip->VPI, 11654 vpip->rpi_online, vpip->rpi_paused, 11655 rpip->did, rpip->RPI); 11656 11657 return (0); 11658 11659 } /* emlxs_vpi_rpi_online_evt_action() */ 11660 11661 11662 /*ARGSUSED*/ 11663 static uint32_t 11664 emlxs_vpi_online_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 11665 void *arg1) 11666 { 11667 uint32_t rval = 0; 11668 11669 if (evt != FCF_EVENT_VPI_ONLINE) { 11670 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11671 "vpi_online_evt_action:%d %s:%s arg=%p flag=%x. " 11672 "Invalid event type. <", 11673 vpip->VPI, 11674 emlxs_vpi_state_xlate(vpip->state), 11675 emlxs_fcf_event_xlate(evt), arg1, 11676 vpip->flag); 11677 return (1); 11678 } 11679 11680 if (vpip->flag & EMLXS_VPI_ONLINE_REQ) { 11681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11682 "vpi_online_evt_action:%d flag=%x. " 11683 "Online already requested. <", 11684 vpip->VPI, 11685 vpip->flag); 11686 return (1); 11687 } 11688 11689 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 11690 vpip->flag |= EMLXS_VPI_ONLINE_REQ; 11691 11692 switch (vpip->state) { 11693 case VPI_STATE_OFFLINE: 11694 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11695 "vpi_online_evt_action:%d flag=%x. Initiating online.", 11696 vpip->VPI, 11697 vpip->flag); 11698 11699 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT, 11700 FCF_REASON_EVENT, evt, arg1); 11701 break; 11702 11703 case VPI_STATE_PORT_OFFLINE: 11704 case VPI_STATE_PAUSED: 11705 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11706 "vpi_online_evt_action:%d flag=%x. Initiating online.", 11707 vpip->VPI, 11708 vpip->flag); 11709 11710 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 11711 FCF_REASON_EVENT, evt, arg1); 11712 break; 11713 11714 default: 11715 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11716 "vpi_online_evt_action:%d flag=%x. <", 11717 vpip->VPI, 11718 vpip->flag); 11719 return (1); 11720 } 11721 11722 return (rval); 11723 11724 } /* emlxs_vpi_online_evt_action() */ 11725 11726 11727 /*ARGSUSED*/ 11728 static uint32_t 11729 emlxs_vpi_offline_handler(emlxs_port_t *port, VPIobj_t *vpip, void *arg1) 11730 { 11731 uint32_t rval = 0; 11732 11733 if (!(vpip->flag & EMLXS_VPI_OFFLINE_REQ)) { 11734 return (0); 11735 } 11736 11737 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) { 11738 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 11739 FCF_REASON_REQUESTED, 0, arg1); 11740 11741 } else if (vpip->flag & EMLXS_VPI_LOGI) { 11742 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO, 11743 FCF_REASON_REQUESTED, 0, arg1); 11744 11745 } else if (vpip->flag & EMLXS_VPI_REG) { 11746 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 11747 FCF_REASON_REQUESTED, 0, arg1); 11748 11749 } else if (vpip->flag & EMLXS_VPI_INIT) { 11750 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 11751 FCF_REASON_REQUESTED, 0, arg1); 11752 11753 } else { 11754 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE, 11755 FCF_REASON_REQUESTED, 0, arg1); 11756 } 11757 11758 return (rval); 11759 11760 } /* emlxs_vpi_offline_handler() */ 11761 11762 11763 /*ARGSUSED*/ 11764 static uint32_t 11765 emlxs_vpi_offline_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 11766 void *arg1) 11767 { 11768 uint32_t rval = 0; 11769 uint32_t pause_req; 11770 11771 if (evt != FCF_EVENT_VPI_OFFLINE) { 11772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11773 "vpi_offline_evt_action:%d %s:%s arg=%p flag=%x. " 11774 "Invalid event type. <", 11775 vpip->VPI, 11776 emlxs_vpi_state_xlate(vpip->state), 11777 emlxs_fcf_event_xlate(evt), arg1, 11778 vpip->flag); 11779 return (1); 11780 } 11781 11782 if ((vpip->flag & EMLXS_VPI_OFFLINE_REQ) && 11783 !(vpip->flag & EMLXS_VPI_PAUSE_REQ)) { 11784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11785 "vpi_offline_evt_action:%d flag=%x. " 11786 "Offline already requested. <", 11787 vpip->VPI, 11788 vpip->flag); 11789 return (1); 11790 } 11791 11792 pause_req = vpip->flag & EMLXS_VPI_PAUSE_REQ; 11793 11794 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 11795 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 11796 11797 switch (vpip->state) { 11798 case VPI_STATE_PORT_OFFLINE: 11799 if (pause_req || vpip->rpi_paused) { 11800 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11801 "vpi_offline_evt_action:%d flag=%x. Clear nodes.", 11802 vpip->VPI, 11803 vpip->flag); 11804 11805 vpip->flag |= EMLXS_VPI_PORT_ONLINE; 11806 11807 rval = emlxs_vpi_state(port, vpip, 11808 VPI_STATE_PORT_OFFLINE, FCF_REASON_REENTER, evt, 11809 arg1); 11810 11811 break; 11812 } 11813 11814 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11815 "vpi_offline_evt_action:%d flag=%x. Handling offline.", 11816 vpip->VPI, 11817 vpip->flag); 11818 11819 /* Handle offline now */ 11820 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 11821 break; 11822 11823 case VPI_STATE_PAUSED: 11824 if (vpip->rpi_paused) { 11825 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11826 "vpi_offline_evt_action:%d flag=%x. Clear nodes.", 11827 vpip->VPI, 11828 vpip->flag); 11829 11830 vpip->flag |= EMLXS_VPI_PORT_ONLINE; 11831 11832 rval = emlxs_vpi_state(port, vpip, 11833 VPI_STATE_PORT_OFFLINE, FCF_REASON_EVENT, evt, 11834 arg1); 11835 11836 break; 11837 } 11838 11839 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11840 "vpi_offline_evt_action:%d flag=%x. Handling offline.", 11841 vpip->VPI, 11842 vpip->flag); 11843 11844 /* Handle offline now */ 11845 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 11846 break; 11847 11848 /* wait states */ 11849 case VPI_STATE_UNREG: 11850 case VPI_STATE_PORT_ONLINE: 11851 case VPI_STATE_LOGI: 11852 case VPI_STATE_INIT: 11853 case VPI_STATE_REG: 11854 case VPI_STATE_ONLINE: 11855 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11856 "vpi_offline_evt_action:%d flag=%x. Handling offline.", 11857 vpip->VPI, 11858 vpip->flag); 11859 11860 /* Handle offline now */ 11861 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 11862 break; 11863 11864 /* Transitional states */ 11865 default: 11866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11867 "vpi_offline_evt_action:%d flag=%x. <", 11868 vpip->VPI, 11869 vpip->flag); 11870 break; 11871 } 11872 11873 return (rval); 11874 11875 } /* emlxs_vpi_offline_evt_action() */ 11876 11877 11878 /*ARGSUSED*/ 11879 static uint32_t 11880 emlxs_vpi_pause_evt_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 11881 void *arg1) 11882 { 11883 emlxs_hba_t *hba = HBA; 11884 uint32_t rval = 0; 11885 11886 if (evt != FCF_EVENT_VPI_PAUSE) { 11887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 11888 "vpi_pause_evt_action:%d %s:%s arg=%p flag=%x. " 11889 "Invalid event type. <", 11890 vpip->VPI, 11891 emlxs_vpi_state_xlate(vpip->state), 11892 emlxs_fcf_event_xlate(evt), arg1, 11893 vpip->flag); 11894 return (1); 11895 } 11896 11897 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 11898 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11899 "vpi_pause_evt_action:%d flag=%x. " 11900 "Pause already requested. <", 11901 vpip->VPI, 11902 vpip->flag); 11903 return (1); 11904 } 11905 11906 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 11907 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11908 "vpi_pause_evt_action:%d flag=%x. " 11909 "Offline already requested. <", 11910 vpip->VPI, 11911 vpip->flag); 11912 return (1); 11913 } 11914 11915 if (SLI4_FC_MODE || !(hba->sli.sli4.flag & EMLXS_SLI4_DOWN_LINK)) { 11916 /* Fabric logo is implied */ 11917 emlxs_vpi_logo_handler(port, vpip); 11918 } 11919 11920 switch (vpip->state) { 11921 case VPI_STATE_PORT_OFFLINE: 11922 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11923 "vpi_pause_evt_action:%d flag=%x. " 11924 "Already offline. <", 11925 vpip->VPI, 11926 vpip->flag); 11927 break; 11928 11929 case VPI_STATE_PAUSED: 11930 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11931 "vpi_pause_evt_action:%d flag=%x. " 11932 "Already paused. <", 11933 vpip->VPI, 11934 vpip->flag); 11935 break; 11936 11937 /* Wait states */ 11938 case VPI_STATE_UNREG: 11939 case VPI_STATE_PORT_ONLINE: 11940 case VPI_STATE_LOGI: 11941 case VPI_STATE_INIT: 11942 case VPI_STATE_REG: 11943 case VPI_STATE_ONLINE: 11944 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 11945 vpip->flag |= (EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 11946 11947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11948 "vpi_pause_evt_action:%d flag=%x. Handling offline.", 11949 vpip->VPI, 11950 vpip->flag); 11951 11952 /* Handle offline now */ 11953 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 11954 break; 11955 11956 /* Transitional states */ 11957 default: 11958 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 11959 vpip->flag |= (EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 11960 11961 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 11962 "vpi_pause_evt_action:%d flag=%x. <", 11963 vpip->VPI, 11964 vpip->flag); 11965 break; 11966 } 11967 11968 return (rval); 11969 11970 } /* emlxs_vpi_pause_evt_action() */ 11971 11972 11973 /* ARGSUSED */ 11974 static void 11975 emlxs_deferred_cmpl_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 11976 { 11977 emlxs_deferred_cmpl_t *cmpl = (emlxs_deferred_cmpl_t *)arg1; 11978 uint32_t status = (uint32_t)((unsigned long)arg2); 11979 emlxs_port_t *port; 11980 uint32_t mbxStatus; 11981 emlxs_buf_t *sbp; 11982 fc_unsol_buf_t *ubp; 11983 IOCBQ *iocbq; 11984 11985 mbxStatus = (status)? MBX_FAILURE:MBX_SUCCESS; 11986 11987 port = cmpl->port; 11988 sbp = (emlxs_buf_t *)cmpl->arg1; 11989 ubp = (fc_unsol_buf_t *)cmpl->arg2; 11990 iocbq = (IOCBQ *)cmpl->arg3; 11991 11992 kmem_free(cmpl, sizeof (emlxs_deferred_cmpl_t)); 11993 11994 emlxs_mb_deferred_cmpl(port, mbxStatus, sbp, ubp, iocbq); 11995 11996 return; 11997 11998 } /* emlxs_deferred_cmpl_thread() */ 11999 12000 12001 12002 12003 /* ARGSUSED */ 12004 static void 12005 emlxs_port_offline_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 12006 { 12007 emlxs_port_t *port = (emlxs_port_t *)arg1; 12008 uint32_t scope = (uint32_t)((unsigned long)arg2); 12009 12010 (void) emlxs_port_offline(port, scope); 12011 return; 12012 12013 } /* emlxs_port_offline_thread() */ 12014 12015 12016 /* ARGSUSED */ 12017 static void 12018 emlxs_port_online_thread(emlxs_hba_t *hba, void *arg1, void *arg2) 12019 { 12020 emlxs_port_t *port = (emlxs_port_t *)arg1; 12021 12022 (void) emlxs_port_online(port); 12023 return; 12024 12025 } /* emlxs_port_online_thread() */ 12026 12027 12028 /*ARGSUSED*/ 12029 static void 12030 emlxs_vpi_logo_handler(emlxs_port_t *port, VPIobj_t *vpip) 12031 { 12032 vpip->flag &= ~EMLXS_VPI_LOGI; 12033 if (vpip->flag & EMLXS_VPI_VFI_LOGI) { 12034 vpip->flag &= ~EMLXS_VPI_VFI_LOGI; 12035 if (vpip->vfip == NULL) { 12036 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12037 "emlxs_vpi_logo_handler: invalid state " 12038 "(vpip->vfip == NULL), vpip=%p", vpip); 12039 return; 12040 } 12041 if (vpip->vfip->logi_count) { 12042 vpip->vfip->logi_count--; 12043 } 12044 if (vpip == vpip->vfip->flogi_vpip) { 12045 vpip->vfip->flogi_vpip = NULL; 12046 } 12047 } 12048 } /* emlxs_vpi_logo_handler() */ 12049 12050 12051 /*ARGSUSED*/ 12052 static uint32_t 12053 emlxs_vpi_port_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12054 void *arg1) 12055 { 12056 emlxs_hba_t *hba = HBA; 12057 uint32_t rval = 0; 12058 uint32_t scope; 12059 12060 if (vpip->state != VPI_STATE_PORT_OFFLINE) { 12061 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12062 "vpi_port_offline_action:%d %s:%s arg=%p. " 12063 "Invalid state. <", 12064 vpip->VPI, 12065 emlxs_vpi_state_xlate(vpip->state), 12066 emlxs_fcf_event_xlate(evt), arg1); 12067 return (1); 12068 } 12069 12070 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) { 12071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12072 "vpi_port_offline_action:%d flag=%x. Offlining port...", 12073 vpip->VPI, 12074 vpip->flag); 12075 12076 vpip->flag &= ~(EMLXS_VPI_PORT_ONLINE|EMLXS_VPI_PORT_ENABLED); 12077 12078 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 12079 scope = 0xFFFFFFFF; /* Clear all non-FCP2 nodes */ 12080 /* Pause FCP2 nodes */ 12081 } else { 12082 scope = 0xFDFFFFFF; /* Clear all nodes */ 12083 } 12084 12085 emlxs_thread_spawn(hba, emlxs_port_offline_thread, 12086 (void *)vpip->port, (void *)((unsigned long)scope)); 12087 12088 if (vpip->flag & EMLXS_VPI_LOGI) { 12089 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO, 12090 FCF_REASON_EVENT, evt, arg1); 12091 12092 return (rval); 12093 } 12094 } 12095 12096 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 12097 if (vpip->rpi_online > vpip->rpi_paused) { 12098 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12099 "vpi_port_offline_action:%d rpi_online=%d,%d. " 12100 "Pausing. Waiting for RPI's. <", 12101 vpip->VPI, 12102 vpip->rpi_online, vpip->rpi_paused); 12103 return (0); 12104 } 12105 12106 /* Take the Fabric RPI offline now */ 12107 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12108 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12109 "vpi_port_offline_action:%d. " 12110 "Offlining Fabric RPI. >", 12111 vpip->VPI); 12112 12113 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12114 vpip->fabric_rpip); 12115 } 12116 12117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12118 "vpi_port_offline_action:%d rpi_online=%d,%d. Pausing.", 12119 vpip->VPI, 12120 vpip->rpi_online, vpip->rpi_paused); 12121 12122 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED, 12123 FCF_REASON_EVENT, evt, arg1); 12124 12125 return (rval); 12126 } 12127 12128 if (vpip->rpi_online > 0) { 12129 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12130 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. " 12131 "Waiting for RPI's. <", 12132 vpip->VPI, 12133 vpip->rpi_online, vpip->rpi_paused); 12134 12135 return (0); 12136 } 12137 12138 /* Take the Fabric RPI offline now */ 12139 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12141 "vpi_port_offline_action:%d. Offlining Fabric RPI. >", 12142 vpip->VPI); 12143 12144 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12145 vpip->fabric_rpip); 12146 } 12147 12148 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12149 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. " 12150 "Unreg VPI.", 12151 vpip->VPI, 12152 vpip->rpi_online, vpip->rpi_paused); 12153 12154 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 12155 FCF_REASON_EVENT, evt, arg1); 12156 12157 return (rval); 12158 12159 } /* emlxs_vpi_port_offline_action() */ 12160 12161 12162 /*ARGSUSED*/ 12163 static uint32_t 12164 emlxs_vpi_paused_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12165 void *arg1) 12166 { 12167 if (vpip->state != VPI_STATE_PAUSED) { 12168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12169 "vpi_paused_action:%d %s:%s arg=%p. " 12170 "Invalid state. <", 12171 vpip->VPI, 12172 emlxs_vpi_state_xlate(vpip->state), 12173 emlxs_fcf_event_xlate(evt), arg1); 12174 return (1); 12175 } 12176 12177 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 12178 12179 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12180 "vpi_paused_action:%d rpi_online=%d,%d. VPI paused. <", 12181 vpip->VPI, 12182 vpip->rpi_online, vpip->rpi_paused); 12183 12184 return (0); 12185 12186 } /* emlxs_vpi_paused_action() */ 12187 12188 12189 /*ARGSUSED*/ 12190 static uint32_t 12191 emlxs_vpi_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12192 void *arg1) 12193 { 12194 uint32_t rval = 0; 12195 12196 if (vpip->state != VPI_STATE_OFFLINE) { 12197 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12198 "vpi_offline_action:%d %s:%s arg=%p. " 12199 "Invalid state. <", 12200 vpip->VPI, 12201 emlxs_vpi_state_xlate(vpip->state), 12202 emlxs_fcf_event_xlate(evt), arg1); 12203 return (1); 12204 } 12205 12206 if (!vpip->vfip) { 12207 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12208 "vpi_offline_action:%d %s:%s arg=%p flag=%x. " 12209 "Null vfip found. <", 12210 vpip->VPI, 12211 emlxs_vpi_state_xlate(vpip->state), 12212 emlxs_fcf_event_xlate(evt), arg1, 12213 vpip->flag); 12214 return (1); 12215 } 12216 12217 /* Take the Fabric RPI offline, if still active */ 12218 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12219 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12220 "vpi_offline_action:%d. Offlining Fabric RPI. >", 12221 vpip->VPI); 12222 12223 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12224 vpip->fabric_rpip); 12225 } 12226 12227 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 12228 12229 if (vpip->flag & EMLXS_VPI_VFI) { 12230 vpip->flag &= ~EMLXS_VPI_VFI; 12231 12232 if (vpip->vfip->vpi_online) { 12233 vpip->vfip->vpi_online--; 12234 } 12235 } 12236 12237 /* Check if online was requested */ 12238 if (vpip->flag & EMLXS_VPI_ONLINE_REQ) { 12239 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12240 "vpi_offline_action:%d vpi_online=%d. Online requested.", 12241 vpip->VPI, 12242 vpip->vfip->vpi_online); 12243 12244 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT, 12245 FCF_REASON_REQUESTED, 0, arg1); 12246 return (rval); 12247 } 12248 12249 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12250 "vpi_offline_action:%d vpi_online=%d. " 12251 "VPI offline. Notifying VFI:%d. >", 12252 vpip->VPI, 12253 vpip->vfip->vpi_online, 12254 vpip->vfip->VFI); 12255 12256 /* Notify VFI */ 12257 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 12258 12259 return (rval); 12260 12261 } /* emlxs_vpi_offline_action() */ 12262 12263 12264 /*ARGSUSED*/ 12265 static uint32_t 12266 emlxs_vpi_init_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 12267 { 12268 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 12269 VPIobj_t *vpip; 12270 MAILBOX4 *mb4; 12271 12272 vpip = (VPIobj_t *)mbq->context; 12273 mb4 = (MAILBOX4 *)mbq; 12274 12275 mutex_enter(&EMLXS_FCF_LOCK); 12276 12277 if (vpip->state != VPI_STATE_INIT) { 12278 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12279 "vpi_init_mbcmpl:%d %s.", 12280 vpip->VPI, 12281 emlxs_vpi_state_xlate(vpip->state)); 12282 12283 mutex_exit(&EMLXS_FCF_LOCK); 12284 return (0); 12285 } 12286 12287 if (mb4->mbxStatus) { 12288 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12289 "vpi_init_mbcmpl:%d failed. %s. >", 12290 vpip->VPI, 12291 emlxs_mb_xlate_status(mb4->mbxStatus)); 12292 12293 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED, 12294 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 12295 12296 mutex_exit(&EMLXS_FCF_LOCK); 12297 return (0); 12298 } 12299 12300 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12301 "vpi_init_mbcmpl:%d. Init complete. >", 12302 vpip->VPI, 12303 mb4->mbxStatus); 12304 12305 vpip->flag |= EMLXS_VPI_INIT; 12306 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL, 12307 0, 0, 0); 12308 12309 mutex_exit(&EMLXS_FCF_LOCK); 12310 return (0); 12311 12312 } /* emlxs_vpi_init_mbcmpl() */ 12313 12314 12315 /*ARGSUSED*/ 12316 static uint32_t 12317 emlxs_vpi_init_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12318 void *arg1) 12319 { 12320 emlxs_hba_t *hba = HBA; 12321 MAILBOXQ *mbq; 12322 MAILBOX4 *mb4; 12323 uint32_t rval = 0; 12324 12325 if (vpip->state != VPI_STATE_INIT) { 12326 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12327 "vpi_init_action:%d %s:%s arg=%p. " 12328 "Invalid state. <", 12329 vpip->VPI, 12330 emlxs_vpi_state_xlate(vpip->state), 12331 emlxs_fcf_event_xlate(evt), arg1); 12332 return (1); 12333 } 12334 12335 if (vpip->prev_state != VPI_STATE_INIT_FAILED) { 12336 vpip->attempts = 0; 12337 } 12338 12339 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12340 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12341 "vpi_init_action:%d attempts=%d. Offline requested.", 12342 vpip->VPI, 12343 vpip->attempts); 12344 12345 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12346 return (rval); 12347 } 12348 12349 if (!(vpip->flag & EMLXS_VPI_VFI)) { 12350 vpip->flag |= EMLXS_VPI_VFI; 12351 vpip->vfip->vpi_online++; 12352 } 12353 12354 if (((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) == 12355 SLI_INTF_IF_TYPE_0) && (vpip->vfip->vpi_online == 1)) { 12356 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12357 "vpi_init_action:%d. First VPI. Skipping INIT_VPI.", 12358 vpip->VPI); 12359 12360 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12361 FCF_REASON_EVENT, evt, arg1); 12362 return (rval); 12363 } 12364 12365 if (vpip->flag & EMLXS_VPI_INIT) { 12366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12367 "vpi_init_action:%d flag=%x. " 12368 "Already init'd. Skipping INIT_VPI.", 12369 vpip->VPI); 12370 12371 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12372 FCF_REASON_EVENT, evt, arg1); 12373 return (rval); 12374 } 12375 12376 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12377 "vpi_init_action:%d vpi_online=%d attempts=%d. Sending INIT_VPI. <", 12378 vpip->VPI, 12379 vpip->vfip->vpi_online, 12380 vpip->attempts); 12381 12382 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 12383 rval = emlxs_vpi_state(port, vpip, FCFI_STATE_REG_FAILED, 12384 FCF_REASON_NO_MBOX, 0, arg1); 12385 return (rval); 12386 } 12387 mb4 = (MAILBOX4*)mbq; 12388 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 12389 12390 mbq->nonembed = NULL; 12391 mbq->mbox_cmpl = emlxs_vpi_init_mbcmpl; 12392 mbq->context = (void *)vpip; 12393 mbq->port = (void *)port; 12394 12395 mb4->mbxCommand = MBX_INIT_VPI; 12396 mb4->mbxOwner = OWN_HOST; 12397 mb4->un.varInitVPI4.vfi = vpip->vfip->VFI; 12398 mb4->un.varInitVPI4.vpi = vpip->VPI; 12399 12400 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 12401 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 12402 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 12403 12404 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED, 12405 FCF_REASON_SEND_FAILED, rval, arg1); 12406 12407 return (rval); 12408 } 12409 12410 return (0); 12411 12412 } /* emlxs_vpi_init_action() */ 12413 12414 12415 /*ARGSUSED*/ 12416 static uint32_t 12417 emlxs_vpi_init_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12418 void *arg1) 12419 { 12420 uint32_t rval = 0; 12421 12422 vpip->attempts++; 12423 12424 if (vpip->state != VPI_STATE_INIT_FAILED) { 12425 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12426 "vpi_init_action:%d %s:%s arg=%p attempt=%d. " 12427 "Invalid state. <", 12428 vpip->VPI, 12429 emlxs_vpi_state_xlate(vpip->state), 12430 emlxs_fcf_event_xlate(evt), arg1, 12431 vpip->attempts); 12432 return (1); 12433 } 12434 12435 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 12436 (vpip->attempts >= 3)) { 12437 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12438 "vpi_init_action:%d attempt=%d reason=%x. Init cmpl.", 12439 vpip->VPI, 12440 vpip->attempts, 12441 vpip->reason); 12442 12443 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 12444 12445 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 12446 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 12447 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL, 12448 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 12449 } else { 12450 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12451 "vpi_init_action:%d attempt=%d. Initializing.", 12452 vpip->VPI, 12453 vpip->attempts); 12454 12455 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT, 12456 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 12457 } 12458 12459 return (rval); 12460 12461 } /* emlxs_vpi_init_failed_action() */ 12462 12463 12464 /*ARGSUSED*/ 12465 static uint32_t 12466 emlxs_vpi_init_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12467 void *arg1) 12468 { 12469 uint32_t rval = 0; 12470 12471 if (vpip->state != VPI_STATE_INIT_CMPL) { 12472 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12473 "vpi_init_cmpl_action:%d %s:%s arg=%p. " 12474 "Invalid state. <", 12475 vpip->VPI, 12476 emlxs_vpi_state_xlate(vpip->state), 12477 emlxs_fcf_event_xlate(evt), arg1); 12478 return (1); 12479 } 12480 12481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12482 "vpi_init_cmpl_action:%d attempts=%d. Onlining port.", 12483 vpip->VPI, 12484 vpip->attempts); 12485 12486 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12487 FCF_REASON_EVENT, evt, arg1); 12488 return (rval); 12489 12490 } /* emlxs_vpi_init_cmpl_action() */ 12491 12492 12493 /*ARGSUSED*/ 12494 static uint32_t 12495 emlxs_vpi_port_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12496 void *arg1) 12497 { 12498 emlxs_hba_t *hba = HBA; 12499 emlxs_config_t *cfg = &CFG; 12500 uint32_t rval = 0; 12501 12502 if (vpip->state != VPI_STATE_PORT_ONLINE) { 12503 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12504 "vpi_port_online_action:%d %s:%s arg=%p. " 12505 "Invalid state. <", 12506 vpip->VPI, 12507 emlxs_vpi_state_xlate(vpip->state), 12508 emlxs_fcf_event_xlate(evt), arg1); 12509 return (1); 12510 } 12511 12512 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) { 12513 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12514 "vpi_port_online_action:%d. Port already online.", 12515 vpip->VPI); 12516 } 12517 12518 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12519 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12520 "vpi_port_online_action:%d. Offline requested.", 12521 vpip->VPI); 12522 12523 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12524 return (rval); 12525 } 12526 12527 /* Initialize the Fabric RPI */ 12528 if (vpip->fabric_rpip->state == RPI_STATE_FREE) { 12529 emlxs_rpi_alloc_fabric_rpi(vpip->port); 12530 } 12531 12532 /* Notify ULP */ 12533 vpip->flag |= EMLXS_VPI_PORT_ONLINE; 12534 12535 if (hba->flag & FC_LOOPBACK_MODE) { 12536 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12537 "vpi_port_online_action:%d. Loopback mode. " 12538 "Registering VPI.", 12539 vpip->VPI); 12540 12541 if (hba->topology != TOPOLOGY_LOOP) { 12542 port->did = 1; 12543 } 12544 12545 vpip->vfip->flogi_vpip = vpip; 12546 12547 bcopy((void *)&vpip->port->sparam, 12548 (void *)&vpip->fabric_rpip->sparam, 12549 sizeof (SERV_PARM)); 12550 12551 /* Update the VPI Fabric RPI */ 12552 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov = 12553 LE_SWAP32((FF_DEF_RATOV * 1000)); 12554 12555 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 12556 FCF_REASON_EVENT, evt, arg1); 12557 12558 return (rval); 12559 } 12560 12561 if ((hba->topology == TOPOLOGY_LOOP) && ! (port->did)) { 12562 port->did = port->granted_alpa; 12563 } 12564 12565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12566 "vpi_port_online_action:%d vpi_online=%d. Onlining port... <", 12567 vpip->VPI, 12568 vpip->vfip->vpi_online); 12569 12570 if (SLI4_FC_MODE && (port->vpi == 0)) { 12571 mutex_enter(&EMLXS_PORT_LOCK); 12572 hba->linkup_timer = hba->timer_tics + 12573 cfg[CFG_LINKUP_TIMEOUT].current; 12574 mutex_exit(&EMLXS_PORT_LOCK); 12575 } else { 12576 emlxs_thread_spawn(hba, emlxs_port_online_thread, 12577 (void *)vpip->port, 0); 12578 } 12579 12580 /* Wait for emlxs_vpi_logi_notify() */ 12581 12582 return (0); 12583 12584 } /* emlxs_vpi_port_online_action() */ 12585 12586 12587 extern uint32_t 12588 emlxs_vpi_logi_notify(emlxs_port_t *port, emlxs_buf_t *sbp) 12589 { 12590 VPIobj_t *vpip = port->vpip; 12591 emlxs_hba_t *hba = HBA; 12592 uint32_t rval = 0; 12593 12594 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12595 return (1); 12596 } 12597 12598 mutex_enter(&EMLXS_FCF_LOCK); 12599 12600 if (vpip->state == VPI_STATE_OFFLINE) { 12601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12602 "vpi_logi_notify:%d %s.", 12603 vpip->VPI, 12604 emlxs_vpi_state_xlate(vpip->state)); 12605 12606 mutex_exit(&EMLXS_FCF_LOCK); 12607 12608 return (1); 12609 } 12610 12611 if (vpip->state != VPI_STATE_PORT_ONLINE) { 12612 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12613 "vpi_logi_notify:%d %s. " 12614 "Invalid state.", 12615 vpip->VPI, 12616 emlxs_vpi_state_xlate(vpip->state)); 12617 12618 mutex_exit(&EMLXS_FCF_LOCK); 12619 12620 return (1); 12621 } 12622 12623 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12624 "vpi_logi_notify:%d %s. " 12625 "Logging in. >", 12626 vpip->VPI, 12627 emlxs_vpi_state_xlate(vpip->state)); 12628 12629 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI, 12630 0, 0, sbp); 12631 12632 if (rval) { 12633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12634 "vpi_logi_notify:%d %s rval=%d.", 12635 vpip->VPI, 12636 emlxs_vpi_state_xlate(vpip->state), 12637 rval); 12638 } 12639 12640 mutex_exit(&EMLXS_FCF_LOCK); 12641 12642 return (rval); 12643 12644 } /* emlxs_vpi_logi_notify() */ 12645 12646 12647 static uint32_t 12648 emlxs_vpi_logi_cmpl_notify(emlxs_port_t *port, RPIobj_t *rpip) 12649 { 12650 emlxs_hba_t *hba = HBA; 12651 VPIobj_t *vpip = port->vpip; 12652 uint32_t rval = 0; 12653 12654 /* EMLXS_FCF_LOCK must be held when calling this routine */ 12655 12656 if (vpip->state != VPI_STATE_LOGI) { 12657 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12658 "vpi_logi_cmpl_notify:%d %s. " 12659 "Invalid state.", 12660 vpip->VPI, 12661 emlxs_vpi_state_xlate(vpip->state)); 12662 return (1); 12663 } 12664 12665 if (rpip->RPI == FABRIC_RPI) { 12666 if (hba->flag & FC_PT_TO_PT) { 12667 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12668 "vpi_logi_cmpl_notify:%d %s. P2P mode. " 12669 "Completing FLOGI.", 12670 vpip->VPI, 12671 emlxs_vpi_state_xlate(vpip->state)); 12672 12673 /* Complete the FLOGI/FDISC now */ 12674 if (rpip->cmpl) { 12675 emlxs_rpi_deferred_cmpl(port, rpip, 0); 12676 } 12677 12678 /* Wait for P2P PLOGI completion to continue */ 12679 return (0); 12680 } 12681 12682 if (!rpip->cmpl || !rpip->cmpl->arg1) { 12683 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12684 "vpi_logi_cmpl_notify:%d. Null sbp.", 12685 vpip->VPI); 12686 return (1); 12687 } 12688 12689 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12690 "vpi_logi_cmpl_notify:%d %s. Fabric mode. " 12691 "Completing login. >", 12692 vpip->VPI, 12693 emlxs_vpi_state_xlate(vpip->state)); 12694 12695 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL, 12696 0, 0, 0); 12697 12698 if (rval) { 12699 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12700 "vpi_logi_cmpl_notify:%d %s rval=%d.", 12701 vpip->VPI, 12702 emlxs_vpi_state_xlate(vpip->state), 12703 rval); 12704 } 12705 12706 return (rval); 12707 } 12708 12709 if (hba->flag & FC_PT_TO_PT) { 12710 if (port->did == 0) { 12711 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12712 "vpi_logi_cmpl_notify:%d %s did=0. P2P mode. " 12713 "Wait for PLOGI compl.", 12714 vpip->VPI, 12715 emlxs_vpi_state_xlate(vpip->state)); 12716 12717 if (rpip->cmpl) { 12718 emlxs_rpi_deferred_cmpl(port, rpip, 0); 12719 } 12720 12721 /* Wait for P2P PLOGI completion to continue */ 12722 return (0); 12723 } 12724 12725 vpip->p2p_rpip = rpip; 12726 12727 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12728 "vpi_logi_cmpl_notify:%d %s. P2P mode. " 12729 "Completing login. >", 12730 vpip->VPI, 12731 emlxs_vpi_state_xlate(vpip->state)); 12732 12733 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL, 12734 0, 0, 0); 12735 12736 if (rval) { 12737 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12738 "vpi_logi_cmpl_notify:%d %s rval=%d.", 12739 vpip->VPI, 12740 emlxs_vpi_state_xlate(vpip->state), 12741 rval); 12742 } 12743 12744 return (rval); 12745 } 12746 12747 return (1); 12748 12749 } /* emlxs_vpi_logi_cmpl_notify() */ 12750 12751 12752 extern uint32_t 12753 emlxs_vpi_logi_failed_notify(emlxs_port_t *port, emlxs_buf_t *sbp) 12754 { 12755 emlxs_hba_t *hba = HBA; 12756 VPIobj_t *vpip = port->vpip; 12757 RPIobj_t *rpip = vpip->fabric_rpip; 12758 uint32_t rval = 0; 12759 emlxs_deferred_cmpl_t *cmpl; 12760 12761 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12762 return (1); 12763 } 12764 12765 mutex_enter(&EMLXS_FCF_LOCK); 12766 12767 if (vpip->state != VPI_STATE_LOGI) { 12768 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12769 "vpi_logi_failed_notify:%d %s. " 12770 "Invalid state.", 12771 vpip->VPI, 12772 emlxs_vpi_state_xlate(vpip->state)); 12773 12774 /* Fabric logo is implied */ 12775 emlxs_vpi_logo_handler(port, vpip); 12776 12777 mutex_exit(&EMLXS_FCF_LOCK); 12778 12779 return (1); 12780 } 12781 12782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12783 "vpi_logi_failed_notify:%d %s. " 12784 "Failing login. >", 12785 vpip->VPI, 12786 emlxs_vpi_state_xlate(vpip->state)); 12787 12788 /* For safety */ 12789 if (rpip->cmpl) { 12790 emlxs_rpi_deferred_cmpl(port, rpip, 1); 12791 } 12792 12793 if (sbp) { 12794 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 12795 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 12796 12797 cmpl->port = port; 12798 cmpl->arg1 = (void *)sbp; 12799 cmpl->arg2 = 0; 12800 cmpl->arg3 = 0; 12801 12802 rpip->cmpl = cmpl; 12803 } 12804 12805 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_FAILED, 12806 FCF_REASON_OP_FAILED, 1, 0); 12807 12808 if (rval && rpip->cmpl) { 12809 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 12810 rpip->cmpl = 0; 12811 } 12812 12813 mutex_exit(&EMLXS_FCF_LOCK); 12814 return (rval); 12815 12816 } /* emlxs_vpi_logi_failed_notify() */ 12817 12818 12819 extern uint32_t 12820 emlxs_vpi_logo_cmpl_notify(emlxs_port_t *port) 12821 { 12822 emlxs_hba_t *hba = HBA; 12823 VPIobj_t *vpip = port->vpip; 12824 uint32_t rval = 0; 12825 VFIobj_t *vfip; 12826 FCFIobj_t *fcfp; 12827 12828 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12829 return (1); 12830 } 12831 12832 mutex_enter(&EMLXS_FCF_LOCK); 12833 12834 /* Fabric logo is complete */ 12835 emlxs_vpi_logo_handler(port, vpip); 12836 12837 if ((vpip->state == VPI_STATE_OFFLINE) || 12838 (vpip->flag & EMLXS_VPI_OFFLINE_REQ)) { 12839 /* Already offline. Do nothing */ 12840 mutex_exit(&EMLXS_FCF_LOCK); 12841 return (0); 12842 } 12843 12844 vfip = vpip->vfip; 12845 fcfp = vfip->fcfp; 12846 12847 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12848 "vpi_logo_cmpl_notify:%d %s fcfi:%d vfi:%d. " 12849 "Offlining VPI:%d,%d >", 12850 vpip->VPI, 12851 emlxs_vpi_state_xlate(vpip->state), 12852 fcfp->fcf_index, 12853 vfip->VFI, 12854 vpip->index, vpip->VPI); 12855 12856 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 12857 12858 mutex_exit(&EMLXS_FCF_LOCK); 12859 12860 return (rval); 12861 12862 } /* emlxs_vpi_logo_cmpl_notify() */ 12863 12864 12865 /*ARGSUSED*/ 12866 static uint32_t 12867 emlxs_vpi_logi_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12868 void *arg1) 12869 { 12870 emlxs_hba_t *hba = HBA; 12871 emlxs_buf_t *sbp = (emlxs_buf_t *)arg1; 12872 fc_packet_t *pkt = PRIV2PKT(sbp); 12873 uint32_t rval = 0; 12874 12875 if (vpip->state != VPI_STATE_LOGI) { 12876 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12877 "vpi_logi_action:%d %s:%s arg=%p. " 12878 "Invalid state. <", 12879 vpip->VPI, 12880 emlxs_vpi_state_xlate(vpip->state), 12881 emlxs_fcf_event_xlate(evt), arg1); 12882 return (1); 12883 } 12884 12885 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12887 "vpi_logi_action:%d. Offline requested.", 12888 vpip->VPI); 12889 12890 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12891 return (rval); 12892 } 12893 12894 if (vpip->flag & EMLXS_VPI_LOGI) { 12895 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12896 "vpi_logi_action:%d flag=%x. LOGI already set.", 12897 vpip->VPI, vpip->flag); 12898 12899 /* Fabric logo is implied */ 12900 emlxs_vpi_logo_handler(port, vpip); 12901 } 12902 12903 /* Check if FC_PT_TO_PT is set */ 12904 if (hba->flag & FC_PT_TO_PT) { 12905 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12906 "vpi_logi_action:%d logi_count=%d. FLOGI set. P2P. <", 12907 vpip->VPI, 12908 vpip->vfip->logi_count); 12909 12910 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI; 12911 12912 vpip->vfip->flogi_vpip = vpip; 12913 12914 if (vpip->vfip->logi_count == 0) { 12915 vpip->vfip->logi_count++; 12916 vpip->flag |= EMLXS_VPI_VFI_LOGI; 12917 } 12918 12919 return (0); 12920 } 12921 12922 /* Set login command based on vfi logi_count */ 12923 if (vpip->vfip->logi_count == 0) { 12924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12925 "vpi_logi_action:%d logi_count=%d. FLOGI set. <", 12926 vpip->VPI, 12927 vpip->vfip->logi_count); 12928 12929 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI; 12930 12931 vpip->vfip->flogi_vpip = vpip; 12932 } else { 12933 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12934 "vpi_logi_action:%d logi_count=%d. FDISC set. <", 12935 vpip->VPI, 12936 vpip->vfip->logi_count); 12937 12938 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FDISC; 12939 } 12940 12941 vpip->vfip->logi_count++; 12942 vpip->flag |= EMLXS_VPI_VFI_LOGI; 12943 12944 return (0); 12945 12946 } /* emlxs_vpi_logi_action() */ 12947 12948 12949 /*ARGSUSED*/ 12950 static uint32_t 12951 emlxs_vpi_logi_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12952 void *arg1) 12953 { 12954 emlxs_hba_t *hba = HBA; 12955 uint32_t rval = 0; 12956 12957 if (vpip->state != VPI_STATE_LOGI_FAILED) { 12958 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12959 "vpi_logi_failed_action:%d %s:%s arg=%p. " 12960 "Invalid state. <", 12961 vpip->VPI, 12962 emlxs_vpi_state_xlate(vpip->state), 12963 emlxs_fcf_event_xlate(evt), arg1); 12964 return (1); 12965 } 12966 12967 /* Fabric logo is implied */ 12968 emlxs_vpi_logo_handler(port, vpip); 12969 12970 if (hba->topology == TOPOLOGY_LOOP) { 12971 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12972 "vpi_logi_failed_action:%d. Private loop. " 12973 "Registering VPI.", 12974 vpip->VPI); 12975 12976 /* Update the VPI flogi_vpip pointer for loop */ 12977 /* because the vpi_logo_handler cleared it */ 12978 vpip->vfip->flogi_vpip = vpip; 12979 12980 bcopy((void *)&vpip->port->sparam, 12981 (void *)&vpip->fabric_rpip->sparam, 12982 sizeof (SERV_PARM)); 12983 12984 /* Update the VPI Fabric RPI */ 12985 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov = 12986 LE_SWAP32((FF_DEF_RATOV * 1000)); 12987 12988 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 12989 FCF_REASON_EVENT, evt, arg1); 12990 return (rval); 12991 } 12992 12993 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12994 "vpi_logi_failed_action:%d. Requesting offline.", 12995 vpip->VPI); 12996 12997 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 12998 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 12999 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13000 13001 return (rval); 13002 13003 } /* emlxs_vpi_logi_failed_action() */ 13004 13005 13006 /*ARGSUSED*/ 13007 static uint32_t 13008 emlxs_vpi_logi_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13009 void *arg1) 13010 { 13011 emlxs_hba_t *hba = HBA; 13012 uint32_t rval = 0; 13013 char buffer1[64]; 13014 char buffer2[64]; 13015 uint32_t new_config = 0; 13016 13017 if (vpip->state != VPI_STATE_LOGI_CMPL) { 13018 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13019 "vpi_logi_cmpl_action:%d %s:%s arg=%p. " 13020 "Invalid state. <", 13021 vpip->VPI, 13022 emlxs_vpi_state_xlate(vpip->state), 13023 emlxs_fcf_event_xlate(evt), arg1); 13024 return (1); 13025 } 13026 13027 vpip->flag |= EMLXS_VPI_LOGI; 13028 13029 /* Check for new fabric */ 13030 if (port->prev_did) { 13031 if (SLI4_FCOE_MODE) { 13032 /* Check for FCF change */ 13033 if (((port->prev_did != port->did) || 13034 bcmp(&port->prev_fabric_sparam.portName, 13035 &port->fabric_sparam.portName, 8)) && 13036 emlxs_nport_count(port)) { 13037 new_config = 1; 13038 } 13039 } else { 13040 uint32_t old_topo; 13041 uint32_t new_topo; 13042 13043 /* Check for topology change (0=loop 1=fabric) */ 13044 old_topo = ((port->prev_did && 0xFFFF00) == 0)? 0:1; 13045 new_topo = ((port->did && 0xFFFF00) == 0)? 0:1; 13046 13047 if (old_topo != new_topo) { 13048 new_config = 1; 13049 13050 /* Check for any switch change */ 13051 } else if ((port->prev_did != port->did) || 13052 bcmp(&port->prev_fabric_sparam.portName, 13053 &port->fabric_sparam.portName, 8)) { 13054 new_config = 1; 13055 } 13056 } 13057 } 13058 13059 if (new_config) { 13060 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13061 "vpi_logi_cmpl_action:%d. " 13062 "New config. Offlining port.", 13063 vpip->VPI); 13064 13065 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13066 "vpi_logi_cmpl_action: prev_wwpn=%s wwpn=%s prev_did=%x " 13067 "did=%x.", 13068 emlxs_wwn_xlate(buffer1, sizeof (buffer1), 13069 (uint8_t *)&port->prev_fabric_sparam.portName), 13070 emlxs_wwn_xlate(buffer2, sizeof (buffer2), 13071 (uint8_t *)&port->fabric_sparam.portName), 13072 port->prev_did, port->did); 13073 13074 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13075 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13076 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13077 13078 return (rval); 13079 } 13080 13081 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13082 "vpi_logi_cmpl_action:%d. Registering.", 13083 vpip->VPI); 13084 13085 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 13086 FCF_REASON_EVENT, evt, arg1); 13087 13088 return (rval); 13089 13090 } /* emlxs_vpi_logi_cmpl_action() */ 13091 13092 13093 /*ARGSUSED*/ 13094 static uint32_t 13095 emlxs_vpi_logo_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13096 void *arg1) 13097 { 13098 emlxs_hba_t *hba = HBA; 13099 uint32_t rval = 0; 13100 13101 vpip->attempts++; 13102 13103 if (vpip->state != VPI_STATE_LOGO_FAILED) { 13104 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13105 "vpi_logo_failed_action:%d %s:%s arg=%p attempt=%d. " 13106 "Invalid state. <", 13107 vpip->VPI, 13108 emlxs_vpi_state_xlate(vpip->state), 13109 emlxs_fcf_event_xlate(evt), arg1, 13110 vpip->attempts); 13111 return (1); 13112 } 13113 13114 if (hba->state <= FC_LINK_DOWN) { 13115 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13116 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.", 13117 vpip->VPI, 13118 vpip->attempts); 13119 13120 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13121 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13122 } else if (vpip->attempts >= 3) { 13123 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13124 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.", 13125 vpip->VPI, 13126 vpip->attempts); 13127 13128 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13129 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13130 } else { 13131 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13132 "vpi_logo_failed_action:%d attempt=%d. Logging out.", 13133 vpip->VPI, 13134 vpip->attempts); 13135 13136 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO, 13137 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13138 } 13139 13140 return (rval); 13141 13142 } /* emlxs_vpi_logo_failed_action() */ 13143 13144 13145 /*ARGSUSED*/ 13146 static uint32_t 13147 emlxs_vpi_logo_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13148 void *arg1) 13149 { 13150 emlxs_hba_t *hba = HBA; 13151 emlxs_port_t *vport = vpip->port; 13152 uint32_t rval = 0; 13153 uint32_t did; 13154 uint32_t sid; 13155 fc_packet_t *pkt; 13156 ELS_PKT *els; 13157 13158 if (vpip->state != VPI_STATE_LOGO) { 13159 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13160 "vpi_logo_action:%d %s:%s arg=%p. " 13161 "Invalid state. <", 13162 vpip->VPI, 13163 emlxs_vpi_state_xlate(vpip->state), 13164 emlxs_fcf_event_xlate(evt), arg1); 13165 return (1); 13166 } 13167 13168 if (!(vpip->flag & EMLXS_VPI_LOGI)) { 13169 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13170 "vpi_logo_action:%d. No login. Skipping LOGO.", 13171 vpip->VPI); 13172 13173 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13174 FCF_REASON_EVENT, evt, arg1); 13175 return (rval); 13176 } 13177 13178 if (!(hba->flag & FC_ONLINE_MODE) && 13179 !(hba->flag & FC_OFFLINING_MODE)) { 13180 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13181 "vpi_logo_action:%d. HBA offline. Skipping LOGO.", 13182 vpip->VPI); 13183 13184 /* Fabric logo is implied */ 13185 emlxs_vpi_logo_handler(port, vpip); 13186 13187 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13188 FCF_REASON_EVENT, evt, arg1); 13189 return (rval); 13190 } 13191 13192 if (SLI4_FC_MODE) { 13193 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13194 "vpi_logo_action:%d. FC mode. Skipping LOGO.", 13195 vpip->VPI); 13196 13197 /* Fabric logo is implied */ 13198 emlxs_vpi_logo_handler(port, vpip); 13199 13200 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13201 FCF_REASON_EVENT, evt, arg1); 13202 return (rval); 13203 } 13204 13205 if (vpip->prev_state != VPI_STATE_LOGO_FAILED) { 13206 vpip->attempts = 0; 13207 } 13208 13209 did = FABRIC_DID; 13210 sid = (vport->did)? vport->did:vport->prev_did; 13211 13212 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13213 "vpi_logo_action:%d attempts=%d sid=%x did=%x. Sending LOGO. <", 13214 vpip->VPI, 13215 vpip->attempts, 13216 sid, did); 13217 13218 pkt = emlxs_pkt_alloc(vport, 13219 (sizeof (uint32_t) + sizeof (LOGO)), 13220 (sizeof (uint32_t) + sizeof (LOGO)), 0, KM_NOSLEEP); 13221 13222 if (!pkt) { 13223 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED, 13224 FCF_REASON_NO_PKT, 0, arg1); 13225 13226 return (rval); 13227 } 13228 13229 pkt->pkt_tran_type = FC_PKT_EXCHANGE; 13230 pkt->pkt_timeout = (2 * hba->fc_ratov); 13231 13232 /* Build the fc header */ 13233 pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 13234 pkt->pkt_cmd_fhdr.r_ctl = 13235 R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 13236 pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(sid); 13237 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 13238 pkt->pkt_cmd_fhdr.f_ctl = 13239 F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 13240 pkt->pkt_cmd_fhdr.seq_id = 0; 13241 pkt->pkt_cmd_fhdr.df_ctl = 0; 13242 pkt->pkt_cmd_fhdr.seq_cnt = 0; 13243 pkt->pkt_cmd_fhdr.ox_id = 0xffff; 13244 pkt->pkt_cmd_fhdr.rx_id = 0xffff; 13245 pkt->pkt_cmd_fhdr.ro = 0; 13246 13247 /* Build the command */ 13248 els = (ELS_PKT *)pkt->pkt_cmd; 13249 els->elsCode = 0x05; 13250 els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id; 13251 bcopy((uint8_t *)&vport->wwpn, 13252 (uint8_t *)&els->un.logo.portName, 8); 13253 13254 /* Send the pkt now */ 13255 rval = emlxs_pkt_send(pkt, 0); 13256 if (rval != FC_SUCCESS) { 13257 /* Free the pkt */ 13258 emlxs_pkt_free(pkt); 13259 13260 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED, 13261 FCF_REASON_SEND_FAILED, rval, arg1); 13262 13263 return (rval); 13264 } 13265 13266 /* For now we will send and forget */ 13267 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13268 FCF_REASON_EVENT, evt, arg1); 13269 13270 return (rval); 13271 13272 } /* emlxs_vpi_logo_action() */ 13273 13274 13275 /*ARGSUSED*/ 13276 static uint32_t 13277 emlxs_vpi_logo_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13278 void *arg1) 13279 { 13280 uint32_t rval = 0; 13281 13282 if (vpip->state != VPI_STATE_LOGO_CMPL) { 13283 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13284 "vpi_logo_cmpl_action:%d %s:%s arg=%p. " 13285 "Invalid state. <", 13286 vpip->VPI, 13287 emlxs_vpi_state_xlate(vpip->state), 13288 emlxs_fcf_event_xlate(evt), arg1); 13289 return (1); 13290 } 13291 13292 /* Fabric logo is complete */ 13293 emlxs_vpi_logo_handler(port, vpip); 13294 13295 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13296 "vpi_logo_cmpl_action:%d attempts=%d. Offline RPI's.", 13297 vpip->VPI, 13298 vpip->attempts); 13299 13300 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13301 FCF_REASON_EVENT, evt, arg1); 13302 13303 return (rval); 13304 13305 } /* emlxs_vpi_logo_cmpl_action() */ 13306 13307 13308 /*ARGSUSED*/ 13309 static uint32_t 13310 emlxs_vpi_unreg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13311 void *arg1) 13312 { 13313 uint32_t rval = 0; 13314 13315 vpip->attempts++; 13316 13317 if (vpip->state != VPI_STATE_UNREG_FAILED) { 13318 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13319 "vpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 13320 "Invalid state. <", 13321 vpip->VPI, 13322 emlxs_vpi_state_xlate(vpip->state), 13323 emlxs_fcf_event_xlate(evt), arg1, 13324 vpip->attempts); 13325 return (1); 13326 } 13327 13328 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 13329 (vpip->attempts >= 3)) { 13330 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13331 "vpi_unreg_failed_action:%d attempt=%d. Unreg cmpl.", 13332 vpip->VPI, 13333 vpip->attempts); 13334 13335 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 13336 13337 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13338 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13339 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL, 13340 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13341 } else { 13342 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13343 "vpi_unreg_failed_action:%d attempt=%d. Unregistering.", 13344 vpip->VPI, 13345 vpip->attempts); 13346 13347 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 13348 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13349 } 13350 13351 return (rval); 13352 13353 } /* emlxs_vpi_unreg_failed_action() */ 13354 13355 13356 /*ARGSUSED*/ 13357 static uint32_t 13358 emlxs_vpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 13359 { 13360 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 13361 MAILBOX4 *mb4; 13362 VPIobj_t *vpip; 13363 13364 vpip = (VPIobj_t *)mbq->context; 13365 mb4 = (MAILBOX4 *)mbq; 13366 13367 mutex_enter(&EMLXS_FCF_LOCK); 13368 13369 if (vpip->state != VPI_STATE_UNREG) { 13370 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13371 "vpi_unreg_mbcmpl:%d state=%s.", 13372 vpip->VPI, 13373 emlxs_vpi_state_xlate(vpip->state)); 13374 13375 mutex_exit(&EMLXS_FCF_LOCK); 13376 return (0); 13377 } 13378 13379 if (mb4->mbxStatus) { 13380 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13381 "vpi_unreg_mbcmpl:%d failed. %s. >", 13382 vpip->VPI, 13383 emlxs_mb_xlate_status(mb4->mbxStatus)); 13384 13385 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13386 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 13387 13388 mutex_exit(&EMLXS_FCF_LOCK); 13389 return (0); 13390 } 13391 13392 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13393 "vpi_unreg_mbcmpl:%d. Unreg complete. >", 13394 vpip->VPI); 13395 13396 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 13397 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL, 0, 0, 0); 13398 13399 mutex_exit(&EMLXS_FCF_LOCK); 13400 return (0); 13401 13402 } /* emlxs_vpi_unreg_mbcmpl() */ 13403 13404 13405 /*ARGSUSED*/ 13406 static uint32_t 13407 emlxs_vpi_unreg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13408 void *arg1) 13409 { 13410 emlxs_hba_t *hba = HBA; 13411 MAILBOX4 *mb4; 13412 MAILBOXQ *mbq; 13413 uint32_t rval = 0; 13414 13415 if (vpip->state != VPI_STATE_UNREG) { 13416 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13417 "vpi_unreg_action:%d %s:%s arg=%p. " 13418 "Invalid state. <", 13419 vpip->VPI, 13420 emlxs_vpi_state_xlate(vpip->state), 13421 emlxs_fcf_event_xlate(evt), arg1); 13422 return (1); 13423 } 13424 13425 if ((vpip->rpi_online > vpip->rpi_paused) || 13426 (vpip->fabric_rpip->state != RPI_STATE_FREE)) { 13427 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13428 "vpi_unreg_action:%d rpi_online=%d,%d fstate=%x. " 13429 "Waiting for RPI's.", vpip->VPI, vpip->rpi_online, 13430 vpip->rpi_paused, vpip->fabric_rpip->state); 13431 13432 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13433 FCF_REASON_EVENT, evt, arg1); 13434 return (rval); 13435 } 13436 13437 if (!(vpip->flag & EMLXS_VPI_REG)) { 13438 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13439 "vpi_unreg_action:%d. Not registered. Skipping UNREG_VPI.", 13440 vpip->VPI); 13441 13442 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE, 13443 FCF_REASON_EVENT, evt, arg1); 13444 return (rval); 13445 } 13446 13447 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 13448 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13449 "vpi_unreg_action:%d rpi_online=%d,%d. Pausing.", 13450 vpip->VPI, 13451 vpip->rpi_online, vpip->rpi_paused); 13452 13453 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED, 13454 FCF_REASON_EVENT, evt, arg1); 13455 return (rval); 13456 } 13457 13458 if (vpip->prev_state != VPI_STATE_UNREG_FAILED) { 13459 vpip->attempts = 0; 13460 } 13461 13462 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13463 "vpi_unreg_action:%d attempts=%d. Sending UNREG_VPI. <", 13464 vpip->VPI, 13465 vpip->attempts); 13466 13467 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 13468 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13469 FCF_REASON_NO_MBOX, 0, arg1); 13470 13471 return (rval); 13472 } 13473 mb4 = (MAILBOX4*)mbq; 13474 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 13475 13476 mbq->nonembed = NULL; 13477 mbq->mbox_cmpl = emlxs_vpi_unreg_mbcmpl; 13478 mbq->context = (void *)vpip; 13479 mbq->port = (void *)vpip->port; 13480 13481 mb4->un.varUnRegVPI4.ii = 0; /* index is a VPI */ 13482 mb4->un.varUnRegVPI4.index = vpip->VPI; 13483 mb4->mbxCommand = MBX_UNREG_VPI; 13484 mb4->mbxOwner = OWN_HOST; 13485 13486 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 13487 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 13488 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 13489 13490 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13491 FCF_REASON_SEND_FAILED, rval, arg1); 13492 13493 return (rval); 13494 } 13495 13496 return (0); 13497 13498 } /* emlxs_vpi_unreg_action() */ 13499 13500 13501 /*ARGSUSED*/ 13502 static uint32_t 13503 emlxs_vpi_unreg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13504 void *arg1) 13505 { 13506 uint32_t rval = 0; 13507 13508 if (vpip->state != VPI_STATE_UNREG_CMPL) { 13509 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13510 "vpi_unreg_cmpl_action:%d %s:%s arg=%p. " 13511 "Invalid state. <", 13512 vpip->VPI, 13513 emlxs_vpi_state_xlate(vpip->state), 13514 emlxs_fcf_event_xlate(evt), arg1); 13515 return (1); 13516 } 13517 13518 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13519 "vpi_unreg_cmpl_action:%d attempts=%d. Going offline.", 13520 vpip->VPI, 13521 vpip->attempts); 13522 13523 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE, 13524 FCF_REASON_EVENT, evt, arg1); 13525 13526 return (rval); 13527 13528 } /* emlxs_vpi_unreg_cmpl_action() */ 13529 13530 13531 /*ARGSUSED*/ 13532 static uint32_t 13533 emlxs_vpi_reg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13534 void *arg1) 13535 { 13536 uint32_t rval = 0; 13537 13538 vpip->attempts++; 13539 13540 if (vpip->state != VPI_STATE_REG_FAILED) { 13541 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13542 "vpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 13543 "Invalid state. <", 13544 vpip->VPI, 13545 emlxs_vpi_state_xlate(vpip->state), 13546 emlxs_fcf_event_xlate(evt), arg1, 13547 vpip->attempts); 13548 return (1); 13549 } 13550 13551 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 13552 (vpip->attempts >= 3)) { 13553 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13554 "vpi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.", 13555 vpip->VPI, 13556 vpip->attempts, 13557 vpip->reason); 13558 13559 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13560 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13561 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL, 13562 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13563 } else { 13564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13565 "vpi_reg_failed_action:%d attempt=%d. Registering.", 13566 vpip->VPI, 13567 vpip->attempts); 13568 13569 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 13570 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13571 } 13572 13573 return (rval); 13574 13575 } /* emlxs_vpi_reg_failed_action() */ 13576 13577 13578 /*ARGSUSED*/ 13579 static uint32_t 13580 emlxs_vpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 13581 { 13582 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 13583 MAILBOX4 *mb4; 13584 VPIobj_t *vpip; 13585 13586 vpip = (VPIobj_t *)mbq->context; 13587 mb4 = (MAILBOX4 *)mbq; 13588 13589 mutex_enter(&EMLXS_FCF_LOCK); 13590 13591 if (vpip->state != VPI_STATE_REG) { 13592 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13593 "vpi_reg_mbcmpl:%d state=%s.", 13594 vpip->VPI, 13595 emlxs_vpi_state_xlate(vpip->state)); 13596 13597 mutex_exit(&EMLXS_FCF_LOCK); 13598 return (0); 13599 } 13600 13601 if (mb4->mbxStatus) { 13602 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13603 "vpi_reg_mbcmpl:%d failed. %s. >", 13604 vpip->VPI, 13605 emlxs_mb_xlate_status(mb4->mbxStatus)); 13606 13607 if (mb4->mbxStatus == MBXERR_DID_INCONSISTENT) { 13608 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13609 } 13610 13611 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13612 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 13613 13614 mutex_exit(&EMLXS_FCF_LOCK); 13615 return (0); 13616 } 13617 13618 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13619 "vpi_reg_mbcmpl:%d. Reg complete. >", 13620 vpip->VPI); 13621 13622 vpip->flag |= EMLXS_VPI_REG; 13623 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL, 13624 0, 0, 0); 13625 13626 mutex_exit(&EMLXS_FCF_LOCK); 13627 return (0); 13628 13629 } /* emlxs_vpi_reg_mbcmpl() */ 13630 13631 13632 /*ARGSUSED*/ 13633 static uint32_t 13634 emlxs_vpi_reg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13635 void *arg1) 13636 { 13637 emlxs_hba_t *hba = HBA; 13638 uint32_t *wwpn; 13639 MAILBOX *mb; 13640 MAILBOXQ *mbq; 13641 uint32_t rval = 0; 13642 13643 if (vpip->state != VPI_STATE_REG) { 13644 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13645 "vpi_reg_action:%d %s:%s arg=%p. " 13646 "Invalid state. <", 13647 vpip->VPI, 13648 emlxs_vpi_state_xlate(vpip->state), 13649 emlxs_fcf_event_xlate(evt), arg1); 13650 return (1); 13651 } 13652 13653 if (vpip->prev_state != VPI_STATE_REG_FAILED) { 13654 vpip->attempts = 0; 13655 } 13656 13657 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13658 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13659 "vpi_reg_action:%d attempts=%d. Offline requested.", 13660 vpip->VPI, 13661 vpip->attempts); 13662 13663 rval = emlxs_vpi_offline_handler(port, vpip, 0); 13664 return (rval); 13665 } 13666 13667 if (!(vpip->vfip->flag & EMLXS_VFI_REG)) { 13668 /* We can't register the VPI until our VFI is registered */ 13669 13670 /* If this is the flogi_vpip, then we can skip the REG_VPI. */ 13671 /* REG_VPI will be performed later during REG_VFI */ 13672 if (vpip == vpip->vfip->flogi_vpip) { 13673 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13674 "vpi_reg_action:%d. flogi_vpi. Skipping REG_VPI.", 13675 vpip->VPI); 13676 13677 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE, 13678 FCF_REASON_EVENT, evt, arg1); 13679 13680 return (rval); 13681 } 13682 13683 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13684 "vpi_reg_action:%d attempts=%d. VFI not registered. " 13685 "Offlining.", 13686 vpip->VPI, 13687 vpip->attempts); 13688 13689 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13690 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13691 rval = emlxs_vpi_offline_handler(port, vpip, 0); 13692 return (rval); 13693 } 13694 13695 if (vpip->flag & EMLXS_VPI_REG) { 13696 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13697 "vpi_reg_action:%d attempts=%d. Updating REG_VPI. <", 13698 vpip->VPI, 13699 vpip->attempts); 13700 } else { 13701 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13702 "vpi_reg_action:%d attempts=%d. Sending REG_VPI. <", 13703 vpip->VPI, 13704 vpip->attempts); 13705 } 13706 13707 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 13708 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13709 FCF_REASON_NO_MBOX, 0, arg1); 13710 13711 return (rval); 13712 } 13713 mb = (MAILBOX*)mbq; 13714 bzero((void *) mb, MAILBOX_CMD_BSIZE); 13715 13716 mbq->nonembed = NULL; 13717 mbq->mbox_cmpl = emlxs_vpi_reg_mbcmpl; 13718 mbq->context = (void *)vpip; 13719 mbq->port = (void *)vpip->port; 13720 13721 mb->un.varRegVpi.vfi = vpip->vfip->VFI; 13722 mb->un.varRegVpi.upd = (vpip->flag & EMLXS_VPI_REG)? 1:0; 13723 13724 wwpn = (uint32_t *)&port->wwpn; 13725 mb->un.varRegVpi.portname[0] = BE_SWAP32(*wwpn); 13726 wwpn++; 13727 mb->un.varRegVpi.portname[1] = BE_SWAP32(*wwpn); 13728 13729 mb->un.varRegVpi.vpi = vpip->VPI; 13730 mb->un.varRegVpi.sid = vpip->port->did; 13731 mb->mbxCommand = MBX_REG_VPI; 13732 mb->mbxOwner = OWN_HOST; 13733 13734 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 13735 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 13736 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 13737 13738 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13739 FCF_REASON_SEND_FAILED, rval, arg1); 13740 13741 return (rval); 13742 } 13743 13744 return (0); 13745 13746 } /* emlxs_vpi_reg_action() */ 13747 13748 13749 /*ARGSUSED*/ 13750 static uint32_t 13751 emlxs_vpi_reg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13752 void *arg1) 13753 { 13754 uint32_t rval = 0; 13755 13756 if (vpip->state != VPI_STATE_REG_CMPL) { 13757 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13758 "vpi_reg_cmpl_action:%d %s:%s arg=%p. " 13759 "Invalid state. <", 13760 vpip->VPI, 13761 emlxs_vpi_state_xlate(vpip->state), 13762 emlxs_fcf_event_xlate(evt), arg1); 13763 return (1); 13764 } 13765 13766 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13767 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13768 "vpi_reg_cmpl_action:%d attempts=%d. Offline requested.", 13769 vpip->VPI, 13770 vpip->attempts); 13771 13772 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13773 return (rval); 13774 } 13775 13776 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13777 "vpi_reg_cmpl_action:%d attempts=%d. Going online.", 13778 vpip->VPI, 13779 vpip->attempts); 13780 13781 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE, 13782 FCF_REASON_EVENT, evt, arg1); 13783 13784 return (rval); 13785 13786 } /* emlxs_vpi_reg_cmpl_action() */ 13787 13788 13789 /*ARGSUSED*/ 13790 static uint32_t 13791 emlxs_vpi_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13792 void *arg1) 13793 { 13794 uint32_t rval = 0; 13795 13796 if (vpip->state != VPI_STATE_ONLINE) { 13797 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13798 "vpi_online_action:%d %s:%s arg=%p. " 13799 "Invalid state. <", 13800 vpip->VPI, 13801 emlxs_vpi_state_xlate(vpip->state), 13802 emlxs_fcf_event_xlate(evt), arg1); 13803 return (1); 13804 } 13805 13806 vpip->flag &= ~EMLXS_VPI_ONLINE_REQ; 13807 13808 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13809 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13810 "vpi_online_action:%d attempts=%d. Offline requested.", 13811 vpip->VPI, 13812 vpip->attempts); 13813 13814 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13815 return (rval); 13816 } 13817 13818 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13819 "vpi_online_action:%d. VPI online. Notifying VFI:%d >", 13820 vpip->VPI, 13821 vpip->vfip->VFI); 13822 13823 /* Notify VFI */ 13824 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_ONLINE, vpip); 13825 13826 return (rval); 13827 13828 } /* emlxs_vpi_online_action() */ 13829 13830 13831 /* ************************************************************************** */ 13832 /* RPI */ 13833 /* ************************************************************************** */ 13834 13835 static char * 13836 emlxs_rpi_state_xlate(uint32_t state) 13837 { 13838 static char buffer[32]; 13839 uint32_t i; 13840 uint32_t count; 13841 13842 count = sizeof (emlxs_rpi_state_table) / sizeof (emlxs_table_t); 13843 for (i = 0; i < count; i++) { 13844 if (state == emlxs_rpi_state_table[i].code) { 13845 return (emlxs_rpi_state_table[i].string); 13846 } 13847 } 13848 13849 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 13850 return (buffer); 13851 13852 } /* emlxs_rpi_state_xlate() */ 13853 13854 13855 static uint32_t 13856 emlxs_rpi_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 13857 void *arg1) 13858 { 13859 uint32_t rval = 0; 13860 uint32_t(*func) (emlxs_port_t *, RPIobj_t *, uint32_t, void *); 13861 uint32_t index; 13862 uint32_t events; 13863 uint16_t state; 13864 13865 /* Convert event to action table index */ 13866 switch (evt) { 13867 case FCF_EVENT_STATE_ENTER: 13868 index = 0; 13869 break; 13870 case FCF_EVENT_RPI_ONLINE: 13871 index = 1; 13872 break; 13873 case FCF_EVENT_RPI_OFFLINE: 13874 index = 2; 13875 break; 13876 case FCF_EVENT_RPI_PAUSE: 13877 index = 3; 13878 break; 13879 case FCF_EVENT_RPI_RESUME: 13880 index = 4; 13881 break; 13882 default: 13883 return (1); 13884 } 13885 13886 events = RPI_ACTION_EVENTS; 13887 state = rpip->state; 13888 13889 index += (state * events); 13890 func = (uint32_t(*) (emlxs_port_t *, RPIobj_t *, uint32_t, void *)) 13891 emlxs_rpi_action_table[index]; 13892 13893 if (!func) { 13894 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13895 "rpi_action:%d %s:%s arg=%p. No action. <", 13896 rpip->RPI, 13897 emlxs_rpi_state_xlate(rpip->state), 13898 emlxs_fcf_event_xlate(evt), arg1); 13899 13900 return (1); 13901 } 13902 13903 rval = (func)(port, rpip, evt, arg1); 13904 13905 return (rval); 13906 13907 } /* emlxs_rpi_action() */ 13908 13909 13910 static uint32_t 13911 emlxs_rpi_event(emlxs_port_t *port, uint32_t evt, 13912 void *arg1) 13913 { 13914 RPIobj_t *rpip = NULL; 13915 uint32_t rval = 0; 13916 13917 /* Filter events and acquire fcfi context */ 13918 switch (evt) { 13919 case FCF_EVENT_RPI_ONLINE: 13920 case FCF_EVENT_RPI_OFFLINE: 13921 case FCF_EVENT_RPI_PAUSE: 13922 case FCF_EVENT_RPI_RESUME: 13923 rpip = (RPIobj_t *)arg1; 13924 13925 if (!rpip) { 13926 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13927 "rpi_event: %s arg=%p. Null RPI found. <", 13928 emlxs_fcf_event_xlate(evt), arg1); 13929 13930 return (1); 13931 } 13932 13933 break; 13934 13935 default: 13936 return (1); 13937 } 13938 13939 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13940 "rpi_event:%d %s:%s arg=%p", 13941 rpip->RPI, 13942 emlxs_rpi_state_xlate(rpip->state), 13943 emlxs_fcf_event_xlate(evt), arg1); 13944 13945 rval = emlxs_rpi_action(port, rpip, evt, arg1); 13946 13947 return (rval); 13948 13949 } /* emlxs_rpi_event() */ 13950 13951 13952 /*ARGSUSED*/ 13953 static uint32_t 13954 emlxs_rpi_state(emlxs_port_t *port, RPIobj_t *rpip, uint16_t state, 13955 uint16_t reason, uint32_t explain, void *arg1) 13956 { 13957 uint32_t rval = 0; 13958 13959 if (state >= RPI_ACTION_STATES) { 13960 return (1); 13961 } 13962 13963 if ((rpip->state == state) && 13964 (reason != FCF_REASON_REENTER)) { 13965 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13966 "rpi_state:%d %s:%s:0x%x arg=%p. State not changed. <", 13967 rpip->RPI, 13968 emlxs_rpi_state_xlate(rpip->state), 13969 emlxs_fcf_reason_xlate(reason), 13970 explain, arg1); 13971 return (1); 13972 } 13973 13974 if (!reason) { 13975 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13976 "rpi_state:%d %s-->%s arg=%p", 13977 rpip->RPI, 13978 emlxs_rpi_state_xlate(rpip->state), 13979 emlxs_rpi_state_xlate(state), arg1); 13980 } else if (reason == FCF_REASON_EVENT) { 13981 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13982 "rpi_state:%d %s-->%s:%s:%s arg=%p", 13983 rpip->RPI, 13984 emlxs_rpi_state_xlate(rpip->state), 13985 emlxs_rpi_state_xlate(state), 13986 emlxs_fcf_reason_xlate(reason), 13987 emlxs_fcf_event_xlate(explain), arg1); 13988 } else if (explain) { 13989 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13990 "rpi_state:%d %s-->%s:%s:0x%x arg=%p", 13991 rpip->RPI, 13992 emlxs_rpi_state_xlate(rpip->state), 13993 emlxs_rpi_state_xlate(state), 13994 emlxs_fcf_reason_xlate(reason), 13995 explain, arg1); 13996 } else { 13997 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13998 "rpi_state:%d %s-->%s:%s arg=%p", 13999 rpip->RPI, 14000 emlxs_rpi_state_xlate(rpip->state), 14001 emlxs_rpi_state_xlate(state), 14002 emlxs_fcf_reason_xlate(reason), arg1); 14003 } 14004 14005 rpip->prev_state = rpip->state; 14006 rpip->prev_reason = rpip->reason; 14007 rpip->state = state; 14008 rpip->reason = reason; 14009 14010 rval = emlxs_rpi_action(port, rpip, FCF_EVENT_STATE_ENTER, arg1); 14011 14012 return (rval); 14013 14014 } /* emlxs_rpi_state() */ 14015 14016 14017 static void 14018 emlxs_rpi_deferred_cmpl(emlxs_port_t *port, RPIobj_t *rpip, uint32_t status) 14019 { 14020 emlxs_hba_t *hba = HBA; 14021 emlxs_deferred_cmpl_t *cmpl; 14022 14023 if (!rpip->cmpl) { 14024 return; 14025 } 14026 14027 cmpl = rpip->cmpl; 14028 rpip->cmpl = 0; 14029 14030 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14031 "rpi_deferred_cmpl:%d. status=%x ...", 14032 port->vpip->VPI, 14033 status); 14034 14035 emlxs_thread_spawn(hba, emlxs_deferred_cmpl_thread, (void *)cmpl, 14036 (void*)(uintptr_t)status); 14037 14038 return; 14039 14040 } /* emlxs_rpi_deferred_cmpl() */ 14041 14042 14043 static void 14044 emlxs_rpi_idle_timer(emlxs_hba_t *hba) 14045 { 14046 emlxs_config_t *cfg = &CFG; 14047 RPIobj_t *rpip; 14048 uint32_t i; 14049 14050 /* This timer monitors for idle timeout of an RPI in a */ 14051 /* RESERVED state. */ 14052 /* This means that the RPI was reserved, but never registered. */ 14053 /* If the RPI sits for too long (~2 secs) in this state we free it */ 14054 rpip = hba->sli.sli4.RPIp; 14055 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14056 if (rpip->state != RPI_STATE_RESERVED) { 14057 continue; 14058 } 14059 14060 /* If RPI is active, then clear timer. */ 14061 if (rpip->xri_count) { 14062 rpip->idle_timer = 0; 14063 continue; 14064 } 14065 14066 /* If an F-port RPI is found idle, then free it. */ 14067 /* Since an F-port RPI is never registered after the login */ 14068 /* completes, it is safe to free it immediately. */ 14069 if ((rpip->did == FABRIC_DID) || 14070 (rpip->did == SCR_DID)) { 14071 goto free_it; 14072 } 14073 14074 /* Start idle timer if not already active */ 14075 if (!rpip->idle_timer) { 14076 rpip->idle_timer = hba->timer_tics + 14077 cfg[CFG_FCF_RPI_IDLE_TIMEOUT].current; 14078 } 14079 14080 /* Check for idle timeout */ 14081 if (hba->timer_tics < rpip->idle_timer) { 14082 continue; 14083 } 14084 rpip->idle_timer = 0; 14085 14086 free_it: 14087 (void) emlxs_rpi_state(rpip->vpip->port, rpip, RPI_STATE_FREE, 14088 FCF_REASON_UNUSED, 0, 0); 14089 } 14090 14091 return; 14092 14093 } /* emlxs_rpi_idle_timer() */ 14094 14095 14096 static RPIobj_t * 14097 emlxs_rpi_alloc(emlxs_port_t *port, uint32_t did) 14098 { 14099 emlxs_hba_t *hba = HBA; 14100 uint16_t i; 14101 RPIobj_t *rpip; 14102 14103 rpip = hba->sli.sli4.RPIp; 14104 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14105 /* To be consistent with SLI3, the RPI assignment */ 14106 /* starts with 1. ONLY one SLI4 HBA in the entire */ 14107 /* system will be sacrificed by one RPI and that */ 14108 /* is the one having RPI base equal 0. */ 14109 if ((rpip->state == RPI_STATE_FREE) && (rpip->RPI != 0)) { 14110 14111 bzero(rpip, sizeof (RPIobj_t)); 14112 rpip->index = i; 14113 rpip->RPI = emlxs_sli4_index_to_rpi(hba, i); 14114 rpip->vpip = port->vpip; 14115 rpip->did = did; 14116 14117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14118 "rpi_alloc:%d. RPI allocated. >", 14119 rpip->RPI); 14120 14121 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESERVED, 14122 0, 0, 0); 14123 14124 return (rpip); 14125 } 14126 } 14127 14128 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14129 "rpi_alloc: Out of RPI objects."); 14130 14131 return (NULL); 14132 14133 } /* emlxs_rpi_alloc() */ 14134 14135 14136 /* Special routine for VPI object */ 14137 static void 14138 emlxs_rpi_alloc_fabric_rpi(emlxs_port_t *port) 14139 { 14140 RPIobj_t *fabric_rpip; 14141 14142 fabric_rpip = port->vpip->fabric_rpip; 14143 14144 if (fabric_rpip->state != RPI_STATE_FREE) { 14145 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14146 "rpi_alloc_fabric_rpi: Fabric RPI active:%s.", 14147 emlxs_rpi_state_xlate(fabric_rpip->state)); 14148 return; 14149 } 14150 14151 bzero(fabric_rpip, sizeof (RPIobj_t)); 14152 fabric_rpip->index = 0xffff; 14153 fabric_rpip->RPI = FABRIC_RPI; 14154 fabric_rpip->did = FABRIC_DID; 14155 fabric_rpip->vpip = port->vpip; 14156 14157 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14158 "rpi_alloc_fabric_rpi: Allocating Fabric RPI. >"); 14159 14160 (void) emlxs_rpi_state(port, fabric_rpip, RPI_STATE_RESERVED, 14161 0, 0, 0); 14162 14163 return; 14164 14165 } /* emlxs_rpi_alloc_fabric_rpi() */ 14166 14167 14168 static uint32_t 14169 emlxs_rpi_free(emlxs_port_t *port, RPIobj_t *rpip) 14170 { 14171 uint32_t rval = 0; 14172 14173 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14174 "rpi_free:%d did=%x. Freeing RPI. >", 14175 rpip->RPI, rpip->did); 14176 14177 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 14178 14179 return (rval); 14180 14181 } /* emlxs_rpi_free() */ 14182 14183 14184 extern RPIobj_t * 14185 emlxs_rpi_find(emlxs_port_t *port, uint16_t rpi) 14186 { 14187 emlxs_hba_t *hba = HBA; 14188 RPIobj_t *rpip; 14189 uint32_t index; 14190 14191 /* Special handling for Fabric RPI */ 14192 if (rpi == FABRIC_RPI) { 14193 return (port->vpip->fabric_rpip); 14194 } 14195 14196 index = emlxs_sli4_rpi_to_index(hba, rpi); 14197 14198 if (index >= hba->sli.sli4.RPICount) { 14199 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14200 "rpi_find:%d. RPI Invalid.", 14201 rpi); 14202 14203 return (NULL); 14204 } 14205 14206 rpip = &hba->sli.sli4.RPIp[index]; 14207 14208 if (rpip->state == RPI_STATE_FREE) { 14209 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14210 "rpi_find:%d RPI not active", 14211 rpi); 14212 14213 return (NULL); 14214 } 14215 14216 return (rpip); 14217 14218 } /* emlxs_rpi_find() */ 14219 14220 14221 static RPIobj_t * 14222 emlxs_rpi_find_did(emlxs_port_t *port, uint32_t did) 14223 { 14224 emlxs_hba_t *hba = HBA; 14225 RPIobj_t *rpip; 14226 RPIobj_t *rpip1; 14227 uint32_t i; 14228 14229 rpip1 = NULL; 14230 rpip = hba->sli.sli4.RPIp; 14231 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14232 if (rpip->state == RPI_STATE_FREE) { 14233 continue; 14234 } 14235 14236 if ((rpip->did == did) && (rpip->vpip == port->vpip)) { 14237 rpip1 = rpip; 14238 break; 14239 } 14240 } 14241 14242 return (rpip1); 14243 14244 } /* emlxs_rpi_find_did() */ 14245 14246 14247 extern RPIobj_t * 14248 emlxs_rpi_reserve_notify(emlxs_port_t *port, uint32_t did, XRIobj_t *xrip) 14249 { 14250 emlxs_hba_t *hba = HBA; 14251 RPIobj_t *rpip; 14252 14253 /* xrip will be NULL for unsolicited BLS requests */ 14254 14255 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14256 return (NULL); 14257 } 14258 14259 mutex_enter(&EMLXS_FCF_LOCK); 14260 14261 rpip = emlxs_rpi_find_did(port, did); 14262 14263 if (!rpip) { 14264 rpip = emlxs_rpi_alloc(port, did); 14265 } 14266 14267 if (!rpip) { 14268 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14269 "rpi_reserve_notify: Unable to reserve an rpi. " 14270 "did=%x xri=%d.", 14271 did, ((xrip)?xrip->XRI:0)); 14272 14273 mutex_exit(&EMLXS_FCF_LOCK); 14274 return (NULL); 14275 } 14276 14277 /* Bind the XRI */ 14278 if (xrip) { 14279 mutex_enter(&EMLXS_FCTAB_LOCK); 14280 xrip->reserved_rpip = rpip; 14281 rpip->xri_count++; 14282 mutex_exit(&EMLXS_FCTAB_LOCK); 14283 } 14284 14285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14286 "rpi_reserve_notify:%d did=%x xri=%d.", 14287 rpip->RPI, rpip->did, ((xrip)?xrip->XRI:0)); 14288 14289 mutex_exit(&EMLXS_FCF_LOCK); 14290 14291 return (rpip); 14292 14293 } /* emlxs_rpi_reserve_notify() */ 14294 14295 14296 extern RPIobj_t * 14297 emlxs_rpi_alloc_notify(emlxs_port_t *port, uint32_t did) 14298 { 14299 emlxs_hba_t *hba = HBA; 14300 RPIobj_t *rpip; 14301 14302 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14303 return (NULL); 14304 } 14305 14306 mutex_enter(&EMLXS_FCF_LOCK); 14307 14308 rpip = emlxs_rpi_alloc(port, did); 14309 14310 mutex_exit(&EMLXS_FCF_LOCK); 14311 14312 return (rpip); 14313 14314 } /* emlxs_rpi_alloc_notify() */ 14315 14316 14317 extern uint32_t 14318 emlxs_rpi_free_notify(emlxs_port_t *port, RPIobj_t *rpip) 14319 { 14320 emlxs_hba_t *hba = HBA; 14321 uint32_t rval = 0; 14322 14323 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14324 return (1); 14325 } 14326 14327 if (!rpip) { 14328 return (1); 14329 } 14330 14331 /* Fabric RPI will be handled automatically */ 14332 if (rpip->RPI == FABRIC_RPI) { 14333 return (1); 14334 } 14335 14336 mutex_enter(&EMLXS_FCF_LOCK); 14337 14338 rval = emlxs_rpi_free(port, rpip); 14339 14340 mutex_exit(&EMLXS_FCF_LOCK); 14341 14342 return (rval); 14343 14344 } /* emlxs_rpi_free_notify() */ 14345 14346 14347 extern uint32_t 14348 emlxs_rpi_pause_notify(emlxs_port_t *port, RPIobj_t *rpip) 14349 { 14350 emlxs_hba_t *hba = HBA; 14351 14352 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14353 return (1); 14354 } 14355 14356 if (!rpip) { 14357 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14358 "rpi_pause_notify: No RPI provided."); 14359 return (1); 14360 } 14361 14362 /* Fabric RPI will be handled automatically */ 14363 if (rpip->RPI == FABRIC_RPI) { 14364 return (1); 14365 } 14366 14367 mutex_enter(&EMLXS_FCF_LOCK); 14368 14369 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14370 "rpi_pause_notify:%d %s. Pausing RPI. >", 14371 rpip->RPI, 14372 emlxs_rpi_state_xlate(rpip->state)); 14373 14374 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_PAUSE, rpip); 14375 14376 mutex_exit(&EMLXS_FCF_LOCK); 14377 14378 return (0); 14379 14380 } /* emlxs_rpi_pause_notify() */ 14381 14382 14383 extern uint32_t 14384 emlxs_rpi_online_notify(emlxs_port_t *port, RPIobj_t *rpip, uint32_t did, 14385 SERV_PARM *sparam, void *arg1, void *arg2, void *arg3) 14386 { 14387 emlxs_hba_t *hba = HBA; 14388 emlxs_deferred_cmpl_t *cmpl; 14389 uint32_t allocated = 0; 14390 uint32_t rval = 0; 14391 14392 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14393 return (1); 14394 } 14395 14396 if ((did == port->did) && (!(hba->flag & FC_LOOPBACK_MODE))) { 14397 /* We never register our local port */ 14398 return (1); 14399 } 14400 14401 mutex_enter(&EMLXS_FCF_LOCK); 14402 14403 if (!rpip && (did == FABRIC_DID)) { 14404 /* We never online the Fabric DID other */ 14405 /* than the fabric_rpip */ 14406 rpip = port->vpip->fabric_rpip; 14407 } 14408 14409 if (!rpip) { 14410 rpip = emlxs_rpi_find_did(port, did); 14411 } 14412 14413 if (!rpip) { 14414 rpip = emlxs_rpi_alloc(port, did); 14415 allocated = 1; 14416 } 14417 14418 if (!rpip) { 14419 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14420 "rpi_online_notify: Unable to allocate an rpi. did=%x", 14421 did); 14422 14423 mutex_exit(&EMLXS_FCF_LOCK); 14424 return (1); 14425 } 14426 14427 /* Initialize RPI node info */ 14428 bcopy((void *)sparam, (void *)&rpip->sparam, sizeof (SERV_PARM)); 14429 14430 if (arg1 || arg2 || arg3) { 14431 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14432 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14433 14434 cmpl->port = port; 14435 cmpl->arg1 = arg1; 14436 cmpl->arg2 = arg2; 14437 cmpl->arg3 = arg3; 14438 14439 /* For safety */ 14440 if (rpip->cmpl) { 14441 emlxs_rpi_deferred_cmpl(port, rpip, 1); 14442 } 14443 14444 rpip->cmpl = cmpl; 14445 } 14446 14447 if ((rpip->RPI == FABRIC_RPI) || 14448 (hba->flag & FC_PT_TO_PT)) { 14449 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14450 "rpi_online_notify:%d %s. %s. Login cmpl.", 14451 rpip->RPI, 14452 emlxs_rpi_state_xlate(rpip->state), 14453 ((allocated)? "Allocated":"Updated")); 14454 14455 rval = emlxs_vpi_logi_cmpl_notify(port, rpip); 14456 14457 if (rval && rpip->cmpl) { 14458 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14459 rpip->cmpl = 0; 14460 } 14461 14462 mutex_exit(&EMLXS_FCF_LOCK); 14463 return (rval); 14464 } 14465 14466 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14467 "rpi_online_notify:%d %s. %s. Onlining RPI. >", 14468 rpip->RPI, 14469 emlxs_rpi_state_xlate(rpip->state), 14470 ((allocated)? "Allocated":"Updated")); 14471 14472 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_ONLINE, rpip); 14473 14474 if (rpip->cmpl) { 14475 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14476 "rpi_online_notify:%d %s. Deferred args not completed.", 14477 rpip->RPI, 14478 emlxs_rpi_state_xlate(rpip->state)); 14479 14480 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14481 rpip->cmpl = 0; 14482 14483 mutex_exit(&EMLXS_FCF_LOCK); 14484 return (1); 14485 } 14486 14487 mutex_exit(&EMLXS_FCF_LOCK); 14488 return (0); 14489 14490 } /* emlxs_rpi_online_notify() */ 14491 14492 14493 extern uint32_t 14494 emlxs_rpi_offline_notify(emlxs_port_t *port, RPIobj_t *rpip, 14495 void *arg1, void *arg2, void *arg3) 14496 { 14497 emlxs_hba_t *hba = HBA; 14498 emlxs_deferred_cmpl_t *cmpl; 14499 14500 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14501 return (1); 14502 } 14503 14504 if (!rpip) { 14505 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14506 "rpi_offline_notify: No RPI provided."); 14507 return (1); 14508 } 14509 14510 /* Fabric RPI will be handled automatically */ 14511 if (rpip->RPI == FABRIC_RPI) { 14512 return (1); 14513 } 14514 14515 mutex_enter(&EMLXS_FCF_LOCK); 14516 14517 if (arg1 || arg2 || arg3) { 14518 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14519 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14520 14521 cmpl->port = port; 14522 cmpl->arg1 = arg1; 14523 cmpl->arg2 = arg2; 14524 cmpl->arg3 = arg3; 14525 14526 rpip->cmpl = cmpl; 14527 } 14528 14529 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14530 "rpi_offline_notify:%d %s. Offlining RPI. >", 14531 rpip->RPI, 14532 emlxs_rpi_state_xlate(rpip->state)); 14533 14534 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip); 14535 14536 if (rpip->cmpl) { 14537 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14538 "rpi_offline_notify:%d %s. Deferred args not completed.", 14539 rpip->RPI, 14540 emlxs_rpi_state_xlate(rpip->state)); 14541 14542 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14543 rpip->cmpl = 0; 14544 14545 mutex_exit(&EMLXS_FCF_LOCK); 14546 return (1); 14547 } 14548 14549 mutex_exit(&EMLXS_FCF_LOCK); 14550 14551 return (0); 14552 14553 } /* emlxs_rpi_offline_notify() */ 14554 14555 14556 extern uint32_t 14557 emlxs_rpi_resume_notify(emlxs_port_t *port, RPIobj_t *rpip, emlxs_buf_t *sbp) 14558 { 14559 emlxs_hba_t *hba = HBA; 14560 emlxs_deferred_cmpl_t *cmpl; 14561 14562 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14563 return (1); 14564 } 14565 14566 if (!rpip) { 14567 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14568 "rpi_resume_notify: No RPI provided."); 14569 return (1); 14570 } 14571 14572 /* Fabric RPI will be handled automatically */ 14573 if (rpip->RPI == FABRIC_RPI) { 14574 return (1); 14575 } 14576 14577 mutex_enter(&EMLXS_FCF_LOCK); 14578 14579 if (rpip->state != RPI_STATE_PAUSED) { 14580 mutex_exit(&EMLXS_FCF_LOCK); 14581 return (1); 14582 } 14583 14584 if (sbp) { 14585 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14586 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14587 14588 cmpl->port = port; 14589 cmpl->arg1 = (void *)sbp; 14590 cmpl->arg2 = 0; 14591 cmpl->arg3 = 0; 14592 14593 rpip->cmpl = cmpl; 14594 } 14595 14596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14597 "rpi_resume_notify:%d %s. Resuming RPI. >", 14598 rpip->RPI, 14599 emlxs_rpi_state_xlate(rpip->state)); 14600 14601 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_RESUME, rpip); 14602 14603 if (rpip->cmpl) { 14604 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14605 "rpi_resume_notify:%d %s. Deferred args not completed.", 14606 rpip->RPI, 14607 emlxs_rpi_state_xlate(rpip->state)); 14608 14609 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14610 rpip->cmpl = 0; 14611 14612 mutex_exit(&EMLXS_FCF_LOCK); 14613 return (1); 14614 } 14615 14616 mutex_exit(&EMLXS_FCF_LOCK); 14617 14618 return (0); 14619 14620 } /* emlxs_rpi_resume_notify() */ 14621 14622 14623 /*ARGSUSED*/ 14624 static uint32_t 14625 emlxs_rpi_free_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14626 void *arg1) 14627 { 14628 emlxs_hba_t *hba = HBA; 14629 XRIobj_t *xrip; 14630 XRIobj_t *next_xrip; 14631 14632 if (rpip->state != RPI_STATE_FREE) { 14633 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14634 "rpi_free_action:%d %s:%s arg=%p. " 14635 "Invalid state. <", 14636 rpip->RPI, 14637 emlxs_rpi_state_xlate(rpip->state), 14638 emlxs_fcf_event_xlate(evt), arg1); 14639 return (1); 14640 } 14641 14642 if (rpip->cmpl) { 14643 emlxs_rpi_deferred_cmpl(port, rpip, 1); 14644 } 14645 14646 if (rpip->vpip->p2p_rpip == rpip) { 14647 rpip->vpip->p2p_rpip = NULL; 14648 } 14649 14650 /* Break node/RPI binding */ 14651 rw_enter(&port->node_rwlock, RW_WRITER); 14652 if (rpip->node) { 14653 rpip->node->rpip = NULL; 14654 rpip->node = NULL; 14655 } 14656 rw_exit(&port->node_rwlock); 14657 14658 /* Remove all XRIs under this RPI */ 14659 mutex_enter(&EMLXS_FCTAB_LOCK); 14660 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 14661 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 14662 next_xrip = xrip->_f; 14663 if (xrip->rpip == rpip) { 14664 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14665 "rpi_free_action:%d xri_count=%d. " 14666 "Removing XRI:%d iotag:%d.", 14667 rpip->RPI, 14668 rpip->xri_count, 14669 xrip->XRI, xrip->iotag); 14670 14671 rpip->xri_count--; 14672 xrip->rpip = NULL; 14673 } 14674 14675 if (xrip->reserved_rpip == rpip) { 14676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14677 "rpi_free_action:%d xri_count=%d. " 14678 "Removing XRI:%d iotag:%d.", 14679 rpip->RPI, 14680 rpip->xri_count, 14681 xrip->XRI, xrip->iotag); 14682 14683 rpip->xri_count--; 14684 xrip->reserved_rpip = NULL; 14685 } 14686 14687 xrip = next_xrip; 14688 } 14689 mutex_exit(&EMLXS_FCTAB_LOCK); 14690 14691 if (rpip->xri_count) { 14692 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14693 "rpi_free_action:%d. xri_count=%d", 14694 rpip->RPI, 14695 rpip->xri_count); 14696 } 14697 14698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14699 "rpi_free_action:%d flag=%x. RPI freed. <", 14700 rpip->RPI, 14701 rpip->flag); 14702 14703 rpip->flag = 0; 14704 14705 return (0); 14706 14707 } /* emlxs_rpi_free_action() */ 14708 14709 14710 /*ARGSUSED*/ 14711 static uint32_t 14712 emlxs_rpi_online_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14713 void *arg1) 14714 { 14715 uint32_t rval = 1; 14716 14717 if (evt != FCF_EVENT_RPI_ONLINE) { 14718 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14719 "rpi_online_evt_action:%d %s:%s arg=%p. " 14720 "Invalid event type. <", 14721 rpip->RPI, 14722 emlxs_rpi_state_xlate(rpip->state), 14723 emlxs_fcf_event_xlate(evt), arg1); 14724 return (1); 14725 } 14726 14727 switch (rpip->state) { 14728 case RPI_STATE_REG: 14729 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14730 "rpi_online_evt_action:%d flag=%x. Registering.", 14731 rpip->RPI, 14732 rpip->flag); 14733 14734 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG, 14735 FCF_REASON_REENTER, evt, arg1); 14736 break; 14737 14738 default: 14739 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14740 "rpi_online_evt_action:%d flag=%x. Registering.", 14741 rpip->RPI, 14742 rpip->flag); 14743 14744 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG, 14745 FCF_REASON_EVENT, evt, arg1); 14746 break; 14747 } 14748 14749 return (rval); 14750 14751 } /* emlxs_rpi_online_evt_action() */ 14752 14753 14754 /*ARGSUSED*/ 14755 static uint32_t 14756 emlxs_rpi_offline_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14757 void *arg1) 14758 { 14759 uint32_t rval = 1; 14760 14761 if (evt != FCF_EVENT_RPI_OFFLINE) { 14762 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14763 "rpi_offline_evt_action:%d %s:%s arg=%p. " 14764 "Invalid event type. <", 14765 rpip->RPI, 14766 emlxs_rpi_state_xlate(rpip->state), 14767 emlxs_fcf_event_xlate(evt), arg1); 14768 return (1); 14769 } 14770 14771 switch (rpip->state) { 14772 case RPI_STATE_RESERVED: 14773 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14774 "rpi_offline_evt_action:%d flag=%x. Freeing RPI.", 14775 rpip->RPI, 14776 rpip->flag); 14777 14778 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 14779 FCF_REASON_EVENT, evt, arg1); 14780 break; 14781 14782 case RPI_STATE_UNREG: 14783 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14784 "rpi_offline_evt_action:%d flag=%x. " 14785 "Already unregistering. <", 14786 rpip->RPI, 14787 rpip->flag); 14788 14789 break; 14790 14791 default: 14792 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14793 "rpi_offline_evt_action:%d flag=%x. Unregistering.", 14794 rpip->RPI, 14795 rpip->flag); 14796 14797 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 14798 FCF_REASON_EVENT, evt, arg1); 14799 break; 14800 14801 } 14802 14803 return (rval); 14804 14805 } /* emlxs_rpi_offline_evt_action() */ 14806 14807 14808 /*ARGSUSED*/ 14809 static uint32_t 14810 emlxs_rpi_pause_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14811 void *arg1) 14812 { 14813 VPIobj_t *vpip; 14814 uint32_t rval = 1; 14815 14816 vpip = rpip->vpip; 14817 14818 if (evt != FCF_EVENT_RPI_PAUSE) { 14819 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14820 "rpi_pause_evt_action:%d %s:%s arg=%p flag=%x. " 14821 "Invalid event type. <", 14822 rpip->RPI, 14823 emlxs_rpi_state_xlate(rpip->state), 14824 emlxs_fcf_event_xlate(evt), arg1, 14825 rpip->flag); 14826 return (1); 14827 } 14828 14829 switch (rpip->state) { 14830 case RPI_STATE_RESERVED: 14831 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14832 "rpi_pause_evt_action:%d flag=%x. Freeing RPI.", 14833 rpip->RPI, 14834 rpip->flag); 14835 14836 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 14837 FCF_REASON_EVENT, evt, arg1); 14838 break; 14839 14840 case RPI_STATE_UNREG: 14841 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14842 "rpi_pause_evt_action:%d flag=%x. Not online. <", 14843 rpip->RPI, 14844 rpip->flag); 14845 14846 break; 14847 14848 case RPI_STATE_PAUSED: 14849 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14850 "rpi_pause_evt_action:%d flag=%x. Already paused. <", 14851 rpip->RPI, 14852 rpip->flag); 14853 14854 break; 14855 14856 case RPI_STATE_REG: 14857 case RPI_STATE_ONLINE: 14858 case RPI_STATE_RESUME: 14859 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14860 "rpi_pause_evt_action:%d flag=%x. Pausing.", 14861 rpip->RPI, 14862 rpip->flag); 14863 14864 /* Don't pause an RPI, if the VPI is not pausing too */ 14865 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) { 14866 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14867 "rpi_pause_evt_action:%d rpi_online=%d,%d " 14868 "xri_count=%d. VPI:%d pause not requested. " 14869 "Unregistering.", rpip->RPI, 14870 vpip->rpi_online, vpip->rpi_paused, 14871 rpip->xri_count, vpip->VPI); 14872 14873 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 14874 FCF_REASON_EVENT, evt, arg1); 14875 break; 14876 } 14877 14878 rval = emlxs_rpi_state(port, rpip, RPI_STATE_PAUSED, 14879 FCF_REASON_EVENT, evt, arg1); 14880 break; 14881 14882 default: 14883 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14884 "rpi_pause_evt_action:%d flag=%x. <", 14885 rpip->RPI, 14886 rpip->flag); 14887 break; 14888 } 14889 14890 return (rval); 14891 14892 } /* emlxs_rpi_pause_evt_action() */ 14893 14894 14895 /*ARGSUSED*/ 14896 static uint32_t 14897 emlxs_rpi_resume_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14898 void *arg1) 14899 { 14900 uint32_t rval = 1; 14901 14902 if (evt != FCF_EVENT_RPI_RESUME) { 14903 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14904 "rpi_resume_evt_action:%d %s:%s arg=%p flag=%x. " 14905 "Invalid event type. <", 14906 rpip->RPI, 14907 emlxs_rpi_state_xlate(rpip->state), 14908 emlxs_fcf_event_xlate(evt), arg1, 14909 rpip->flag); 14910 return (1); 14911 } 14912 14913 switch (rpip->state) { 14914 case RPI_STATE_PAUSED: 14915 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14916 "rpi_resume_evt_action:%d flag=%x. Resuming.", 14917 rpip->RPI, 14918 rpip->flag); 14919 14920 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME, 14921 FCF_REASON_EVENT, evt, arg1); 14922 break; 14923 14924 default: 14925 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14926 "rpi_resume_evt_action:%d flag=%x. Not paused. <", 14927 rpip->RPI, 14928 rpip->flag); 14929 break; 14930 } 14931 14932 return (rval); 14933 14934 } /* emlxs_rpi_resume_evt_action() */ 14935 14936 14937 /*ARGSUSED*/ 14938 static uint32_t 14939 emlxs_rpi_reserved_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14940 void *arg1) 14941 { 14942 VPIobj_t *vpip; 14943 14944 vpip = rpip->vpip; 14945 14946 if (rpip->state != RPI_STATE_RESERVED) { 14947 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14948 "rpi_reserved_action:%d %s:%s arg=%p. " 14949 "Invalid state. <", 14950 rpip->RPI, 14951 emlxs_rpi_state_xlate(rpip->state), 14952 emlxs_fcf_event_xlate(evt), arg1); 14953 return (1); 14954 } 14955 14956 if (rpip->prev_state != RPI_STATE_FREE) { 14957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14958 "rpi_reserved_action:%d %s:%s arg=%p. " 14959 "Invalid previous state. %s <", 14960 rpip->RPI, 14961 emlxs_rpi_state_xlate(rpip->state), 14962 emlxs_fcf_event_xlate(evt), arg1, 14963 emlxs_rpi_state_xlate(rpip->prev_state)); 14964 14965 return (1); 14966 } 14967 14968 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14969 "rpi_reserved_action:%d rpi_online=%d,%d. <", 14970 rpip->RPI, 14971 vpip->rpi_online, vpip->rpi_paused); 14972 14973 return (0); 14974 14975 } /* emlxs_rpi_reserved_action() */ 14976 14977 14978 /*ARGSUSED*/ 14979 static uint32_t 14980 emlxs_rpi_offline_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14981 void *arg1) 14982 { 14983 uint32_t rval = 0; 14984 VPIobj_t *vpip; 14985 14986 vpip = rpip->vpip; 14987 14988 if (rpip->state != RPI_STATE_OFFLINE) { 14989 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14990 "rpi_offline_action:%d %s:%s arg=%p. " 14991 "Invalid state. <", 14992 rpip->RPI, 14993 emlxs_rpi_state_xlate(rpip->state), 14994 emlxs_fcf_event_xlate(evt), arg1); 14995 return (1); 14996 } 14997 14998 if (rpip->flag & EMLXS_RPI_PAUSED) { 14999 rpip->flag &= ~EMLXS_RPI_PAUSED; 15000 15001 if (vpip->rpi_paused) { 15002 vpip->rpi_paused--; 15003 } 15004 } 15005 15006 if (rpip->flag & EMLXS_RPI_VPI) { 15007 rpip->flag &= ~EMLXS_RPI_VPI; 15008 15009 if (vpip->rpi_online) { 15010 vpip->rpi_online--; 15011 } 15012 15013 /* Added protection */ 15014 if (vpip->rpi_online < vpip->rpi_paused) { 15015 vpip->rpi_paused = vpip->rpi_online; 15016 } 15017 } 15018 15019 if (rpip->RPI == FABRIC_RPI) { 15020 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15021 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15022 "Fabric RPI offline. Freeing.", 15023 rpip->RPI, 15024 vpip->rpi_online, vpip->rpi_paused, 15025 rpip->xri_count); 15026 15027 /* Free RPI */ 15028 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 15029 15030 return (rval); 15031 } 15032 15033 if ((vpip->rpi_online == 0) || 15034 (vpip->rpi_online == vpip->rpi_paused)) { 15035 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15036 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15037 "RPI offline. " 15038 "Notifying VPI:%d >", 15039 rpip->RPI, 15040 vpip->rpi_online, vpip->rpi_paused, 15041 rpip->xri_count, 15042 vpip->VPI); 15043 15044 /* Notify VPI */ 15045 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip); 15046 15047 } else { 15048 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15049 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15050 "RPI offline. Freeing.", 15051 rpip->RPI, 15052 vpip->rpi_online, vpip->rpi_paused, 15053 rpip->xri_count); 15054 } 15055 15056 /* Free RPI */ 15057 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 15058 15059 return (rval); 15060 15061 } /* emlxs_rpi_offline_action() */ 15062 15063 15064 /*ARGSUSED*/ 15065 static uint32_t 15066 emlxs_rpi_paused_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15067 void *arg1) 15068 { 15069 VPIobj_t *vpip; 15070 uint32_t rval = 0; 15071 15072 vpip = rpip->vpip; 15073 15074 if (rpip->state != RPI_STATE_PAUSED) { 15075 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15076 "rpi_paused_action:%d %s:%s arg=%p. " 15077 "Invalid state. <", 15078 rpip->RPI, 15079 emlxs_rpi_state_xlate(rpip->state), 15080 emlxs_fcf_event_xlate(evt), arg1); 15081 return (1); 15082 } 15083 15084 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) { 15085 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15086 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15087 "VPI:%d pause not requested. Unregistering.", 15088 rpip->RPI, 15089 vpip->rpi_online, vpip->rpi_paused, 15090 rpip->xri_count, 15091 vpip->VPI); 15092 15093 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15094 FCF_REASON_EVENT, evt, arg1); 15095 return (rval); 15096 } 15097 15098 if (!(rpip->flag & EMLXS_RPI_PAUSED)) { 15099 rpip->flag |= EMLXS_RPI_PAUSED; 15100 vpip->rpi_paused++; 15101 } 15102 15103 /* Check if all RPI's have been paused for a VPI */ 15104 if (vpip->rpi_online == vpip->rpi_paused) { 15105 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15106 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15107 "RPI paused. " 15108 "Notifying VPI:%d >", 15109 rpip->RPI, 15110 vpip->rpi_online, vpip->rpi_paused, 15111 rpip->xri_count, 15112 vpip->VPI); 15113 15114 /* Notify VPI */ 15115 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_PAUSE, rpip); 15116 15117 } else { 15118 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15119 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15120 "RPI paused. <", 15121 rpip->RPI, 15122 vpip->rpi_online, vpip->rpi_paused, 15123 rpip->xri_count); 15124 } 15125 15126 return (0); 15127 15128 } /* emlxs_rpi_paused_action() */ 15129 15130 15131 /*ARGSUSED*/ 15132 static uint32_t 15133 emlxs_rpi_unreg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15134 void *arg1) 15135 { 15136 uint32_t rval = 0; 15137 15138 rpip->attempts++; 15139 15140 if (rpip->state != RPI_STATE_UNREG_FAILED) { 15141 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15142 "rpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 15143 "Invalid state. <", 15144 rpip->RPI, 15145 emlxs_rpi_state_xlate(rpip->state), 15146 emlxs_fcf_event_xlate(evt), arg1, 15147 rpip->attempts); 15148 return (1); 15149 } 15150 15151 if ((rpip->reason == FCF_REASON_SEND_FAILED) || 15152 !(rpip->flag & EMLXS_RPI_REG)) { 15153 15154 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15155 "rpi_unreg_failed_action:%d reason=%x flag=%x. " 15156 "Going offline.", 15157 rpip->RPI, 15158 rpip->reason, 15159 rpip->flag); 15160 15161 rpip->flag &= ~EMLXS_RPI_REG; 15162 15163 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15164 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15165 } else { 15166 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15167 "rpi_unreg_failed_action:%d flag=%x. Going online.", 15168 rpip->RPI, 15169 rpip->flag); 15170 15171 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15172 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15173 } 15174 15175 return (rval); 15176 15177 } /* emlxs_rpi_unreg_failed_action() */ 15178 15179 15180 static void 15181 emlxs_rpi_unreg_handler(emlxs_port_t *port, RPIobj_t *rpip) 15182 { 15183 emlxs_hba_t *hba = HBA; 15184 VPIobj_t *vpip = rpip->vpip; 15185 emlxs_node_t *node = rpip->node; 15186 XRIobj_t *xrip; 15187 XRIobj_t *next_xrip; 15188 15189 /* Special handling for Fabric RPI */ 15190 if (rpip->RPI == FABRIC_RPI) { 15191 if (node) { 15192 (void) emlxs_tx_node_flush(port, node, 0, 0, 0); 15193 (void) emlxs_chipq_node_flush(port, 0, node, 0); 15194 } 15195 15196 /* Clear all reserved XRIs under this RPI */ 15197 mutex_enter(&EMLXS_FCTAB_LOCK); 15198 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 15199 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 15200 next_xrip = xrip->_f; 15201 /* We don't need to worry about xrip->reserved_rpip */ 15202 /* here because the Fabric RPI can never be reserved */ 15203 /* by an xri. */ 15204 if ((xrip->rpip == rpip) && 15205 (xrip->flag & EMLXS_XRI_RESERVED)) { 15206 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15207 "rpi_unreg_handler:%d xri_count=%d. " 15208 "Unreserving XRI:%d iotag:%d.", 15209 rpip->RPI, 15210 rpip->xri_count, 15211 xrip->XRI, xrip->iotag); 15212 15213 (void) emlxs_sli4_unreserve_xri(port, 15214 xrip->XRI, 0); 15215 } 15216 xrip = next_xrip; 15217 } 15218 mutex_exit(&EMLXS_FCTAB_LOCK); 15219 } 15220 15221 rpip->flag &= ~EMLXS_RPI_REG; 15222 15223 if (rpip->flag & EMLXS_RPI_PAUSED) { 15224 rpip->flag &= ~EMLXS_RPI_PAUSED; 15225 15226 if (vpip->rpi_paused) { 15227 vpip->rpi_paused--; 15228 } 15229 } 15230 15231 if (rpip->flag & EMLXS_RPI_VPI) { 15232 rpip->flag &= ~EMLXS_RPI_VPI; 15233 15234 if (vpip->rpi_online) { 15235 vpip->rpi_online--; 15236 } 15237 15238 /* Added protection */ 15239 if (vpip->rpi_online < vpip->rpi_paused) { 15240 vpip->rpi_paused = vpip->rpi_online; 15241 } 15242 } 15243 15244 rw_enter(&port->node_rwlock, RW_WRITER); 15245 if (node) { 15246 rpip->node = NULL; 15247 node->rpip = NULL; 15248 } 15249 rw_exit(&port->node_rwlock); 15250 15251 if (node) { 15252 emlxs_node_rm(port, node); 15253 } 15254 15255 return; 15256 15257 } /* emlxs_rpi_unreg_handler() */ 15258 15259 15260 /*ARGSUSED*/ 15261 static uint32_t 15262 emlxs_rpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15263 { 15264 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15265 MAILBOX4 *mb4; 15266 RPIobj_t *rpip; 15267 15268 mutex_enter(&EMLXS_FCF_LOCK); 15269 15270 rpip = (RPIobj_t *)mbq->context; 15271 15272 mb4 = (MAILBOX4 *)mbq; 15273 15274 if (rpip->state != RPI_STATE_UNREG) { 15275 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15276 "rpi_unreg_mbcmpl:%d state=%s. " 15277 "No longer in RPI_STATE_UNREG.", 15278 rpip->RPI, 15279 emlxs_rpi_state_xlate(rpip->state)); 15280 15281 mutex_exit(&EMLXS_FCF_LOCK); 15282 return (0); 15283 } 15284 15285 if (mb4->mbxStatus) { 15286 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15287 "rpi_unreg_mbcmpl:%d failed. %s. >", 15288 rpip->RPI, 15289 emlxs_mb_xlate_status(mb4->mbxStatus)); 15290 15291 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15292 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 15293 15294 mutex_exit(&EMLXS_FCF_LOCK); 15295 return (0); 15296 } 15297 15298 emlxs_rpi_unreg_handler(port, rpip); 15299 15300 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15301 "rpi_unreg_mbcmpl:%d Unregistered. Unreg complete. >", 15302 rpip->RPI); 15303 15304 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_CMPL, 15305 0, 0, 0); 15306 15307 mutex_exit(&EMLXS_FCF_LOCK); 15308 return (0); 15309 15310 } /* emlxs_rpi_unreg_mbcmpl() */ 15311 15312 15313 /*ARGSUSED*/ 15314 static uint32_t 15315 emlxs_rpi_unreg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15316 void *arg1) 15317 { 15318 emlxs_hba_t *hba = HBA; 15319 MAILBOX4 *mb4; 15320 MAILBOXQ *mbq; 15321 uint32_t rval = 0; 15322 VPIobj_t *vpip = rpip->vpip; 15323 15324 if (rpip->state != RPI_STATE_UNREG) { 15325 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15326 "rpi_unreg_action:%d %s:%s arg=%p. " 15327 "Invalid state. <", 15328 rpip->RPI, 15329 emlxs_rpi_state_xlate(rpip->state), 15330 emlxs_fcf_event_xlate(evt), arg1); 15331 return (1); 15332 } 15333 15334 if (!(rpip->flag & EMLXS_RPI_REG)) { 15335 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15336 "rpi_unreg_action:%d. Not registered. Going offline.", 15337 rpip->RPI); 15338 15339 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15340 FCF_REASON_EVENT, evt, arg1); 15341 15342 return (rval); 15343 } 15344 15345 if (rpip->prev_state != RPI_STATE_UNREG_FAILED) { 15346 rpip->attempts = 0; 15347 } 15348 15349 if (rpip->RPI == FABRIC_RPI) { 15350 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15351 "rpi_unreg_action:%d did=%x vpi=%d. Fabric RPI. " 15352 "Going offline.", 15353 rpip->RPI, 15354 rpip->did, 15355 rpip->vpip->VPI); 15356 15357 /* Don't send UNREG_RPI, but process it as if we did */ 15358 emlxs_rpi_unreg_handler(port, rpip); 15359 15360 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15361 FCF_REASON_EVENT, evt, arg1); 15362 15363 return (rval); 15364 } 15365 15366 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15367 "rpi_unreg_action:%d attempts=%d. Sending UNREG_RPI. <", 15368 rpip->RPI, 15369 rpip->attempts); 15370 15371 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15372 15373 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15374 FCF_REASON_NO_MBOX, 0, arg1); 15375 15376 return (rval); 15377 } 15378 mb4 = (MAILBOX4*)mbq; 15379 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15380 15381 mbq->nonembed = NULL; 15382 mbq->mbox_cmpl = emlxs_rpi_unreg_mbcmpl; 15383 mbq->context = (void *)rpip; 15384 mbq->port = (void *)port; 15385 15386 mb4->mbxCommand = MBX_UNREG_RPI; 15387 mb4->mbxOwner = OWN_HOST; 15388 mb4->un.varUnregLogin.rpi = rpip->RPI; 15389 mb4->un.varUnregLogin.vpi = vpip->VPI; 15390 15391 if (rpip->cmpl) { 15392 mbq->sbp = rpip->cmpl->arg1; 15393 mbq->ubp = rpip->cmpl->arg2; 15394 mbq->iocbq = rpip->cmpl->arg3; 15395 } 15396 15397 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15398 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15399 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15400 15401 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15402 FCF_REASON_SEND_FAILED, rval, arg1); 15403 15404 return (rval); 15405 } 15406 15407 if (rpip->cmpl) { 15408 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15409 rpip->cmpl = 0; 15410 } 15411 15412 return (0); 15413 15414 } /* emlxs_rpi_unreg_action() */ 15415 15416 15417 /*ARGSUSED*/ 15418 static uint32_t 15419 emlxs_rpi_unreg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15420 void *arg1) 15421 { 15422 uint32_t rval = 0; 15423 15424 if (rpip->state != RPI_STATE_UNREG_CMPL) { 15425 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15426 "rpi_unreg_cmpl_action:%d %s:%s arg=%p. " 15427 "Invalid state. <", 15428 rpip->RPI, 15429 emlxs_rpi_state_xlate(rpip->state), 15430 emlxs_fcf_event_xlate(evt), arg1); 15431 return (1); 15432 } 15433 15434 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15435 "rpi_unreg_cmpl_action:%d flag=%x. Going offline.", 15436 rpip->RPI, 15437 rpip->flag); 15438 15439 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15440 FCF_REASON_EVENT, evt, arg1); 15441 15442 return (rval); 15443 15444 } /* emlxs_rpi_unreg_cmpl_action() */ 15445 15446 15447 /*ARGSUSED*/ 15448 static uint32_t 15449 emlxs_rpi_reg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15450 void *arg1) 15451 { 15452 uint32_t rval = 0; 15453 15454 rpip->attempts++; 15455 15456 if (rpip->state != RPI_STATE_REG_FAILED) { 15457 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15458 "rpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 15459 "Invalid state. <", 15460 rpip->RPI, 15461 emlxs_rpi_state_xlate(rpip->state), 15462 emlxs_fcf_event_xlate(evt), arg1, 15463 rpip->attempts); 15464 return (1); 15465 } 15466 15467 if ((rpip->reason == FCF_REASON_SEND_FAILED) || 15468 !(rpip->flag & EMLXS_RPI_REG)) { 15469 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15470 "rpi_reg_failed_action:%d reason=%x flag=%x. " 15471 "Going offline.", 15472 rpip->RPI, 15473 rpip->reason, 15474 rpip->flag); 15475 15476 rpip->flag &= ~EMLXS_RPI_REG; 15477 15478 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15479 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15480 } else { 15481 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15482 "rpi_reg_failed_action:%d flag=%x. Unregistering", 15483 rpip->RPI, 15484 rpip->flag); 15485 15486 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15487 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15488 } 15489 15490 return (rval); 15491 15492 } /* emlxs_rpi_reg_failed_action() */ 15493 15494 15495 static uint32_t 15496 emlxs_rpi_reg_handler(emlxs_port_t *port, RPIobj_t *rpip) 15497 { 15498 emlxs_hba_t *hba = HBA; 15499 VPIobj_t *vpip; 15500 emlxs_node_t *node; 15501 15502 vpip = rpip->vpip; 15503 15504 rpip->flag |= EMLXS_RPI_REG; 15505 15506 if (rpip->flag & EMLXS_RPI_PAUSED) { 15507 rpip->flag &= ~EMLXS_RPI_PAUSED; 15508 15509 if (vpip->rpi_paused) { 15510 vpip->rpi_paused--; 15511 } 15512 } 15513 15514 if (!(rpip->flag & EMLXS_RPI_VPI) && (rpip->RPI != FABRIC_RPI)) { 15515 rpip->flag |= EMLXS_RPI_VPI; 15516 vpip->rpi_online++; 15517 } 15518 15519 /* If private loop and this is fabric RPI, then exit now */ 15520 if (!(hba->flag & FC_FABRIC_ATTACHED) && (rpip->RPI == FABRIC_RPI)) { 15521 return (0); 15522 } 15523 15524 /* Create or update the node */ 15525 node = emlxs_node_create(port, rpip->did, rpip->RPI, &rpip->sparam); 15526 15527 if (!node) { 15528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15529 "rpi_reg_handler:%d. Node create failed. Reg failed.", 15530 rpip->RPI); 15531 15532 return (FCF_REASON_NO_NODE); 15533 } 15534 15535 return (0); 15536 15537 } /* emlxs_rpi_reg_handler() */ 15538 15539 15540 /*ARGSUSED*/ 15541 static uint32_t 15542 emlxs_rpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15543 { 15544 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15545 MAILBOX4 *mb4; 15546 RPIobj_t *rpip; 15547 emlxs_node_t *node; 15548 uint32_t rval = 0; 15549 15550 mutex_enter(&EMLXS_FCF_LOCK); 15551 15552 rpip = (RPIobj_t *)mbq->context; 15553 mb4 = (MAILBOX4 *)mbq; 15554 15555 if (rpip->state != RPI_STATE_REG) { 15556 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15557 "rpi_reg_mbcmpl:%d state=%s. No longer in RPI_STATE_REG.", 15558 rpip->RPI, 15559 emlxs_rpi_state_xlate(rpip->state)); 15560 15561 mutex_exit(&EMLXS_FCF_LOCK); 15562 return (0); 15563 } 15564 15565 if (mb4->mbxStatus) { 15566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15567 "rpi_reg_mbcmpl:%d failed. %s. >", 15568 rpip->RPI, 15569 emlxs_mb_xlate_status(mb4->mbxStatus)); 15570 15571 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15572 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 15573 15574 mutex_exit(&EMLXS_FCF_LOCK); 15575 return (0); 15576 } 15577 15578 rval = emlxs_rpi_reg_handler(port, rpip); 15579 15580 if (rval) { 15581 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15582 "rpi_reg_mbcmpl:%d. Reg failed. >", 15583 rpip->RPI); 15584 15585 mb4->mbxStatus = MBX_FAILURE; 15586 15587 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15588 rval, 0, 0); 15589 15590 mutex_exit(&EMLXS_FCF_LOCK); 15591 return (0); 15592 } 15593 15594 node = rpip->node; 15595 15596 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15597 "rpi_reg_mbcmpl:%d Registered. Reg complete. >", 15598 rpip->RPI); 15599 15600 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_CMPL, 0, 0, 0); 15601 15602 mutex_exit(&EMLXS_FCF_LOCK); 15603 15604 /* Needed for FCT trigger in emlxs_mb_deferred_cmpl */ 15605 if (mbq->sbp) { 15606 ((emlxs_buf_t *)mbq->sbp)->node = node; 15607 } 15608 15609 #ifdef DHCHAP_SUPPORT 15610 if (mbq->sbp || mbq->ubp) { 15611 if (emlxs_dhc_auth_start(port, node, (uint8_t *)mbq->sbp, 15612 (uint8_t *)mbq->ubp) == 0) { 15613 /* Auth started - auth completion will */ 15614 /* handle sbp and ubp now */ 15615 mbq->sbp = NULL; 15616 mbq->ubp = NULL; 15617 } 15618 } 15619 #endif /* DHCHAP_SUPPORT */ 15620 15621 return (0); 15622 15623 } /* emlxs_rpi_reg_mbcmpl() */ 15624 15625 15626 /*ARGSUSED*/ 15627 static uint32_t 15628 emlxs_rpi_reg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15629 void *arg1) 15630 { 15631 emlxs_hba_t *hba = HBA; 15632 MAILBOX4 *mb4; 15633 MAILBOXQ *mbq; 15634 MATCHMAP *mp; 15635 uint32_t rval = 0; 15636 15637 if (rpip->state != RPI_STATE_REG) { 15638 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15639 "rpi_reg_action:%d %s:%s arg=%p. " 15640 "Invalid state. <", 15641 rpip->RPI, 15642 emlxs_rpi_state_xlate(rpip->state), 15643 emlxs_fcf_event_xlate(evt), arg1); 15644 return (1); 15645 } 15646 15647 if (rpip->RPI == FABRIC_RPI) { 15648 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15649 "rpi_reg_action:%d did=%x vpi=%d. Fabric RPI. " 15650 "Going online.", 15651 rpip->RPI, 15652 rpip->did, 15653 rpip->vpip->VPI); 15654 15655 /* Don't send REG_RPI, but process it as if we did */ 15656 rval = emlxs_rpi_reg_handler(port, rpip); 15657 15658 if (rval) { 15659 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15660 rval, 0, 0); 15661 15662 return (rval); 15663 } 15664 15665 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15666 FCF_REASON_EVENT, evt, arg1); 15667 15668 return (rval); 15669 } 15670 15671 if (rpip->prev_state != RPI_STATE_REG_FAILED) { 15672 rpip->attempts = 0; 15673 } 15674 15675 if (rpip->flag & EMLXS_RPI_REG) { 15676 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15677 "rpi_reg_action:%d attempts=%d. " 15678 "Updating REG_RPI. <", 15679 rpip->RPI, 15680 rpip->attempts); 15681 } else { 15682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15683 "rpi_reg_action:%d attempts=%d. " 15684 "Sending REG_RPI. <", 15685 rpip->RPI, 15686 rpip->attempts); 15687 } 15688 15689 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15690 15691 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15692 FCF_REASON_NO_MBOX, 0, arg1); 15693 15694 return (rval); 15695 } 15696 15697 mb4 = (MAILBOX4*)mbq; 15698 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15699 15700 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 15701 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15702 15703 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15704 FCF_REASON_NO_BUFFER, 0, arg1); 15705 15706 return (rval); 15707 } 15708 15709 mbq->bp = (void *)mp; 15710 mbq->nonembed = NULL; 15711 15712 mbq->mbox_cmpl = emlxs_rpi_reg_mbcmpl; 15713 mbq->context = (void *)rpip; 15714 mbq->port = (void *)port; 15715 15716 mb4->mbxCommand = MBX_REG_RPI; 15717 mb4->mbxOwner = OWN_HOST; 15718 15719 mb4->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 15720 mb4->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys); 15721 mb4->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys); 15722 mb4->un.varRegLogin.did = rpip->did; 15723 mb4->un.varWords[30] = 0; /* flags */ 15724 15725 mb4->un.varRegLogin.vpi = rpip->vpip->VPI; 15726 mb4->un.varRegLogin.rpi = rpip->RPI; 15727 mb4->un.varRegLogin.update = (rpip->flag & EMLXS_RPI_REG)? 1:0; 15728 15729 bcopy((void *)&rpip->sparam, (void *)mp->virt, sizeof (SERV_PARM)); 15730 15731 if (rpip->cmpl) { 15732 mbq->sbp = rpip->cmpl->arg1; 15733 mbq->ubp = rpip->cmpl->arg2; 15734 mbq->iocbq = rpip->cmpl->arg3; 15735 } 15736 15737 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15738 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15739 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 15740 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15741 15742 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15743 FCF_REASON_SEND_FAILED, rval, arg1); 15744 15745 return (rval); 15746 } 15747 15748 if (rpip->cmpl) { 15749 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15750 rpip->cmpl = 0; 15751 } 15752 15753 return (0); 15754 15755 } /* emlxs_rpi_reg_action() */ 15756 15757 15758 /*ARGSUSED*/ 15759 static uint32_t 15760 emlxs_rpi_reg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15761 void *arg1) 15762 { 15763 uint32_t rval = 0; 15764 15765 if (rpip->state != RPI_STATE_REG_CMPL) { 15766 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15767 "rpi_reg_cmpl_action:%d %s:%s arg=%p. " 15768 "Invalid state. <", 15769 rpip->RPI, 15770 emlxs_rpi_state_xlate(rpip->state), 15771 emlxs_fcf_event_xlate(evt), arg1); 15772 return (1); 15773 } 15774 15775 if (rpip->flag & EMLXS_RPI_REG) { 15776 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15777 "rpi_reg_cmpl_action:%d flag=%x. Going online.", 15778 rpip->RPI, 15779 rpip->flag); 15780 15781 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15782 FCF_REASON_EVENT, evt, arg1); 15783 } else { 15784 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15785 "rpi_reg_cmpl_action:%d flag=%x. Going offline.", 15786 rpip->RPI, 15787 rpip->flag); 15788 15789 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15790 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15791 } 15792 15793 return (rval); 15794 15795 } /* emlxs_rpi_reg_cmpl_action() */ 15796 15797 15798 /*ARGSUSED*/ 15799 static uint32_t 15800 emlxs_rpi_resume_failed_action(emlxs_port_t *port, RPIobj_t *rpip, 15801 uint32_t evt, void *arg1) 15802 { 15803 uint32_t rval = 0; 15804 15805 rpip->attempts++; 15806 15807 if (rpip->state != RPI_STATE_RESUME_FAILED) { 15808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15809 "rpi_resume_failed_action:%d %s:%s arg=%p attempt=%d. " 15810 "Invalid state. <", 15811 rpip->RPI, 15812 emlxs_rpi_state_xlate(rpip->state), 15813 emlxs_fcf_event_xlate(evt), arg1, 15814 rpip->attempts); 15815 return (1); 15816 } 15817 15818 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15819 "rpi_resume_failed_action:%d attempt=%d. Unregistering.", 15820 rpip->RPI, 15821 rpip->attempts); 15822 15823 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15824 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15825 15826 return (rval); 15827 15828 } /* emlxs_rpi_resume_failed_action() */ 15829 15830 15831 /*ARGSUSED*/ 15832 static void 15833 emlxs_rpi_resume_handler(emlxs_port_t *port, RPIobj_t *rpip) 15834 { 15835 if (rpip->flag & EMLXS_RPI_PAUSED) { 15836 rpip->flag &= ~EMLXS_RPI_PAUSED; 15837 15838 if (rpip->vpip->rpi_paused) { 15839 rpip->vpip->rpi_paused--; 15840 } 15841 } 15842 15843 return; 15844 15845 } /* emlxs_rpi_resume_handler() */ 15846 15847 15848 /*ARGSUSED*/ 15849 static uint32_t 15850 emlxs_rpi_resume_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15851 { 15852 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15853 MAILBOX4 *mb4; 15854 RPIobj_t *rpip; 15855 15856 mutex_enter(&EMLXS_FCF_LOCK); 15857 15858 rpip = (RPIobj_t *)mbq->context; 15859 mb4 = (MAILBOX4 *)mbq; 15860 15861 if (rpip->state != RPI_STATE_RESUME) { 15862 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15863 "rpi_resume_mbcmpl:%d state=%s. " 15864 "No longer in RPI_STATE_RESUME.", 15865 rpip->RPI, 15866 emlxs_rpi_state_xlate(rpip->state)); 15867 15868 mutex_exit(&EMLXS_FCF_LOCK); 15869 return (0); 15870 } 15871 15872 if (mb4->mbxStatus) { 15873 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15874 "rpi_resume_mbcmpl:%d failed. %s. >", 15875 rpip->RPI, 15876 emlxs_mb_xlate_status(mb4->mbxStatus)); 15877 15878 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15879 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 15880 15881 mutex_exit(&EMLXS_FCF_LOCK); 15882 return (0); 15883 } 15884 15885 emlxs_rpi_resume_handler(port, rpip); 15886 15887 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15888 "rpi_resume_mbcmpl:%d Resumed. Resume complete. >", 15889 rpip->RPI); 15890 15891 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_CMPL, 0, 0, 0); 15892 15893 mutex_exit(&EMLXS_FCF_LOCK); 15894 15895 return (0); 15896 15897 } /* emlxs_rpi_resume_mbcmpl() */ 15898 15899 15900 /*ARGSUSED*/ 15901 static uint32_t 15902 emlxs_rpi_resume_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15903 void *arg1) 15904 { 15905 emlxs_hba_t *hba = HBA; 15906 MAILBOX4 *mb4; 15907 MAILBOXQ *mbq; 15908 uint32_t rval = 0; 15909 15910 if (rpip->state != RPI_STATE_RESUME) { 15911 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15912 "rpi_resume_action:%d %s:%s arg=%p. " 15913 "Invalid state. <", 15914 rpip->RPI, 15915 emlxs_rpi_state_xlate(rpip->state), 15916 emlxs_fcf_event_xlate(evt), arg1); 15917 return (1); 15918 } 15919 15920 if (!(rpip->flag & EMLXS_RPI_PAUSED)) { 15921 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15922 "rpi_resume_action:%d flag=%x. Not Paused. Going online.", 15923 rpip->RPI, rpip->flag); 15924 15925 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15926 FCF_REASON_EVENT, evt, arg1); 15927 15928 return (rval); 15929 } 15930 15931 if (rpip->RPI == FABRIC_RPI) { 15932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15933 "rpi_resume_action:%d. Fabric RPI. " 15934 "Going online.", 15935 rpip->RPI); 15936 15937 /* Don't send RESUME_RPI, but process it as if we did */ 15938 emlxs_rpi_resume_handler(port, rpip); 15939 15940 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15941 FCF_REASON_EVENT, evt, arg1); 15942 15943 return (rval); 15944 } 15945 15946 if (rpip->prev_state != RPI_STATE_RESUME_FAILED) { 15947 rpip->attempts = 0; 15948 } 15949 15950 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15951 "rpi_resume_action:%d attempts=%d. Sending RESUME_RPI. <", 15952 rpip->RPI, 15953 rpip->attempts); 15954 15955 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15956 15957 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15958 FCF_REASON_NO_MBOX, 0, arg1); 15959 15960 return (rval); 15961 } 15962 mb4 = (MAILBOX4*)mbq; 15963 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15964 15965 mbq->nonembed = NULL; 15966 mbq->mbox_cmpl = emlxs_rpi_resume_mbcmpl; 15967 mbq->context = (void *)rpip; 15968 mbq->port = (void *)port; 15969 15970 mb4->mbxCommand = MBX_RESUME_RPI; 15971 mb4->mbxOwner = OWN_HOST; 15972 15973 mb4->un.varResumeRPI.EventTag = hba->link_event_tag; 15974 mb4->un.varResumeRPI.RPI = rpip->RPI; 15975 15976 if (rpip->cmpl) { 15977 mbq->sbp = rpip->cmpl->arg1; 15978 mbq->ubp = rpip->cmpl->arg2; 15979 mbq->iocbq = rpip->cmpl->arg3; 15980 } 15981 15982 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15983 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15984 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15985 15986 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15987 FCF_REASON_SEND_FAILED, rval, arg1); 15988 15989 return (rval); 15990 } 15991 15992 if (rpip->cmpl) { 15993 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15994 rpip->cmpl = 0; 15995 } 15996 15997 return (0); 15998 15999 } /* emlxs_rpi_resume_action() */ 16000 16001 16002 static uint32_t 16003 emlxs_rpi_resume_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 16004 void *arg1) 16005 { 16006 uint32_t rval = 0; 16007 16008 if (rpip->state != RPI_STATE_RESUME_CMPL) { 16009 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 16010 "rpi_resume_cmpl_action:%d %s:%s arg=%p. " 16011 "Invalid state. <", 16012 rpip->RPI, 16013 emlxs_rpi_state_xlate(rpip->state), 16014 emlxs_fcf_event_xlate(evt), arg1); 16015 return (1); 16016 } 16017 16018 if (rpip->flag & EMLXS_RPI_PAUSED) { 16019 if (rpip->flag & EMLXS_RPI_REG) { 16020 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16021 "rpi_reg_cmpl_action:%d flag=%x. Unregistering.", 16022 rpip->RPI, 16023 rpip->flag); 16024 16025 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 16026 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16027 } else { 16028 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16029 "rpi_reg_cmpl_action:%d flag=%x. Going offline.", 16030 rpip->RPI, 16031 rpip->flag); 16032 16033 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 16034 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16035 } 16036 } else { 16037 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16038 "rpi_resume_cmpl_action:%d flag=%x. Going online.", 16039 rpip->RPI, 16040 rpip->flag); 16041 16042 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 16043 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16044 } 16045 16046 return (rval); 16047 16048 } /* emlxs_rpi_resume_cmpl_action() */ 16049 16050 16051 /*ARGSUSED*/ 16052 static uint32_t 16053 emlxs_rpi_online_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 16054 void *arg1) 16055 { 16056 emlxs_hba_t *hba = HBA; 16057 uint32_t rval = 0; 16058 RPIobj_t *p2p_rpip; 16059 16060 if (rpip->state != RPI_STATE_ONLINE) { 16061 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16062 "rpi_online_action:%d %s:%s arg=%p. " 16063 "Invalid state. <", 16064 rpip->RPI, 16065 emlxs_rpi_state_xlate(rpip->state), 16066 emlxs_fcf_event_xlate(evt), arg1); 16067 return (1); 16068 } 16069 16070 if (rpip->RPI == FABRIC_RPI) { 16071 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16072 "rpi_online_action:%d did=%x. Fabric RPI online. <", 16073 rpip->RPI, 16074 rpip->did, 16075 rpip->vpip->VPI); 16076 16077 /* Now register the p2p_rpip */ 16078 p2p_rpip = rpip->vpip->p2p_rpip; 16079 if (p2p_rpip) { 16080 rpip->vpip->p2p_rpip = NULL; 16081 16082 rval = emlxs_rpi_state(port, p2p_rpip, RPI_STATE_REG, 16083 FCF_REASON_EVENT, evt, arg1); 16084 } 16085 16086 EMLXS_STATE_CHANGE(hba, FC_READY); 16087 16088 if (rpip->cmpl) { 16089 emlxs_rpi_deferred_cmpl(port, rpip, 0); 16090 } 16091 16092 return (0); 16093 } 16094 16095 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16096 "rpi_online_action:%d did=%x. RPI online. Notifying VPI:%d. >", 16097 rpip->RPI, 16098 rpip->did, 16099 rpip->vpip->VPI); 16100 16101 /* Notify VPI */ 16102 rval = emlxs_vpi_event(port, FCF_EVENT_RPI_ONLINE, rpip); 16103 16104 return (rval); 16105 16106 } /* emlxs_rpi_online_action() */ 16107