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 mb4->un.varCfgLnk.citov = hba->fc_citov; 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, 11976 void *arg1, void *arg2) 11977 { 11978 emlxs_deferred_cmpl_t *cmpl = (emlxs_deferred_cmpl_t *)arg1; 11979 uint32_t status = (uint32_t)((unsigned long)arg2); 11980 emlxs_port_t *port; 11981 uint32_t mbxStatus; 11982 emlxs_buf_t *sbp; 11983 fc_unsol_buf_t *ubp; 11984 IOCBQ *iocbq; 11985 11986 mbxStatus = (status)? MBX_FAILURE:MBX_SUCCESS; 11987 11988 port = cmpl->port; 11989 sbp = (emlxs_buf_t *)cmpl->arg1; 11990 ubp = (fc_unsol_buf_t *)cmpl->arg2; 11991 iocbq = (IOCBQ *)cmpl->arg3; 11992 11993 kmem_free(cmpl, sizeof (emlxs_deferred_cmpl_t)); 11994 11995 emlxs_mb_deferred_cmpl(port, mbxStatus, sbp, ubp, iocbq); 11996 11997 return; 11998 11999 } /* emlxs_deferred_cmpl_thread() */ 12000 12001 12002 12003 12004 /* ARGSUSED */ 12005 static void 12006 emlxs_port_offline_thread(emlxs_hba_t *hba, 12007 void *arg1, void *arg2) 12008 { 12009 emlxs_port_t *port = (emlxs_port_t *)arg1; 12010 uint32_t scope = (uint32_t)((unsigned long)arg2); 12011 12012 (void) emlxs_port_offline(port, scope); 12013 return; 12014 12015 } /* emlxs_port_offline_thread() */ 12016 12017 12018 /* ARGSUSED */ 12019 static void 12020 emlxs_port_online_thread(emlxs_hba_t *hba, 12021 void *arg1, void *arg2) 12022 { 12023 emlxs_port_t *port = (emlxs_port_t *)arg1; 12024 12025 (void) emlxs_port_online(port); 12026 return; 12027 12028 } /* emlxs_port_online_thread() */ 12029 12030 12031 /*ARGSUSED*/ 12032 static void 12033 emlxs_vpi_logo_handler(emlxs_port_t *port, VPIobj_t *vpip) 12034 { 12035 vpip->flag &= ~EMLXS_VPI_LOGI; 12036 if (vpip->flag & EMLXS_VPI_VFI_LOGI) { 12037 vpip->flag &= ~EMLXS_VPI_VFI_LOGI; 12038 12039 if (vpip->vfip->logi_count) { 12040 vpip->vfip->logi_count--; 12041 } 12042 if (vpip == vpip->vfip->flogi_vpip) { 12043 vpip->vfip->flogi_vpip = NULL; 12044 } 12045 } 12046 12047 } /* emlxs_vpi_logo_handler() */ 12048 12049 12050 /*ARGSUSED*/ 12051 static uint32_t 12052 emlxs_vpi_port_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12053 void *arg1) 12054 { 12055 emlxs_hba_t *hba = HBA; 12056 uint32_t rval = 0; 12057 uint32_t scope; 12058 12059 if (vpip->state != VPI_STATE_PORT_OFFLINE) { 12060 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12061 "vpi_port_offline_action:%d %s:%s arg=%p. " 12062 "Invalid state. <", 12063 vpip->VPI, 12064 emlxs_vpi_state_xlate(vpip->state), 12065 emlxs_fcf_event_xlate(evt), arg1); 12066 return (1); 12067 } 12068 12069 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) { 12070 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12071 "vpi_port_offline_action:%d flag=%x. Offlining port...", 12072 vpip->VPI, 12073 vpip->flag); 12074 12075 vpip->flag &= ~(EMLXS_VPI_PORT_ONLINE|EMLXS_VPI_PORT_ENABLED); 12076 12077 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 12078 scope = 0xFFFFFFFF; /* Clear all non-FCP2 nodes */ 12079 /* Pause FCP2 nodes */ 12080 } else { 12081 scope = 0xFDFFFFFF; /* Clear all nodes */ 12082 } 12083 12084 emlxs_thread_spawn(hba, emlxs_port_offline_thread, 12085 (void *)vpip->port, (void *)((unsigned long)scope)); 12086 12087 if (vpip->flag & EMLXS_VPI_LOGI) { 12088 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO, 12089 FCF_REASON_EVENT, evt, arg1); 12090 12091 return (rval); 12092 } 12093 } 12094 12095 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 12096 if (vpip->rpi_online > vpip->rpi_paused) { 12097 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12098 "vpi_port_offline_action:%d rpi_online=%d,%d. " 12099 "Pausing. Waiting for RPI's. <", 12100 vpip->VPI, 12101 vpip->rpi_online, vpip->rpi_paused); 12102 return (0); 12103 } 12104 12105 /* Take the Fabric RPI offline now */ 12106 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12107 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12108 "vpi_port_offline_action:%d. " 12109 "Offlining Fabric RPI. >", 12110 vpip->VPI); 12111 12112 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12113 vpip->fabric_rpip); 12114 } 12115 12116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12117 "vpi_port_offline_action:%d rpi_online=%d,%d. Pausing.", 12118 vpip->VPI, 12119 vpip->rpi_online, vpip->rpi_paused); 12120 12121 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED, 12122 FCF_REASON_EVENT, evt, arg1); 12123 12124 return (rval); 12125 } 12126 12127 if (vpip->rpi_online > 0) { 12128 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12129 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. " 12130 "Waiting for RPI's. <", 12131 vpip->VPI, 12132 vpip->rpi_online, vpip->rpi_paused); 12133 12134 return (0); 12135 } 12136 12137 /* Take the Fabric RPI offline now */ 12138 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12139 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12140 "vpi_port_offline_action:%d. Offlining Fabric RPI. >", 12141 vpip->VPI); 12142 12143 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12144 vpip->fabric_rpip); 12145 } 12146 12147 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12148 "vpi_port_offline_action:%d rpi_online=%d,%d. Offlining. " 12149 "Unreg VPI.", 12150 vpip->VPI, 12151 vpip->rpi_online, vpip->rpi_paused); 12152 12153 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 12154 FCF_REASON_EVENT, evt, arg1); 12155 12156 return (rval); 12157 12158 } /* emlxs_vpi_port_offline_action() */ 12159 12160 12161 /*ARGSUSED*/ 12162 static uint32_t 12163 emlxs_vpi_paused_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12164 void *arg1) 12165 { 12166 if (vpip->state != VPI_STATE_PAUSED) { 12167 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12168 "vpi_paused_action:%d %s:%s arg=%p. " 12169 "Invalid state. <", 12170 vpip->VPI, 12171 emlxs_vpi_state_xlate(vpip->state), 12172 emlxs_fcf_event_xlate(evt), arg1); 12173 return (1); 12174 } 12175 12176 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 12177 12178 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12179 "vpi_paused_action:%d rpi_online=%d,%d. VPI paused. <", 12180 vpip->VPI, 12181 vpip->rpi_online, vpip->rpi_paused); 12182 12183 return (0); 12184 12185 } /* emlxs_vpi_paused_action() */ 12186 12187 12188 /*ARGSUSED*/ 12189 static uint32_t 12190 emlxs_vpi_offline_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12191 void *arg1) 12192 { 12193 uint32_t rval = 0; 12194 12195 if (vpip->state != VPI_STATE_OFFLINE) { 12196 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12197 "vpi_offline_action:%d %s:%s arg=%p. " 12198 "Invalid state. <", 12199 vpip->VPI, 12200 emlxs_vpi_state_xlate(vpip->state), 12201 emlxs_fcf_event_xlate(evt), arg1); 12202 return (1); 12203 } 12204 12205 if (!vpip->vfip) { 12206 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12207 "vpi_offline_action:%d %s:%s arg=%p flag=%x. " 12208 "Null vfip found. <", 12209 vpip->VPI, 12210 emlxs_vpi_state_xlate(vpip->state), 12211 emlxs_fcf_event_xlate(evt), arg1, 12212 vpip->flag); 12213 return (1); 12214 } 12215 12216 /* Take the Fabric RPI offline, if still active */ 12217 if (vpip->fabric_rpip->state != RPI_STATE_FREE) { 12218 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12219 "vpi_offline_action:%d. Offlining Fabric RPI. >", 12220 vpip->VPI); 12221 12222 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, 12223 vpip->fabric_rpip); 12224 } 12225 12226 vpip->flag &= ~(EMLXS_VPI_OFFLINE_REQ | EMLXS_VPI_PAUSE_REQ); 12227 12228 if (vpip->flag & EMLXS_VPI_VFI) { 12229 vpip->flag &= ~EMLXS_VPI_VFI; 12230 12231 if (vpip->vfip->vpi_online) { 12232 vpip->vfip->vpi_online--; 12233 } 12234 } 12235 12236 /* Check if online was requested */ 12237 if (vpip->flag & EMLXS_VPI_ONLINE_REQ) { 12238 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12239 "vpi_offline_action:%d vpi_online=%d. Online requested.", 12240 vpip->VPI, 12241 vpip->vfip->vpi_online); 12242 12243 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT, 12244 FCF_REASON_REQUESTED, 0, arg1); 12245 return (rval); 12246 } 12247 12248 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12249 "vpi_offline_action:%d vpi_online=%d. " 12250 "VPI offline. Notifying VFI:%d. >", 12251 vpip->VPI, 12252 vpip->vfip->vpi_online, 12253 vpip->vfip->VFI); 12254 12255 /* Notify VFI */ 12256 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 12257 12258 return (rval); 12259 12260 } /* emlxs_vpi_offline_action() */ 12261 12262 12263 /*ARGSUSED*/ 12264 static uint32_t 12265 emlxs_vpi_init_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 12266 { 12267 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 12268 VPIobj_t *vpip; 12269 MAILBOX4 *mb4; 12270 12271 vpip = (VPIobj_t *)mbq->context; 12272 mb4 = (MAILBOX4 *)mbq; 12273 12274 mutex_enter(&EMLXS_FCF_LOCK); 12275 12276 if (vpip->state != VPI_STATE_INIT) { 12277 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12278 "vpi_init_mbcmpl:%d %s.", 12279 vpip->VPI, 12280 emlxs_vpi_state_xlate(vpip->state)); 12281 12282 mutex_exit(&EMLXS_FCF_LOCK); 12283 return (0); 12284 } 12285 12286 if (mb4->mbxStatus) { 12287 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12288 "vpi_init_mbcmpl:%d failed. %s. >", 12289 vpip->VPI, 12290 emlxs_mb_xlate_status(mb4->mbxStatus)); 12291 12292 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED, 12293 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 12294 12295 mutex_exit(&EMLXS_FCF_LOCK); 12296 return (0); 12297 } 12298 12299 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12300 "vpi_init_mbcmpl:%d. Init complete. >", 12301 vpip->VPI, 12302 mb4->mbxStatus); 12303 12304 vpip->flag |= EMLXS_VPI_INIT; 12305 (void) emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL, 12306 0, 0, 0); 12307 12308 mutex_exit(&EMLXS_FCF_LOCK); 12309 return (0); 12310 12311 } /* emlxs_vpi_init_mbcmpl() */ 12312 12313 12314 /*ARGSUSED*/ 12315 static uint32_t 12316 emlxs_vpi_init_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12317 void *arg1) 12318 { 12319 emlxs_hba_t *hba = HBA; 12320 MAILBOXQ *mbq; 12321 MAILBOX4 *mb4; 12322 uint32_t rval = 0; 12323 12324 if (vpip->state != VPI_STATE_INIT) { 12325 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12326 "vpi_init_action:%d %s:%s arg=%p. " 12327 "Invalid state. <", 12328 vpip->VPI, 12329 emlxs_vpi_state_xlate(vpip->state), 12330 emlxs_fcf_event_xlate(evt), arg1); 12331 return (1); 12332 } 12333 12334 if (vpip->prev_state != VPI_STATE_INIT_FAILED) { 12335 vpip->attempts = 0; 12336 } 12337 12338 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12339 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12340 "vpi_init_action:%d attempts=%d. Offline requested.", 12341 vpip->VPI, 12342 vpip->attempts); 12343 12344 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12345 return (rval); 12346 } 12347 12348 if (!(vpip->flag & EMLXS_VPI_VFI)) { 12349 vpip->flag |= EMLXS_VPI_VFI; 12350 vpip->vfip->vpi_online++; 12351 } 12352 12353 if (((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) == 12354 SLI_INTF_IF_TYPE_0) && (vpip->vfip->vpi_online == 1)) { 12355 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12356 "vpi_init_action:%d. First VPI. Skipping INIT_VPI.", 12357 vpip->VPI); 12358 12359 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12360 FCF_REASON_EVENT, evt, arg1); 12361 return (rval); 12362 } 12363 12364 if (vpip->flag & EMLXS_VPI_INIT) { 12365 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12366 "vpi_init_action:%d flag=%x. " 12367 "Already init'd. Skipping INIT_VPI.", 12368 vpip->VPI); 12369 12370 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12371 FCF_REASON_EVENT, evt, arg1); 12372 return (rval); 12373 } 12374 12375 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12376 "vpi_init_action:%d vpi_online=%d attempts=%d. Sending INIT_VPI. <", 12377 vpip->VPI, 12378 vpip->vfip->vpi_online, 12379 vpip->attempts); 12380 12381 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 12382 rval = emlxs_vpi_state(port, vpip, FCFI_STATE_REG_FAILED, 12383 FCF_REASON_NO_MBOX, 0, arg1); 12384 return (rval); 12385 } 12386 mb4 = (MAILBOX4*)mbq; 12387 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 12388 12389 mbq->nonembed = NULL; 12390 mbq->mbox_cmpl = emlxs_vpi_init_mbcmpl; 12391 mbq->context = (void *)vpip; 12392 mbq->port = (void *)port; 12393 12394 mb4->mbxCommand = MBX_INIT_VPI; 12395 mb4->mbxOwner = OWN_HOST; 12396 mb4->un.varInitVPI4.vfi = vpip->vfip->VFI; 12397 mb4->un.varInitVPI4.vpi = vpip->VPI; 12398 12399 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 12400 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 12401 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 12402 12403 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_FAILED, 12404 FCF_REASON_SEND_FAILED, rval, arg1); 12405 12406 return (rval); 12407 } 12408 12409 return (0); 12410 12411 } /* emlxs_vpi_init_action() */ 12412 12413 12414 /*ARGSUSED*/ 12415 static uint32_t 12416 emlxs_vpi_init_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12417 void *arg1) 12418 { 12419 uint32_t rval = 0; 12420 12421 vpip->attempts++; 12422 12423 if (vpip->state != VPI_STATE_INIT_FAILED) { 12424 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12425 "vpi_init_action:%d %s:%s arg=%p attempt=%d. " 12426 "Invalid state. <", 12427 vpip->VPI, 12428 emlxs_vpi_state_xlate(vpip->state), 12429 emlxs_fcf_event_xlate(evt), arg1, 12430 vpip->attempts); 12431 return (1); 12432 } 12433 12434 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 12435 (vpip->attempts >= 3)) { 12436 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12437 "vpi_init_action:%d attempt=%d reason=%x. Init cmpl.", 12438 vpip->VPI, 12439 vpip->attempts, 12440 vpip->reason); 12441 12442 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 12443 12444 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 12445 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 12446 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT_CMPL, 12447 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 12448 } else { 12449 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12450 "vpi_init_action:%d attempt=%d. Initializing.", 12451 vpip->VPI, 12452 vpip->attempts); 12453 12454 rval = emlxs_vpi_state(port, vpip, VPI_STATE_INIT, 12455 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 12456 } 12457 12458 return (rval); 12459 12460 } /* emlxs_vpi_init_failed_action() */ 12461 12462 12463 /*ARGSUSED*/ 12464 static uint32_t 12465 emlxs_vpi_init_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12466 void *arg1) 12467 { 12468 uint32_t rval = 0; 12469 12470 if (vpip->state != VPI_STATE_INIT_CMPL) { 12471 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12472 "vpi_init_cmpl_action:%d %s:%s arg=%p. " 12473 "Invalid state. <", 12474 vpip->VPI, 12475 emlxs_vpi_state_xlate(vpip->state), 12476 emlxs_fcf_event_xlate(evt), arg1); 12477 return (1); 12478 } 12479 12480 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12481 "vpi_init_cmpl_action:%d attempts=%d. Onlining port.", 12482 vpip->VPI, 12483 vpip->attempts); 12484 12485 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_ONLINE, 12486 FCF_REASON_EVENT, evt, arg1); 12487 return (rval); 12488 12489 } /* emlxs_vpi_init_cmpl_action() */ 12490 12491 12492 /*ARGSUSED*/ 12493 static uint32_t 12494 emlxs_vpi_port_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12495 void *arg1) 12496 { 12497 emlxs_hba_t *hba = HBA; 12498 emlxs_config_t *cfg = &CFG; 12499 uint32_t rval = 0; 12500 12501 if (vpip->state != VPI_STATE_PORT_ONLINE) { 12502 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12503 "vpi_port_online_action:%d %s:%s arg=%p. " 12504 "Invalid state. <", 12505 vpip->VPI, 12506 emlxs_vpi_state_xlate(vpip->state), 12507 emlxs_fcf_event_xlate(evt), arg1); 12508 return (1); 12509 } 12510 12511 if (vpip->flag & EMLXS_VPI_PORT_ONLINE) { 12512 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12513 "vpi_port_online_action:%d. Port already online.", 12514 vpip->VPI); 12515 } 12516 12517 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12518 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12519 "vpi_port_online_action:%d. Offline requested.", 12520 vpip->VPI); 12521 12522 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12523 return (rval); 12524 } 12525 12526 /* Initialize the Fabric RPI */ 12527 if (vpip->fabric_rpip->state == RPI_STATE_FREE) { 12528 emlxs_rpi_alloc_fabric_rpi(vpip->port); 12529 } 12530 12531 /* Notify ULP */ 12532 vpip->flag |= EMLXS_VPI_PORT_ONLINE; 12533 12534 if (hba->flag & FC_LOOPBACK_MODE) { 12535 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12536 "vpi_port_online_action:%d. Loopback mode. " 12537 "Registering VPI.", 12538 vpip->VPI); 12539 12540 if (hba->topology != TOPOLOGY_LOOP) { 12541 port->did = 1; 12542 } 12543 12544 vpip->vfip->flogi_vpip = vpip; 12545 12546 bcopy((void *)&vpip->port->sparam, 12547 (void *)&vpip->fabric_rpip->sparam, 12548 sizeof (SERV_PARM)); 12549 12550 /* Update the VPI Fabric RPI */ 12551 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov = 12552 LE_SWAP32((FF_DEF_RATOV * 1000)); 12553 12554 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 12555 FCF_REASON_EVENT, evt, arg1); 12556 12557 return (rval); 12558 } 12559 12560 if ((hba->topology == TOPOLOGY_LOOP) && ! (port->did)) { 12561 port->did = port->granted_alpa; 12562 } 12563 12564 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12565 "vpi_port_online_action:%d vpi_online=%d. Onlining port... <", 12566 vpip->VPI, 12567 vpip->vfip->vpi_online); 12568 12569 if (SLI4_FC_MODE && (port->vpi == 0)) { 12570 mutex_enter(&EMLXS_PORT_LOCK); 12571 hba->linkup_timer = hba->timer_tics + 12572 cfg[CFG_LINKUP_TIMEOUT].current; 12573 mutex_exit(&EMLXS_PORT_LOCK); 12574 } else { 12575 emlxs_thread_spawn(hba, emlxs_port_online_thread, 12576 (void *)vpip->port, 0); 12577 } 12578 12579 /* Wait for emlxs_vpi_logi_notify() */ 12580 12581 return (0); 12582 12583 } /* emlxs_vpi_port_online_action() */ 12584 12585 12586 extern uint32_t 12587 emlxs_vpi_logi_notify(emlxs_port_t *port, emlxs_buf_t *sbp) 12588 { 12589 VPIobj_t *vpip = port->vpip; 12590 emlxs_hba_t *hba = HBA; 12591 uint32_t rval = 0; 12592 12593 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12594 return (1); 12595 } 12596 12597 mutex_enter(&EMLXS_FCF_LOCK); 12598 12599 if (vpip->state == VPI_STATE_OFFLINE) { 12600 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12601 "vpi_logi_notify:%d %s.", 12602 vpip->VPI, 12603 emlxs_vpi_state_xlate(vpip->state)); 12604 12605 mutex_exit(&EMLXS_FCF_LOCK); 12606 12607 return (1); 12608 } 12609 12610 if (vpip->state != VPI_STATE_PORT_ONLINE) { 12611 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12612 "vpi_logi_notify:%d %s. " 12613 "Invalid state.", 12614 vpip->VPI, 12615 emlxs_vpi_state_xlate(vpip->state)); 12616 12617 mutex_exit(&EMLXS_FCF_LOCK); 12618 12619 return (1); 12620 } 12621 12622 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12623 "vpi_logi_notify:%d %s. " 12624 "Logging in. >", 12625 vpip->VPI, 12626 emlxs_vpi_state_xlate(vpip->state)); 12627 12628 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI, 12629 0, 0, sbp); 12630 12631 if (rval) { 12632 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12633 "vpi_logi_notify:%d %s rval=%d.", 12634 vpip->VPI, 12635 emlxs_vpi_state_xlate(vpip->state), 12636 rval); 12637 } 12638 12639 mutex_exit(&EMLXS_FCF_LOCK); 12640 12641 return (rval); 12642 12643 } /* emlxs_vpi_logi_notify() */ 12644 12645 12646 static uint32_t 12647 emlxs_vpi_logi_cmpl_notify(emlxs_port_t *port, RPIobj_t *rpip) 12648 { 12649 emlxs_hba_t *hba = HBA; 12650 VPIobj_t *vpip = port->vpip; 12651 uint32_t rval = 0; 12652 12653 /* EMLXS_FCF_LOCK must be held when calling this routine */ 12654 12655 if (vpip->state != VPI_STATE_LOGI) { 12656 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12657 "vpi_logi_cmpl_notify:%d %s. " 12658 "Invalid state.", 12659 vpip->VPI, 12660 emlxs_vpi_state_xlate(vpip->state)); 12661 return (1); 12662 } 12663 12664 if (rpip->RPI == FABRIC_RPI) { 12665 if (hba->flag & FC_PT_TO_PT) { 12666 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12667 "vpi_logi_cmpl_notify:%d %s. P2P mode. " 12668 "Completing FLOGI.", 12669 vpip->VPI, 12670 emlxs_vpi_state_xlate(vpip->state)); 12671 12672 /* Complete the FLOGI/FDISC now */ 12673 if (rpip->cmpl) { 12674 emlxs_rpi_deferred_cmpl(port, rpip, 0); 12675 } 12676 12677 /* Wait for P2P PLOGI completion to continue */ 12678 return (0); 12679 } 12680 12681 if (!rpip->cmpl || !rpip->cmpl->arg1) { 12682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12683 "vpi_logi_cmpl_notify:%d. Null sbp.", 12684 vpip->VPI); 12685 return (1); 12686 } 12687 12688 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12689 "vpi_logi_cmpl_notify:%d %s. Fabric mode. " 12690 "Completing login. >", 12691 vpip->VPI, 12692 emlxs_vpi_state_xlate(vpip->state)); 12693 12694 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL, 12695 0, 0, 0); 12696 12697 if (rval) { 12698 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12699 "vpi_logi_cmpl_notify:%d %s rval=%d.", 12700 vpip->VPI, 12701 emlxs_vpi_state_xlate(vpip->state), 12702 rval); 12703 } 12704 12705 return (rval); 12706 } 12707 12708 if (hba->flag & FC_PT_TO_PT) { 12709 if (port->did == 0) { 12710 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12711 "vpi_logi_cmpl_notify:%d %s did=0. P2P mode. " 12712 "Wait for PLOGI compl.", 12713 vpip->VPI, 12714 emlxs_vpi_state_xlate(vpip->state)); 12715 12716 if (rpip->cmpl) { 12717 emlxs_rpi_deferred_cmpl(port, rpip, 0); 12718 } 12719 12720 /* Wait for P2P PLOGI completion to continue */ 12721 return (0); 12722 } 12723 12724 vpip->p2p_rpip = rpip; 12725 12726 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12727 "vpi_logi_cmpl_notify:%d %s. P2P mode. " 12728 "Completing login. >", 12729 vpip->VPI, 12730 emlxs_vpi_state_xlate(vpip->state)); 12731 12732 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_CMPL, 12733 0, 0, 0); 12734 12735 if (rval) { 12736 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12737 "vpi_logi_cmpl_notify:%d %s rval=%d.", 12738 vpip->VPI, 12739 emlxs_vpi_state_xlate(vpip->state), 12740 rval); 12741 } 12742 12743 return (rval); 12744 } 12745 12746 return (1); 12747 12748 } /* emlxs_vpi_logi_cmpl_notify() */ 12749 12750 12751 extern uint32_t 12752 emlxs_vpi_logi_failed_notify(emlxs_port_t *port, emlxs_buf_t *sbp) 12753 { 12754 emlxs_hba_t *hba = HBA; 12755 VPIobj_t *vpip = port->vpip; 12756 RPIobj_t *rpip = vpip->fabric_rpip; 12757 uint32_t rval = 0; 12758 emlxs_deferred_cmpl_t *cmpl; 12759 12760 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12761 return (1); 12762 } 12763 12764 mutex_enter(&EMLXS_FCF_LOCK); 12765 12766 if (vpip->state != VPI_STATE_LOGI) { 12767 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12768 "vpi_logi_failed_notify:%d %s. " 12769 "Invalid state.", 12770 vpip->VPI, 12771 emlxs_vpi_state_xlate(vpip->state)); 12772 12773 /* Fabric logo is implied */ 12774 emlxs_vpi_logo_handler(port, vpip); 12775 12776 mutex_exit(&EMLXS_FCF_LOCK); 12777 12778 return (1); 12779 } 12780 12781 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12782 "vpi_logi_failed_notify:%d %s. " 12783 "Failing login. >", 12784 vpip->VPI, 12785 emlxs_vpi_state_xlate(vpip->state)); 12786 12787 /* For safety */ 12788 if (rpip->cmpl) { 12789 emlxs_rpi_deferred_cmpl(port, rpip, 1); 12790 } 12791 12792 if (sbp) { 12793 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 12794 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 12795 12796 cmpl->port = port; 12797 cmpl->arg1 = (void *)sbp; 12798 cmpl->arg2 = 0; 12799 cmpl->arg3 = 0; 12800 12801 rpip->cmpl = cmpl; 12802 } 12803 12804 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGI_FAILED, 12805 FCF_REASON_OP_FAILED, 1, 0); 12806 12807 if (rval && rpip->cmpl) { 12808 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 12809 rpip->cmpl = 0; 12810 } 12811 12812 mutex_exit(&EMLXS_FCF_LOCK); 12813 return (rval); 12814 12815 } /* emlxs_vpi_logi_failed_notify() */ 12816 12817 12818 extern uint32_t 12819 emlxs_vpi_logo_cmpl_notify(emlxs_port_t *port) 12820 { 12821 emlxs_hba_t *hba = HBA; 12822 VPIobj_t *vpip = port->vpip; 12823 uint32_t rval = 0; 12824 VFIobj_t *vfip; 12825 FCFIobj_t *fcfp; 12826 12827 if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) { 12828 return (1); 12829 } 12830 12831 mutex_enter(&EMLXS_FCF_LOCK); 12832 12833 /* Fabric logo is complete */ 12834 emlxs_vpi_logo_handler(port, vpip); 12835 12836 if ((vpip->state == VPI_STATE_OFFLINE) || 12837 (vpip->flag & EMLXS_VPI_OFFLINE_REQ)) { 12838 /* Already offline. Do nothing */ 12839 mutex_exit(&EMLXS_FCF_LOCK); 12840 return (0); 12841 } 12842 12843 vfip = vpip->vfip; 12844 fcfp = vfip->fcfp; 12845 12846 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12847 "vpi_logo_cmpl_notify:%d %s fcfi:%d vfi:%d. " 12848 "Offlining VPI:%d,%d >", 12849 vpip->VPI, 12850 emlxs_vpi_state_xlate(vpip->state), 12851 fcfp->fcf_index, 12852 vfip->VFI, 12853 vpip->index, vpip->VPI); 12854 12855 rval = emlxs_vpi_event(port, FCF_EVENT_VPI_OFFLINE, vpip); 12856 12857 mutex_exit(&EMLXS_FCF_LOCK); 12858 12859 return (rval); 12860 12861 } /* emlxs_vpi_logo_cmpl_notify() */ 12862 12863 12864 /*ARGSUSED*/ 12865 static uint32_t 12866 emlxs_vpi_logi_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12867 void *arg1) 12868 { 12869 emlxs_hba_t *hba = HBA; 12870 emlxs_buf_t *sbp = (emlxs_buf_t *)arg1; 12871 fc_packet_t *pkt = PRIV2PKT(sbp); 12872 uint32_t rval = 0; 12873 12874 if (vpip->state != VPI_STATE_LOGI) { 12875 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12876 "vpi_logi_action:%d %s:%s arg=%p. " 12877 "Invalid state. <", 12878 vpip->VPI, 12879 emlxs_vpi_state_xlate(vpip->state), 12880 emlxs_fcf_event_xlate(evt), arg1); 12881 return (1); 12882 } 12883 12884 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 12885 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12886 "vpi_logi_action:%d. Offline requested.", 12887 vpip->VPI); 12888 12889 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12890 return (rval); 12891 } 12892 12893 if (vpip->flag & EMLXS_VPI_LOGI) { 12894 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 12895 "vpi_logi_action:%d flag=%x. LOGI already set.", 12896 vpip->VPI, vpip->flag); 12897 12898 /* Fabric logo is implied */ 12899 emlxs_vpi_logo_handler(port, vpip); 12900 } 12901 12902 /* Check if FC_PT_TO_PT is set */ 12903 if (hba->flag & FC_PT_TO_PT) { 12904 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12905 "vpi_logi_action:%d logi_count=%d. FLOGI set. P2P. <", 12906 vpip->VPI, 12907 vpip->vfip->logi_count); 12908 12909 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI; 12910 12911 vpip->vfip->flogi_vpip = vpip; 12912 12913 if (vpip->vfip->logi_count == 0) { 12914 vpip->vfip->logi_count++; 12915 vpip->flag |= EMLXS_VPI_VFI_LOGI; 12916 } 12917 12918 return (0); 12919 } 12920 12921 /* Set login command based on vfi logi_count */ 12922 if (vpip->vfip->logi_count == 0) { 12923 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12924 "vpi_logi_action:%d logi_count=%d. FLOGI set. <", 12925 vpip->VPI, 12926 vpip->vfip->logi_count); 12927 12928 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FLOGI; 12929 12930 vpip->vfip->flogi_vpip = vpip; 12931 } else { 12932 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12933 "vpi_logi_action:%d logi_count=%d. FDISC set. <", 12934 vpip->VPI, 12935 vpip->vfip->logi_count); 12936 12937 *((uint32_t *)pkt->pkt_cmd) = (uint32_t)ELS_CMD_FDISC; 12938 } 12939 12940 vpip->vfip->logi_count++; 12941 vpip->flag |= EMLXS_VPI_VFI_LOGI; 12942 12943 return (0); 12944 12945 } /* emlxs_vpi_logi_action() */ 12946 12947 12948 /*ARGSUSED*/ 12949 static uint32_t 12950 emlxs_vpi_logi_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 12951 void *arg1) 12952 { 12953 emlxs_hba_t *hba = HBA; 12954 uint32_t rval = 0; 12955 12956 if (vpip->state != VPI_STATE_LOGI_FAILED) { 12957 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12958 "vpi_logi_failed_action:%d %s:%s arg=%p. " 12959 "Invalid state. <", 12960 vpip->VPI, 12961 emlxs_vpi_state_xlate(vpip->state), 12962 emlxs_fcf_event_xlate(evt), arg1); 12963 return (1); 12964 } 12965 12966 /* Fabric logo is implied */ 12967 emlxs_vpi_logo_handler(port, vpip); 12968 12969 if (hba->topology == TOPOLOGY_LOOP) { 12970 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12971 "vpi_logi_failed_action:%d. Private loop. " 12972 "Registering VPI.", 12973 vpip->VPI); 12974 12975 /* Update the VPI flogi_vpip pointer for loop */ 12976 /* because the vpi_logo_handler cleared it */ 12977 vpip->vfip->flogi_vpip = vpip; 12978 12979 bcopy((void *)&vpip->port->sparam, 12980 (void *)&vpip->fabric_rpip->sparam, 12981 sizeof (SERV_PARM)); 12982 12983 /* Update the VPI Fabric RPI */ 12984 vpip->fabric_rpip->sparam.cmn.w2.r_a_tov = 12985 LE_SWAP32((FF_DEF_RATOV * 1000)); 12986 12987 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 12988 FCF_REASON_EVENT, evt, arg1); 12989 return (rval); 12990 } 12991 12992 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 12993 "vpi_logi_failed_action:%d. Requesting offline.", 12994 vpip->VPI); 12995 12996 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 12997 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 12998 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 12999 13000 return (rval); 13001 13002 } /* emlxs_vpi_logi_failed_action() */ 13003 13004 13005 /*ARGSUSED*/ 13006 static uint32_t 13007 emlxs_vpi_logi_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13008 void *arg1) 13009 { 13010 emlxs_hba_t *hba = HBA; 13011 uint32_t rval = 0; 13012 char buffer1[64]; 13013 char buffer2[64]; 13014 uint32_t new_config = 0; 13015 13016 if (vpip->state != VPI_STATE_LOGI_CMPL) { 13017 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13018 "vpi_logi_cmpl_action:%d %s:%s arg=%p. " 13019 "Invalid state. <", 13020 vpip->VPI, 13021 emlxs_vpi_state_xlate(vpip->state), 13022 emlxs_fcf_event_xlate(evt), arg1); 13023 return (1); 13024 } 13025 13026 vpip->flag |= EMLXS_VPI_LOGI; 13027 13028 /* Check for new fabric */ 13029 if (port->prev_did) { 13030 if (SLI4_FCOE_MODE) { 13031 /* Check for FCF change */ 13032 if (((port->prev_did != port->did) || 13033 bcmp(&port->prev_fabric_sparam.portName, 13034 &port->fabric_sparam.portName, 8)) && 13035 emlxs_nport_count(port)) { 13036 new_config = 1; 13037 } 13038 } else { 13039 uint32_t old_topo; 13040 uint32_t new_topo; 13041 13042 /* Check for topology change (0=loop 1=fabric) */ 13043 old_topo = ((port->prev_did && 0xFFFF00) == 0)? 0:1; 13044 new_topo = ((port->did && 0xFFFF00) == 0)? 0:1; 13045 13046 if (old_topo != new_topo) { 13047 new_config = 1; 13048 13049 /* Check for any switch change */ 13050 } else if ((port->prev_did != port->did) || 13051 bcmp(&port->prev_fabric_sparam.portName, 13052 &port->fabric_sparam.portName, 8)) { 13053 new_config = 1; 13054 } 13055 } 13056 } 13057 13058 if (new_config) { 13059 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13060 "vpi_logi_cmpl_action:%d. " 13061 "New config. Offlining port.", 13062 vpip->VPI); 13063 13064 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13065 "vpi_logi_cmpl_action: prev_wwpn=%s wwpn=%s prev_did=%x " 13066 "did=%x.", 13067 emlxs_wwn_xlate(buffer1, sizeof (buffer1), 13068 (uint8_t *)&port->prev_fabric_sparam.portName), 13069 emlxs_wwn_xlate(buffer2, sizeof (buffer2), 13070 (uint8_t *)&port->fabric_sparam.portName), 13071 port->prev_did, port->did); 13072 13073 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13074 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13075 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13076 13077 return (rval); 13078 } 13079 13080 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13081 "vpi_logi_cmpl_action:%d. Registering.", 13082 vpip->VPI); 13083 13084 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 13085 FCF_REASON_EVENT, evt, arg1); 13086 13087 return (rval); 13088 13089 } /* emlxs_vpi_logi_cmpl_action() */ 13090 13091 13092 /*ARGSUSED*/ 13093 static uint32_t 13094 emlxs_vpi_logo_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13095 void *arg1) 13096 { 13097 emlxs_hba_t *hba = HBA; 13098 uint32_t rval = 0; 13099 13100 vpip->attempts++; 13101 13102 if (vpip->state != VPI_STATE_LOGO_FAILED) { 13103 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13104 "vpi_logo_failed_action:%d %s:%s arg=%p attempt=%d. " 13105 "Invalid state. <", 13106 vpip->VPI, 13107 emlxs_vpi_state_xlate(vpip->state), 13108 emlxs_fcf_event_xlate(evt), arg1, 13109 vpip->attempts); 13110 return (1); 13111 } 13112 13113 if (hba->state <= FC_LINK_DOWN) { 13114 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13115 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.", 13116 vpip->VPI, 13117 vpip->attempts); 13118 13119 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13120 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13121 } else if (vpip->attempts >= 3) { 13122 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13123 "vpi_logo_failed_action:%d attempt=%d. Logo cmpl.", 13124 vpip->VPI, 13125 vpip->attempts); 13126 13127 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13128 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13129 } else { 13130 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13131 "vpi_logo_failed_action:%d attempt=%d. Logging out.", 13132 vpip->VPI, 13133 vpip->attempts); 13134 13135 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO, 13136 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13137 } 13138 13139 return (rval); 13140 13141 } /* emlxs_vpi_logo_failed_action() */ 13142 13143 13144 /*ARGSUSED*/ 13145 static uint32_t 13146 emlxs_vpi_logo_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13147 void *arg1) 13148 { 13149 emlxs_hba_t *hba = HBA; 13150 emlxs_port_t *vport = vpip->port; 13151 uint32_t rval = 0; 13152 uint32_t did; 13153 uint32_t sid; 13154 fc_packet_t *pkt; 13155 ELS_PKT *els; 13156 13157 if (vpip->state != VPI_STATE_LOGO) { 13158 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13159 "vpi_logo_action:%d %s:%s arg=%p. " 13160 "Invalid state. <", 13161 vpip->VPI, 13162 emlxs_vpi_state_xlate(vpip->state), 13163 emlxs_fcf_event_xlate(evt), arg1); 13164 return (1); 13165 } 13166 13167 if (!(vpip->flag & EMLXS_VPI_LOGI)) { 13168 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13169 "vpi_logo_action:%d. No login. Skipping LOGO.", 13170 vpip->VPI); 13171 13172 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13173 FCF_REASON_EVENT, evt, arg1); 13174 return (rval); 13175 } 13176 13177 if (!(hba->flag & FC_ONLINE_MODE) && 13178 !(hba->flag & FC_OFFLINING_MODE)) { 13179 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13180 "vpi_logo_action:%d. HBA offline. Skipping LOGO.", 13181 vpip->VPI); 13182 13183 /* Fabric logo is implied */ 13184 emlxs_vpi_logo_handler(port, vpip); 13185 13186 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13187 FCF_REASON_EVENT, evt, arg1); 13188 return (rval); 13189 } 13190 13191 if (SLI4_FC_MODE) { 13192 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13193 "vpi_logo_action:%d. FC mode. Skipping LOGO.", 13194 vpip->VPI); 13195 13196 /* Fabric logo is implied */ 13197 emlxs_vpi_logo_handler(port, vpip); 13198 13199 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13200 FCF_REASON_EVENT, evt, arg1); 13201 return (rval); 13202 } 13203 13204 if (vpip->prev_state != VPI_STATE_LOGO_FAILED) { 13205 vpip->attempts = 0; 13206 } 13207 13208 did = FABRIC_DID; 13209 sid = (vport->did)? vport->did:vport->prev_did; 13210 13211 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13212 "vpi_logo_action:%d attempts=%d sid=%x did=%x. Sending LOGO. <", 13213 vpip->VPI, 13214 vpip->attempts, 13215 sid, did); 13216 13217 pkt = emlxs_pkt_alloc(vport, 13218 (sizeof (uint32_t) + sizeof (LOGO)), 13219 (sizeof (uint32_t) + sizeof (LOGO)), 0, KM_NOSLEEP); 13220 13221 if (!pkt) { 13222 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED, 13223 FCF_REASON_NO_PKT, 0, arg1); 13224 13225 return (rval); 13226 } 13227 13228 pkt->pkt_tran_type = FC_PKT_EXCHANGE; 13229 pkt->pkt_timeout = (2 * hba->fc_ratov); 13230 13231 /* Build the fc header */ 13232 pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(did); 13233 pkt->pkt_cmd_fhdr.r_ctl = 13234 R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL; 13235 pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(sid); 13236 pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS; 13237 pkt->pkt_cmd_fhdr.f_ctl = 13238 F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE; 13239 pkt->pkt_cmd_fhdr.seq_id = 0; 13240 pkt->pkt_cmd_fhdr.df_ctl = 0; 13241 pkt->pkt_cmd_fhdr.seq_cnt = 0; 13242 pkt->pkt_cmd_fhdr.ox_id = 0xffff; 13243 pkt->pkt_cmd_fhdr.rx_id = 0xffff; 13244 pkt->pkt_cmd_fhdr.ro = 0; 13245 13246 /* Build the command */ 13247 els = (ELS_PKT *)pkt->pkt_cmd; 13248 els->elsCode = 0x05; 13249 els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id; 13250 bcopy((uint8_t *)&vport->wwpn, 13251 (uint8_t *)&els->un.logo.portName, 8); 13252 13253 /* Send the pkt now */ 13254 rval = emlxs_pkt_send(pkt, 0); 13255 if (rval != FC_SUCCESS) { 13256 /* Free the pkt */ 13257 emlxs_pkt_free(pkt); 13258 13259 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_FAILED, 13260 FCF_REASON_SEND_FAILED, rval, arg1); 13261 13262 return (rval); 13263 } 13264 13265 /* For now we will send and forget */ 13266 rval = emlxs_vpi_state(port, vpip, VPI_STATE_LOGO_CMPL, 13267 FCF_REASON_EVENT, evt, arg1); 13268 13269 return (rval); 13270 13271 } /* emlxs_vpi_logo_action() */ 13272 13273 13274 /*ARGSUSED*/ 13275 static uint32_t 13276 emlxs_vpi_logo_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13277 void *arg1) 13278 { 13279 uint32_t rval = 0; 13280 13281 if (vpip->state != VPI_STATE_LOGO_CMPL) { 13282 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13283 "vpi_logo_cmpl_action:%d %s:%s arg=%p. " 13284 "Invalid state. <", 13285 vpip->VPI, 13286 emlxs_vpi_state_xlate(vpip->state), 13287 emlxs_fcf_event_xlate(evt), arg1); 13288 return (1); 13289 } 13290 13291 /* Fabric logo is complete */ 13292 emlxs_vpi_logo_handler(port, vpip); 13293 13294 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13295 "vpi_logo_cmpl_action:%d attempts=%d. Offline RPI's.", 13296 vpip->VPI, 13297 vpip->attempts); 13298 13299 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13300 FCF_REASON_EVENT, evt, arg1); 13301 13302 return (rval); 13303 13304 } /* emlxs_vpi_logo_cmpl_action() */ 13305 13306 13307 /*ARGSUSED*/ 13308 static uint32_t 13309 emlxs_vpi_unreg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13310 void *arg1) 13311 { 13312 uint32_t rval = 0; 13313 13314 vpip->attempts++; 13315 13316 if (vpip->state != VPI_STATE_UNREG_FAILED) { 13317 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13318 "vpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 13319 "Invalid state. <", 13320 vpip->VPI, 13321 emlxs_vpi_state_xlate(vpip->state), 13322 emlxs_fcf_event_xlate(evt), arg1, 13323 vpip->attempts); 13324 return (1); 13325 } 13326 13327 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 13328 (vpip->attempts >= 3)) { 13329 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13330 "vpi_unreg_failed_action:%d attempt=%d. Unreg cmpl.", 13331 vpip->VPI, 13332 vpip->attempts); 13333 13334 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 13335 13336 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13337 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13338 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL, 13339 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13340 } else { 13341 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13342 "vpi_unreg_failed_action:%d attempt=%d. Unregistering.", 13343 vpip->VPI, 13344 vpip->attempts); 13345 13346 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG, 13347 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13348 } 13349 13350 return (rval); 13351 13352 } /* emlxs_vpi_unreg_failed_action() */ 13353 13354 13355 /*ARGSUSED*/ 13356 static uint32_t 13357 emlxs_vpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 13358 { 13359 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 13360 MAILBOX4 *mb4; 13361 VPIobj_t *vpip; 13362 13363 vpip = (VPIobj_t *)mbq->context; 13364 mb4 = (MAILBOX4 *)mbq; 13365 13366 mutex_enter(&EMLXS_FCF_LOCK); 13367 13368 if (vpip->state != VPI_STATE_UNREG) { 13369 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13370 "vpi_unreg_mbcmpl:%d state=%s.", 13371 vpip->VPI, 13372 emlxs_vpi_state_xlate(vpip->state)); 13373 13374 mutex_exit(&EMLXS_FCF_LOCK); 13375 return (0); 13376 } 13377 13378 if (mb4->mbxStatus) { 13379 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13380 "vpi_unreg_mbcmpl:%d failed. %s. >", 13381 vpip->VPI, 13382 emlxs_mb_xlate_status(mb4->mbxStatus)); 13383 13384 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13385 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 13386 13387 mutex_exit(&EMLXS_FCF_LOCK); 13388 return (0); 13389 } 13390 13391 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13392 "vpi_unreg_mbcmpl:%d. Unreg complete. >", 13393 vpip->VPI); 13394 13395 vpip->flag &= ~(EMLXS_VPI_REG | EMLXS_VPI_INIT); 13396 (void) emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_CMPL, 0, 0, 0); 13397 13398 mutex_exit(&EMLXS_FCF_LOCK); 13399 return (0); 13400 13401 } /* emlxs_vpi_unreg_mbcmpl() */ 13402 13403 13404 /*ARGSUSED*/ 13405 static uint32_t 13406 emlxs_vpi_unreg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13407 void *arg1) 13408 { 13409 emlxs_hba_t *hba = HBA; 13410 MAILBOX4 *mb4; 13411 MAILBOXQ *mbq; 13412 uint32_t rval = 0; 13413 13414 if (vpip->state != VPI_STATE_UNREG) { 13415 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13416 "vpi_unreg_action:%d %s:%s arg=%p. " 13417 "Invalid state. <", 13418 vpip->VPI, 13419 emlxs_vpi_state_xlate(vpip->state), 13420 emlxs_fcf_event_xlate(evt), arg1); 13421 return (1); 13422 } 13423 13424 if ((vpip->rpi_online > vpip->rpi_paused) || 13425 (vpip->fabric_rpip->state != RPI_STATE_FREE)) { 13426 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13427 "vpi_unreg_action:%d rpi_online=%d,%d fstate=%x. " 13428 "Waiting for RPI's.", vpip->VPI, vpip->rpi_online, 13429 vpip->rpi_paused, vpip->fabric_rpip->state); 13430 13431 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PORT_OFFLINE, 13432 FCF_REASON_EVENT, evt, arg1); 13433 return (rval); 13434 } 13435 13436 if (!(vpip->flag & EMLXS_VPI_REG)) { 13437 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13438 "vpi_unreg_action:%d. Not registered. Skipping UNREG_VPI.", 13439 vpip->VPI); 13440 13441 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE, 13442 FCF_REASON_EVENT, evt, arg1); 13443 return (rval); 13444 } 13445 13446 if (vpip->flag & EMLXS_VPI_PAUSE_REQ) { 13447 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13448 "vpi_unreg_action:%d rpi_online=%d,%d. Pausing.", 13449 vpip->VPI, 13450 vpip->rpi_online, vpip->rpi_paused); 13451 13452 rval = emlxs_vpi_state(port, vpip, VPI_STATE_PAUSED, 13453 FCF_REASON_EVENT, evt, arg1); 13454 return (rval); 13455 } 13456 13457 if (vpip->prev_state != VPI_STATE_UNREG_FAILED) { 13458 vpip->attempts = 0; 13459 } 13460 13461 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13462 "vpi_unreg_action:%d attempts=%d. Sending UNREG_VPI. <", 13463 vpip->VPI, 13464 vpip->attempts); 13465 13466 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 13467 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13468 FCF_REASON_NO_MBOX, 0, arg1); 13469 13470 return (rval); 13471 } 13472 mb4 = (MAILBOX4*)mbq; 13473 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 13474 13475 mbq->nonembed = NULL; 13476 mbq->mbox_cmpl = emlxs_vpi_unreg_mbcmpl; 13477 mbq->context = (void *)vpip; 13478 mbq->port = (void *)vpip->port; 13479 13480 mb4->un.varUnRegVPI4.ii = 0; /* index is a VPI */ 13481 mb4->un.varUnRegVPI4.index = vpip->VPI; 13482 mb4->mbxCommand = MBX_UNREG_VPI; 13483 mb4->mbxOwner = OWN_HOST; 13484 13485 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 13486 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 13487 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 13488 13489 rval = emlxs_vpi_state(port, vpip, VPI_STATE_UNREG_FAILED, 13490 FCF_REASON_SEND_FAILED, rval, arg1); 13491 13492 return (rval); 13493 } 13494 13495 return (0); 13496 13497 } /* emlxs_vpi_unreg_action() */ 13498 13499 13500 /*ARGSUSED*/ 13501 static uint32_t 13502 emlxs_vpi_unreg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13503 void *arg1) 13504 { 13505 uint32_t rval = 0; 13506 13507 if (vpip->state != VPI_STATE_UNREG_CMPL) { 13508 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13509 "vpi_unreg_cmpl_action:%d %s:%s arg=%p. " 13510 "Invalid state. <", 13511 vpip->VPI, 13512 emlxs_vpi_state_xlate(vpip->state), 13513 emlxs_fcf_event_xlate(evt), arg1); 13514 return (1); 13515 } 13516 13517 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13518 "vpi_unreg_cmpl_action:%d attempts=%d. Going offline.", 13519 vpip->VPI, 13520 vpip->attempts); 13521 13522 rval = emlxs_vpi_state(port, vpip, VPI_STATE_OFFLINE, 13523 FCF_REASON_EVENT, evt, arg1); 13524 13525 return (rval); 13526 13527 } /* emlxs_vpi_unreg_cmpl_action() */ 13528 13529 13530 /*ARGSUSED*/ 13531 static uint32_t 13532 emlxs_vpi_reg_failed_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13533 void *arg1) 13534 { 13535 uint32_t rval = 0; 13536 13537 vpip->attempts++; 13538 13539 if (vpip->state != VPI_STATE_REG_FAILED) { 13540 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13541 "vpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 13542 "Invalid state. <", 13543 vpip->VPI, 13544 emlxs_vpi_state_xlate(vpip->state), 13545 emlxs_fcf_event_xlate(evt), arg1, 13546 vpip->attempts); 13547 return (1); 13548 } 13549 13550 if ((vpip->reason == FCF_REASON_SEND_FAILED) || 13551 (vpip->attempts >= 3)) { 13552 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13553 "vpi_reg_failed_action:%d attempt=%d reason=%x. Reg cmpl.", 13554 vpip->VPI, 13555 vpip->attempts, 13556 vpip->reason); 13557 13558 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13559 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13560 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL, 13561 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13562 } else { 13563 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13564 "vpi_reg_failed_action:%d attempt=%d. Registering.", 13565 vpip->VPI, 13566 vpip->attempts); 13567 13568 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG, 13569 FCF_REASON_OP_FAILED, vpip->attempts, arg1); 13570 } 13571 13572 return (rval); 13573 13574 } /* emlxs_vpi_reg_failed_action() */ 13575 13576 13577 /*ARGSUSED*/ 13578 static uint32_t 13579 emlxs_vpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 13580 { 13581 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 13582 MAILBOX4 *mb4; 13583 VPIobj_t *vpip; 13584 13585 vpip = (VPIobj_t *)mbq->context; 13586 mb4 = (MAILBOX4 *)mbq; 13587 13588 mutex_enter(&EMLXS_FCF_LOCK); 13589 13590 if (vpip->state != VPI_STATE_REG) { 13591 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13592 "vpi_reg_mbcmpl:%d state=%s.", 13593 vpip->VPI, 13594 emlxs_vpi_state_xlate(vpip->state)); 13595 13596 mutex_exit(&EMLXS_FCF_LOCK); 13597 return (0); 13598 } 13599 13600 if (mb4->mbxStatus) { 13601 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13602 "vpi_reg_mbcmpl:%d failed. %s. >", 13603 vpip->VPI, 13604 emlxs_mb_xlate_status(mb4->mbxStatus)); 13605 13606 if (mb4->mbxStatus == MBXERR_DID_INCONSISTENT) { 13607 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13608 } 13609 13610 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13611 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 13612 13613 mutex_exit(&EMLXS_FCF_LOCK); 13614 return (0); 13615 } 13616 13617 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13618 "vpi_reg_mbcmpl:%d. Reg complete. >", 13619 vpip->VPI); 13620 13621 vpip->flag |= EMLXS_VPI_REG; 13622 (void) emlxs_vpi_state(port, vpip, VPI_STATE_REG_CMPL, 13623 0, 0, 0); 13624 13625 mutex_exit(&EMLXS_FCF_LOCK); 13626 return (0); 13627 13628 } /* emlxs_vpi_reg_mbcmpl() */ 13629 13630 13631 /*ARGSUSED*/ 13632 static uint32_t 13633 emlxs_vpi_reg_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13634 void *arg1) 13635 { 13636 emlxs_hba_t *hba = HBA; 13637 uint32_t *wwpn; 13638 MAILBOX *mb; 13639 MAILBOXQ *mbq; 13640 uint32_t rval = 0; 13641 13642 if (vpip->state != VPI_STATE_REG) { 13643 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13644 "vpi_reg_action:%d %s:%s arg=%p. " 13645 "Invalid state. <", 13646 vpip->VPI, 13647 emlxs_vpi_state_xlate(vpip->state), 13648 emlxs_fcf_event_xlate(evt), arg1); 13649 return (1); 13650 } 13651 13652 if (vpip->prev_state != VPI_STATE_REG_FAILED) { 13653 vpip->attempts = 0; 13654 } 13655 13656 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13657 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13658 "vpi_reg_action:%d attempts=%d. Offline requested.", 13659 vpip->VPI, 13660 vpip->attempts); 13661 13662 rval = emlxs_vpi_offline_handler(port, vpip, 0); 13663 return (rval); 13664 } 13665 13666 if (!(vpip->vfip->flag & EMLXS_VFI_REG)) { 13667 /* We can't register the VPI until our VFI is registered */ 13668 13669 /* If this is the flogi_vpip, then we can skip the REG_VPI. */ 13670 /* REG_VPI will be performed later during REG_VFI */ 13671 if (vpip == vpip->vfip->flogi_vpip) { 13672 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13673 "vpi_reg_action:%d. flogi_vpi. Skipping REG_VPI.", 13674 vpip->VPI); 13675 13676 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE, 13677 FCF_REASON_EVENT, evt, arg1); 13678 13679 return (rval); 13680 } 13681 13682 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13683 "vpi_reg_action:%d attempts=%d. VFI not registered. " 13684 "Offlining.", 13685 vpip->VPI, 13686 vpip->attempts); 13687 13688 vpip->flag &= ~EMLXS_VPI_REQ_MASK; 13689 vpip->flag |= EMLXS_VPI_OFFLINE_REQ; 13690 rval = emlxs_vpi_offline_handler(port, vpip, 0); 13691 return (rval); 13692 } 13693 13694 if (vpip->flag & EMLXS_VPI_REG) { 13695 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13696 "vpi_reg_action:%d attempts=%d. Updating REG_VPI. <", 13697 vpip->VPI, 13698 vpip->attempts); 13699 } else { 13700 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13701 "vpi_reg_action:%d attempts=%d. Sending REG_VPI. <", 13702 vpip->VPI, 13703 vpip->attempts); 13704 } 13705 13706 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 13707 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13708 FCF_REASON_NO_MBOX, 0, arg1); 13709 13710 return (rval); 13711 } 13712 mb = (MAILBOX*)mbq; 13713 bzero((void *) mb, MAILBOX_CMD_BSIZE); 13714 13715 mbq->nonembed = NULL; 13716 mbq->mbox_cmpl = emlxs_vpi_reg_mbcmpl; 13717 mbq->context = (void *)vpip; 13718 mbq->port = (void *)vpip->port; 13719 13720 mb->un.varRegVpi.vfi = vpip->vfip->VFI; 13721 mb->un.varRegVpi.upd = (vpip->flag & EMLXS_VPI_REG)? 1:0; 13722 13723 wwpn = (uint32_t *)&port->wwpn; 13724 mb->un.varRegVpi.portname[0] = BE_SWAP32(*wwpn); 13725 wwpn++; 13726 mb->un.varRegVpi.portname[1] = BE_SWAP32(*wwpn); 13727 13728 mb->un.varRegVpi.vpi = vpip->VPI; 13729 mb->un.varRegVpi.sid = vpip->port->did; 13730 mb->mbxCommand = MBX_REG_VPI; 13731 mb->mbxOwner = OWN_HOST; 13732 13733 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 13734 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 13735 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 13736 13737 rval = emlxs_vpi_state(port, vpip, VPI_STATE_REG_FAILED, 13738 FCF_REASON_SEND_FAILED, rval, arg1); 13739 13740 return (rval); 13741 } 13742 13743 return (0); 13744 13745 } /* emlxs_vpi_reg_action() */ 13746 13747 13748 /*ARGSUSED*/ 13749 static uint32_t 13750 emlxs_vpi_reg_cmpl_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13751 void *arg1) 13752 { 13753 uint32_t rval = 0; 13754 13755 if (vpip->state != VPI_STATE_REG_CMPL) { 13756 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13757 "vpi_reg_cmpl_action:%d %s:%s arg=%p. " 13758 "Invalid state. <", 13759 vpip->VPI, 13760 emlxs_vpi_state_xlate(vpip->state), 13761 emlxs_fcf_event_xlate(evt), arg1); 13762 return (1); 13763 } 13764 13765 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13766 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13767 "vpi_reg_cmpl_action:%d attempts=%d. Offline requested.", 13768 vpip->VPI, 13769 vpip->attempts); 13770 13771 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13772 return (rval); 13773 } 13774 13775 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13776 "vpi_reg_cmpl_action:%d attempts=%d. Going online.", 13777 vpip->VPI, 13778 vpip->attempts); 13779 13780 rval = emlxs_vpi_state(port, vpip, VPI_STATE_ONLINE, 13781 FCF_REASON_EVENT, evt, arg1); 13782 13783 return (rval); 13784 13785 } /* emlxs_vpi_reg_cmpl_action() */ 13786 13787 13788 /*ARGSUSED*/ 13789 static uint32_t 13790 emlxs_vpi_online_action(emlxs_port_t *port, VPIobj_t *vpip, uint32_t evt, 13791 void *arg1) 13792 { 13793 uint32_t rval = 0; 13794 13795 if (vpip->state != VPI_STATE_ONLINE) { 13796 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13797 "vpi_online_action:%d %s:%s arg=%p. " 13798 "Invalid state. <", 13799 vpip->VPI, 13800 emlxs_vpi_state_xlate(vpip->state), 13801 emlxs_fcf_event_xlate(evt), arg1); 13802 return (1); 13803 } 13804 13805 vpip->flag &= ~EMLXS_VPI_ONLINE_REQ; 13806 13807 if (vpip->flag & EMLXS_VPI_OFFLINE_REQ) { 13808 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13809 "vpi_online_action:%d attempts=%d. Offline requested.", 13810 vpip->VPI, 13811 vpip->attempts); 13812 13813 rval = emlxs_vpi_offline_handler(port, vpip, arg1); 13814 return (rval); 13815 } 13816 13817 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 13818 "vpi_online_action:%d. VPI online. Notifying VFI:%d >", 13819 vpip->VPI, 13820 vpip->vfip->VFI); 13821 13822 /* Notify VFI */ 13823 rval = emlxs_vfi_event(port, FCF_EVENT_VPI_ONLINE, vpip); 13824 13825 return (rval); 13826 13827 } /* emlxs_vpi_online_action() */ 13828 13829 13830 /* ************************************************************************** */ 13831 /* RPI */ 13832 /* ************************************************************************** */ 13833 13834 static char * 13835 emlxs_rpi_state_xlate(uint32_t state) 13836 { 13837 static char buffer[32]; 13838 uint32_t i; 13839 uint32_t count; 13840 13841 count = sizeof (emlxs_rpi_state_table) / sizeof (emlxs_table_t); 13842 for (i = 0; i < count; i++) { 13843 if (state == emlxs_rpi_state_table[i].code) { 13844 return (emlxs_rpi_state_table[i].string); 13845 } 13846 } 13847 13848 (void) snprintf(buffer, sizeof (buffer), "state=0x%x", state); 13849 return (buffer); 13850 13851 } /* emlxs_rpi_state_xlate() */ 13852 13853 13854 static uint32_t 13855 emlxs_rpi_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 13856 void *arg1) 13857 { 13858 uint32_t rval = 0; 13859 uint32_t(*func) (emlxs_port_t *, RPIobj_t *, uint32_t, void *); 13860 uint32_t index; 13861 uint32_t events; 13862 uint16_t state; 13863 13864 /* Convert event to action table index */ 13865 switch (evt) { 13866 case FCF_EVENT_STATE_ENTER: 13867 index = 0; 13868 break; 13869 case FCF_EVENT_RPI_ONLINE: 13870 index = 1; 13871 break; 13872 case FCF_EVENT_RPI_OFFLINE: 13873 index = 2; 13874 break; 13875 case FCF_EVENT_RPI_PAUSE: 13876 index = 3; 13877 break; 13878 case FCF_EVENT_RPI_RESUME: 13879 index = 4; 13880 break; 13881 default: 13882 return (1); 13883 } 13884 13885 events = RPI_ACTION_EVENTS; 13886 state = rpip->state; 13887 13888 index += (state * events); 13889 func = (uint32_t(*) (emlxs_port_t *, RPIobj_t *, uint32_t, void *)) 13890 emlxs_rpi_action_table[index]; 13891 13892 if (!func) { 13893 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13894 "rpi_action:%d %s:%s arg=%p. No action. <", 13895 rpip->RPI, 13896 emlxs_rpi_state_xlate(rpip->state), 13897 emlxs_fcf_event_xlate(evt), arg1); 13898 13899 return (1); 13900 } 13901 13902 rval = (func)(port, rpip, evt, arg1); 13903 13904 return (rval); 13905 13906 } /* emlxs_rpi_action() */ 13907 13908 13909 static uint32_t 13910 emlxs_rpi_event(emlxs_port_t *port, uint32_t evt, 13911 void *arg1) 13912 { 13913 RPIobj_t *rpip = NULL; 13914 uint32_t rval = 0; 13915 13916 /* Filter events and acquire fcfi context */ 13917 switch (evt) { 13918 case FCF_EVENT_RPI_ONLINE: 13919 case FCF_EVENT_RPI_OFFLINE: 13920 case FCF_EVENT_RPI_PAUSE: 13921 case FCF_EVENT_RPI_RESUME: 13922 rpip = (RPIobj_t *)arg1; 13923 13924 if (!rpip) { 13925 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13926 "rpi_event: %s arg=%p. Null RPI found. <", 13927 emlxs_fcf_event_xlate(evt), arg1); 13928 13929 return (1); 13930 } 13931 13932 break; 13933 13934 default: 13935 return (1); 13936 } 13937 13938 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_event_msg, 13939 "rpi_event:%d %s:%s arg=%p", 13940 rpip->RPI, 13941 emlxs_rpi_state_xlate(rpip->state), 13942 emlxs_fcf_event_xlate(evt), arg1); 13943 13944 rval = emlxs_rpi_action(port, rpip, evt, arg1); 13945 13946 return (rval); 13947 13948 } /* emlxs_rpi_event() */ 13949 13950 13951 /*ARGSUSED*/ 13952 static uint32_t 13953 emlxs_rpi_state(emlxs_port_t *port, RPIobj_t *rpip, uint16_t state, 13954 uint16_t reason, uint32_t explain, void *arg1) 13955 { 13956 uint32_t rval = 0; 13957 13958 if (state >= RPI_ACTION_STATES) { 13959 return (1); 13960 } 13961 13962 if ((rpip->state == state) && 13963 (reason != FCF_REASON_REENTER)) { 13964 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 13965 "rpi_state:%d %s:%s:0x%x arg=%p. State not changed. <", 13966 rpip->RPI, 13967 emlxs_rpi_state_xlate(rpip->state), 13968 emlxs_fcf_reason_xlate(reason), 13969 explain, arg1); 13970 return (1); 13971 } 13972 13973 if (!reason) { 13974 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13975 "rpi_state:%d %s-->%s arg=%p", 13976 rpip->RPI, 13977 emlxs_rpi_state_xlate(rpip->state), 13978 emlxs_rpi_state_xlate(state), arg1); 13979 } else if (reason == FCF_REASON_EVENT) { 13980 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13981 "rpi_state:%d %s-->%s:%s:%s arg=%p", 13982 rpip->RPI, 13983 emlxs_rpi_state_xlate(rpip->state), 13984 emlxs_rpi_state_xlate(state), 13985 emlxs_fcf_reason_xlate(reason), 13986 emlxs_fcf_event_xlate(explain), arg1); 13987 } else if (explain) { 13988 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13989 "rpi_state:%d %s-->%s:%s:0x%x arg=%p", 13990 rpip->RPI, 13991 emlxs_rpi_state_xlate(rpip->state), 13992 emlxs_rpi_state_xlate(state), 13993 emlxs_fcf_reason_xlate(reason), 13994 explain, arg1); 13995 } else { 13996 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_state_msg, 13997 "rpi_state:%d %s-->%s:%s arg=%p", 13998 rpip->RPI, 13999 emlxs_rpi_state_xlate(rpip->state), 14000 emlxs_rpi_state_xlate(state), 14001 emlxs_fcf_reason_xlate(reason), arg1); 14002 } 14003 14004 rpip->prev_state = rpip->state; 14005 rpip->prev_reason = rpip->reason; 14006 rpip->state = state; 14007 rpip->reason = reason; 14008 14009 rval = emlxs_rpi_action(port, rpip, FCF_EVENT_STATE_ENTER, arg1); 14010 14011 return (rval); 14012 14013 } /* emlxs_rpi_state() */ 14014 14015 14016 static void 14017 emlxs_rpi_deferred_cmpl(emlxs_port_t *port, RPIobj_t *rpip, uint32_t status) 14018 { 14019 emlxs_hba_t *hba = HBA; 14020 emlxs_deferred_cmpl_t *cmpl; 14021 14022 if (!rpip->cmpl) { 14023 return; 14024 } 14025 14026 cmpl = rpip->cmpl; 14027 rpip->cmpl = 0; 14028 14029 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14030 "rpi_deferred_cmpl:%d. status=%x ...", 14031 port->vpip->VPI, 14032 status); 14033 14034 emlxs_thread_spawn(hba, emlxs_deferred_cmpl_thread, (void *)cmpl, 14035 (void*)(uintptr_t)status); 14036 14037 return; 14038 14039 } /* emlxs_rpi_deferred_cmpl() */ 14040 14041 14042 static void 14043 emlxs_rpi_idle_timer(emlxs_hba_t *hba) 14044 { 14045 emlxs_config_t *cfg = &CFG; 14046 RPIobj_t *rpip; 14047 uint32_t i; 14048 14049 /* This timer monitors for idle timeout of an RPI in a */ 14050 /* RESERVED state. */ 14051 /* This means that the RPI was reserved, but never registered. */ 14052 /* If the RPI sits for too long (~2 secs) in this state we free it */ 14053 rpip = hba->sli.sli4.RPIp; 14054 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14055 if (rpip->state != RPI_STATE_RESERVED) { 14056 continue; 14057 } 14058 14059 /* If RPI is active, then clear timer. */ 14060 if (rpip->xri_count) { 14061 rpip->idle_timer = 0; 14062 continue; 14063 } 14064 14065 /* If an F-port RPI is found idle, then free it. */ 14066 /* Since an F-port RPI is never registered after the login */ 14067 /* completes, it is safe to free it immediately. */ 14068 if ((rpip->did == FABRIC_DID) || 14069 (rpip->did == SCR_DID)) { 14070 goto free_it; 14071 } 14072 14073 /* Start idle timer if not already active */ 14074 if (!rpip->idle_timer) { 14075 rpip->idle_timer = hba->timer_tics + 14076 cfg[CFG_FCF_RPI_IDLE_TIMEOUT].current; 14077 } 14078 14079 /* Check for idle timeout */ 14080 if (hba->timer_tics < rpip->idle_timer) { 14081 continue; 14082 } 14083 rpip->idle_timer = 0; 14084 14085 free_it: 14086 (void) emlxs_rpi_state(rpip->vpip->port, rpip, RPI_STATE_FREE, 14087 FCF_REASON_UNUSED, 0, 0); 14088 } 14089 14090 return; 14091 14092 } /* emlxs_rpi_idle_timer() */ 14093 14094 14095 static RPIobj_t * 14096 emlxs_rpi_alloc(emlxs_port_t *port, uint32_t did) 14097 { 14098 emlxs_hba_t *hba = HBA; 14099 uint16_t i; 14100 RPIobj_t *rpip; 14101 14102 rpip = hba->sli.sli4.RPIp; 14103 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14104 /* To be consistent with SLI3, the RPI assignment */ 14105 /* starts with 1. ONLY one SLI4 HBA in the entire */ 14106 /* system will be sacrificed by one RPI and that */ 14107 /* is the one having RPI base equal 0. */ 14108 if ((rpip->state == RPI_STATE_FREE) && (rpip->RPI != 0)) { 14109 14110 bzero(rpip, sizeof (RPIobj_t)); 14111 rpip->index = i; 14112 rpip->RPI = emlxs_sli4_index_to_rpi(hba, i); 14113 rpip->vpip = port->vpip; 14114 rpip->did = did; 14115 14116 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14117 "rpi_alloc:%d. RPI allocated. >", 14118 rpip->RPI); 14119 14120 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESERVED, 14121 0, 0, 0); 14122 14123 return (rpip); 14124 } 14125 } 14126 14127 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14128 "rpi_alloc: Out of RPI objects."); 14129 14130 return (NULL); 14131 14132 } /* emlxs_rpi_alloc() */ 14133 14134 14135 /* Special routine for VPI object */ 14136 static void 14137 emlxs_rpi_alloc_fabric_rpi(emlxs_port_t *port) 14138 { 14139 RPIobj_t *fabric_rpip; 14140 14141 fabric_rpip = port->vpip->fabric_rpip; 14142 14143 if (fabric_rpip->state != RPI_STATE_FREE) { 14144 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14145 "rpi_alloc_fabric_rpi: Fabric RPI active:%s.", 14146 emlxs_rpi_state_xlate(fabric_rpip->state)); 14147 return; 14148 } 14149 14150 bzero(fabric_rpip, sizeof (RPIobj_t)); 14151 fabric_rpip->index = 0xffff; 14152 fabric_rpip->RPI = FABRIC_RPI; 14153 fabric_rpip->did = FABRIC_DID; 14154 fabric_rpip->vpip = port->vpip; 14155 14156 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14157 "rpi_alloc_fabric_rpi: Allocating Fabric RPI. >"); 14158 14159 (void) emlxs_rpi_state(port, fabric_rpip, RPI_STATE_RESERVED, 14160 0, 0, 0); 14161 14162 return; 14163 14164 } /* emlxs_rpi_alloc_fabric_rpi() */ 14165 14166 14167 static uint32_t 14168 emlxs_rpi_free(emlxs_port_t *port, RPIobj_t *rpip) 14169 { 14170 uint32_t rval = 0; 14171 14172 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14173 "rpi_free:%d did=%x. Freeing RPI. >", 14174 rpip->RPI, rpip->did); 14175 14176 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 14177 14178 return (rval); 14179 14180 } /* emlxs_rpi_free() */ 14181 14182 14183 extern RPIobj_t * 14184 emlxs_rpi_find(emlxs_port_t *port, uint16_t rpi) 14185 { 14186 emlxs_hba_t *hba = HBA; 14187 RPIobj_t *rpip; 14188 uint32_t index; 14189 14190 /* Special handling for Fabric RPI */ 14191 if (rpi == FABRIC_RPI) { 14192 return (port->vpip->fabric_rpip); 14193 } 14194 14195 index = emlxs_sli4_rpi_to_index(hba, rpi); 14196 14197 if (index >= hba->sli.sli4.RPICount) { 14198 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14199 "rpi_find:%d. RPI Invalid.", 14200 rpi); 14201 14202 return (NULL); 14203 } 14204 14205 rpip = &hba->sli.sli4.RPIp[index]; 14206 14207 if (rpip->state == RPI_STATE_FREE) { 14208 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14209 "rpi_find:%d RPI not active", 14210 rpi); 14211 14212 return (NULL); 14213 } 14214 14215 return (rpip); 14216 14217 } /* emlxs_rpi_find() */ 14218 14219 14220 static RPIobj_t * 14221 emlxs_rpi_find_did(emlxs_port_t *port, uint32_t did) 14222 { 14223 emlxs_hba_t *hba = HBA; 14224 RPIobj_t *rpip; 14225 RPIobj_t *rpip1; 14226 uint32_t i; 14227 14228 rpip1 = NULL; 14229 rpip = hba->sli.sli4.RPIp; 14230 for (i = 0; i < hba->sli.sli4.RPICount; i++, rpip++) { 14231 if (rpip->state == RPI_STATE_FREE) { 14232 continue; 14233 } 14234 14235 if ((rpip->did == did) && (rpip->vpip == port->vpip)) { 14236 rpip1 = rpip; 14237 break; 14238 } 14239 } 14240 14241 return (rpip1); 14242 14243 } /* emlxs_rpi_find_did() */ 14244 14245 14246 extern RPIobj_t * 14247 emlxs_rpi_reserve_notify(emlxs_port_t *port, uint32_t did, XRIobj_t *xrip) 14248 { 14249 emlxs_hba_t *hba = HBA; 14250 RPIobj_t *rpip; 14251 14252 /* xrip will be NULL for unsolicited BLS requests */ 14253 14254 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14255 return (NULL); 14256 } 14257 14258 mutex_enter(&EMLXS_FCF_LOCK); 14259 14260 rpip = emlxs_rpi_find_did(port, did); 14261 14262 if (!rpip) { 14263 rpip = emlxs_rpi_alloc(port, did); 14264 } 14265 14266 if (!rpip) { 14267 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14268 "rpi_reserve_notify: Unable to reserve an rpi. " 14269 "did=%x xri=%d.", 14270 did, ((xrip)?xrip->XRI:0)); 14271 14272 mutex_exit(&EMLXS_FCF_LOCK); 14273 return (NULL); 14274 } 14275 14276 /* Bind the XRI */ 14277 if (xrip) { 14278 mutex_enter(&EMLXS_FCTAB_LOCK); 14279 xrip->reserved_rpip = rpip; 14280 rpip->xri_count++; 14281 mutex_exit(&EMLXS_FCTAB_LOCK); 14282 } 14283 14284 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14285 "rpi_reserve_notify:%d did=%x xri=%d.", 14286 rpip->RPI, rpip->did, ((xrip)?xrip->XRI:0)); 14287 14288 mutex_exit(&EMLXS_FCF_LOCK); 14289 14290 return (rpip); 14291 14292 } /* emlxs_rpi_reserve_notify() */ 14293 14294 14295 extern RPIobj_t * 14296 emlxs_rpi_alloc_notify(emlxs_port_t *port, uint32_t did) 14297 { 14298 emlxs_hba_t *hba = HBA; 14299 RPIobj_t *rpip; 14300 14301 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14302 return (NULL); 14303 } 14304 14305 mutex_enter(&EMLXS_FCF_LOCK); 14306 14307 rpip = emlxs_rpi_alloc(port, did); 14308 14309 mutex_exit(&EMLXS_FCF_LOCK); 14310 14311 return (rpip); 14312 14313 } /* emlxs_rpi_alloc_notify() */ 14314 14315 14316 extern uint32_t 14317 emlxs_rpi_free_notify(emlxs_port_t *port, RPIobj_t *rpip) 14318 { 14319 emlxs_hba_t *hba = HBA; 14320 uint32_t rval = 0; 14321 14322 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14323 return (1); 14324 } 14325 14326 if (!rpip) { 14327 return (1); 14328 } 14329 14330 /* Fabric RPI will be handled automatically */ 14331 if (rpip->RPI == FABRIC_RPI) { 14332 return (1); 14333 } 14334 14335 mutex_enter(&EMLXS_FCF_LOCK); 14336 14337 rval = emlxs_rpi_free(port, rpip); 14338 14339 mutex_exit(&EMLXS_FCF_LOCK); 14340 14341 return (rval); 14342 14343 } /* emlxs_rpi_free_notify() */ 14344 14345 14346 extern uint32_t 14347 emlxs_rpi_pause_notify(emlxs_port_t *port, RPIobj_t *rpip) 14348 { 14349 emlxs_hba_t *hba = HBA; 14350 14351 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14352 return (1); 14353 } 14354 14355 if (!rpip) { 14356 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14357 "rpi_pause_notify: No RPI provided."); 14358 return (1); 14359 } 14360 14361 /* Fabric RPI will be handled automatically */ 14362 if (rpip->RPI == FABRIC_RPI) { 14363 return (1); 14364 } 14365 14366 mutex_enter(&EMLXS_FCF_LOCK); 14367 14368 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14369 "rpi_pause_notify:%d %s. Pausing RPI. >", 14370 rpip->RPI, 14371 emlxs_rpi_state_xlate(rpip->state)); 14372 14373 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_PAUSE, rpip); 14374 14375 mutex_exit(&EMLXS_FCF_LOCK); 14376 14377 return (0); 14378 14379 } /* emlxs_rpi_pause_notify() */ 14380 14381 14382 extern uint32_t 14383 emlxs_rpi_online_notify(emlxs_port_t *port, RPIobj_t *rpip, uint32_t did, 14384 SERV_PARM *sparam, void *arg1, void *arg2, void *arg3) 14385 { 14386 emlxs_hba_t *hba = HBA; 14387 emlxs_deferred_cmpl_t *cmpl; 14388 uint32_t allocated = 0; 14389 uint32_t rval = 0; 14390 14391 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14392 return (1); 14393 } 14394 14395 if ((did == port->did) && (!(hba->flag & FC_LOOPBACK_MODE))) { 14396 /* We never register our local port */ 14397 return (1); 14398 } 14399 14400 mutex_enter(&EMLXS_FCF_LOCK); 14401 14402 if (!rpip && (did == FABRIC_DID)) { 14403 /* We never online the Fabric DID other */ 14404 /* than the fabric_rpip */ 14405 rpip = port->vpip->fabric_rpip; 14406 } 14407 14408 if (!rpip) { 14409 rpip = emlxs_rpi_find_did(port, did); 14410 } 14411 14412 if (!rpip) { 14413 rpip = emlxs_rpi_alloc(port, did); 14414 allocated = 1; 14415 } 14416 14417 if (!rpip) { 14418 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14419 "rpi_online_notify: Unable to allocate an rpi. did=%x", 14420 did); 14421 14422 mutex_exit(&EMLXS_FCF_LOCK); 14423 return (1); 14424 } 14425 14426 /* Initialize RPI node info */ 14427 bcopy((void *)sparam, (void *)&rpip->sparam, sizeof (SERV_PARM)); 14428 14429 if (arg1 || arg2 || arg3) { 14430 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14431 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14432 14433 cmpl->port = port; 14434 cmpl->arg1 = arg1; 14435 cmpl->arg2 = arg2; 14436 cmpl->arg3 = arg3; 14437 14438 /* For safety */ 14439 if (rpip->cmpl) { 14440 emlxs_rpi_deferred_cmpl(port, rpip, 1); 14441 } 14442 14443 rpip->cmpl = cmpl; 14444 } 14445 14446 if ((rpip->RPI == FABRIC_RPI) || 14447 (hba->flag & FC_PT_TO_PT)) { 14448 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14449 "rpi_online_notify:%d %s. %s. Login cmpl.", 14450 rpip->RPI, 14451 emlxs_rpi_state_xlate(rpip->state), 14452 ((allocated)? "Allocated":"Updated")); 14453 14454 rval = emlxs_vpi_logi_cmpl_notify(port, rpip); 14455 14456 if (rval && rpip->cmpl) { 14457 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14458 rpip->cmpl = 0; 14459 } 14460 14461 mutex_exit(&EMLXS_FCF_LOCK); 14462 return (rval); 14463 } 14464 14465 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14466 "rpi_online_notify:%d %s. %s. Onlining RPI. >", 14467 rpip->RPI, 14468 emlxs_rpi_state_xlate(rpip->state), 14469 ((allocated)? "Allocated":"Updated")); 14470 14471 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_ONLINE, rpip); 14472 14473 if (rpip->cmpl) { 14474 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14475 "rpi_online_notify:%d %s. Deferred args not completed.", 14476 rpip->RPI, 14477 emlxs_rpi_state_xlate(rpip->state)); 14478 14479 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14480 rpip->cmpl = 0; 14481 14482 mutex_exit(&EMLXS_FCF_LOCK); 14483 return (1); 14484 } 14485 14486 mutex_exit(&EMLXS_FCF_LOCK); 14487 return (0); 14488 14489 } /* emlxs_rpi_online_notify() */ 14490 14491 14492 extern uint32_t 14493 emlxs_rpi_offline_notify(emlxs_port_t *port, RPIobj_t *rpip, 14494 void *arg1, void *arg2, void *arg3) 14495 { 14496 emlxs_hba_t *hba = HBA; 14497 emlxs_deferred_cmpl_t *cmpl; 14498 14499 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14500 return (1); 14501 } 14502 14503 if (!rpip) { 14504 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14505 "rpi_offline_notify: No RPI provided."); 14506 return (1); 14507 } 14508 14509 /* Fabric RPI will be handled automatically */ 14510 if (rpip->RPI == FABRIC_RPI) { 14511 return (1); 14512 } 14513 14514 mutex_enter(&EMLXS_FCF_LOCK); 14515 14516 if (arg1 || arg2 || arg3) { 14517 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14518 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14519 14520 cmpl->port = port; 14521 cmpl->arg1 = arg1; 14522 cmpl->arg2 = arg2; 14523 cmpl->arg3 = arg3; 14524 14525 rpip->cmpl = cmpl; 14526 } 14527 14528 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14529 "rpi_offline_notify:%d %s. Offlining RPI. >", 14530 rpip->RPI, 14531 emlxs_rpi_state_xlate(rpip->state)); 14532 14533 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip); 14534 14535 if (rpip->cmpl) { 14536 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14537 "rpi_offline_notify:%d %s. Deferred args not completed.", 14538 rpip->RPI, 14539 emlxs_rpi_state_xlate(rpip->state)); 14540 14541 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14542 rpip->cmpl = 0; 14543 14544 mutex_exit(&EMLXS_FCF_LOCK); 14545 return (1); 14546 } 14547 14548 mutex_exit(&EMLXS_FCF_LOCK); 14549 14550 return (0); 14551 14552 } /* emlxs_rpi_offline_notify() */ 14553 14554 14555 extern uint32_t 14556 emlxs_rpi_resume_notify(emlxs_port_t *port, RPIobj_t *rpip, emlxs_buf_t *sbp) 14557 { 14558 emlxs_hba_t *hba = HBA; 14559 emlxs_deferred_cmpl_t *cmpl; 14560 14561 if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) { 14562 return (1); 14563 } 14564 14565 if (!rpip) { 14566 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14567 "rpi_resume_notify: No RPI provided."); 14568 return (1); 14569 } 14570 14571 /* Fabric RPI will be handled automatically */ 14572 if (rpip->RPI == FABRIC_RPI) { 14573 return (1); 14574 } 14575 14576 mutex_enter(&EMLXS_FCF_LOCK); 14577 14578 if (rpip->state != RPI_STATE_PAUSED) { 14579 mutex_exit(&EMLXS_FCF_LOCK); 14580 return (1); 14581 } 14582 14583 if (sbp) { 14584 cmpl = (emlxs_deferred_cmpl_t *)kmem_zalloc( 14585 sizeof (emlxs_deferred_cmpl_t), KM_SLEEP); 14586 14587 cmpl->port = port; 14588 cmpl->arg1 = (void *)sbp; 14589 cmpl->arg2 = 0; 14590 cmpl->arg3 = 0; 14591 14592 rpip->cmpl = cmpl; 14593 } 14594 14595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14596 "rpi_resume_notify:%d %s. Resuming RPI. >", 14597 rpip->RPI, 14598 emlxs_rpi_state_xlate(rpip->state)); 14599 14600 (void) emlxs_rpi_event(port, FCF_EVENT_RPI_RESUME, rpip); 14601 14602 if (rpip->cmpl) { 14603 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14604 "rpi_resume_notify:%d %s. Deferred args not completed.", 14605 rpip->RPI, 14606 emlxs_rpi_state_xlate(rpip->state)); 14607 14608 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 14609 rpip->cmpl = 0; 14610 14611 mutex_exit(&EMLXS_FCF_LOCK); 14612 return (1); 14613 } 14614 14615 mutex_exit(&EMLXS_FCF_LOCK); 14616 14617 return (0); 14618 14619 } /* emlxs_rpi_resume_notify() */ 14620 14621 14622 /*ARGSUSED*/ 14623 static uint32_t 14624 emlxs_rpi_free_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14625 void *arg1) 14626 { 14627 emlxs_hba_t *hba = HBA; 14628 XRIobj_t *xrip; 14629 XRIobj_t *next_xrip; 14630 14631 if (rpip->state != RPI_STATE_FREE) { 14632 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14633 "rpi_free_action:%d %s:%s arg=%p. " 14634 "Invalid state. <", 14635 rpip->RPI, 14636 emlxs_rpi_state_xlate(rpip->state), 14637 emlxs_fcf_event_xlate(evt), arg1); 14638 return (1); 14639 } 14640 14641 if (rpip->cmpl) { 14642 emlxs_rpi_deferred_cmpl(port, rpip, 1); 14643 } 14644 14645 if (rpip->vpip->p2p_rpip == rpip) { 14646 rpip->vpip->p2p_rpip = NULL; 14647 } 14648 14649 /* Break node/RPI binding */ 14650 rw_enter(&port->node_rwlock, RW_WRITER); 14651 if (rpip->node) { 14652 rpip->node->rpip = NULL; 14653 rpip->node = NULL; 14654 } 14655 rw_exit(&port->node_rwlock); 14656 14657 /* Remove all XRIs under this RPI */ 14658 mutex_enter(&EMLXS_FCTAB_LOCK); 14659 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 14660 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 14661 next_xrip = xrip->_f; 14662 if (xrip->rpip == rpip) { 14663 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14664 "rpi_free_action:%d xri_count=%d. " 14665 "Removing XRI:%d iotag:%d.", 14666 rpip->RPI, 14667 rpip->xri_count, 14668 xrip->XRI, xrip->iotag); 14669 14670 rpip->xri_count--; 14671 xrip->rpip = NULL; 14672 } 14673 14674 if (xrip->reserved_rpip == rpip) { 14675 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14676 "rpi_free_action:%d xri_count=%d. " 14677 "Removing XRI:%d iotag:%d.", 14678 rpip->RPI, 14679 rpip->xri_count, 14680 xrip->XRI, xrip->iotag); 14681 14682 rpip->xri_count--; 14683 xrip->reserved_rpip = NULL; 14684 } 14685 14686 xrip = next_xrip; 14687 } 14688 mutex_exit(&EMLXS_FCTAB_LOCK); 14689 14690 if (rpip->xri_count) { 14691 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14692 "rpi_free_action:%d. xri_count=%d", 14693 rpip->RPI, 14694 rpip->xri_count); 14695 } 14696 14697 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14698 "rpi_free_action:%d flag=%x. RPI freed. <", 14699 rpip->RPI, 14700 rpip->flag); 14701 14702 rpip->flag = 0; 14703 14704 return (0); 14705 14706 } /* emlxs_rpi_free_action() */ 14707 14708 14709 /*ARGSUSED*/ 14710 static uint32_t 14711 emlxs_rpi_online_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14712 void *arg1) 14713 { 14714 uint32_t rval = 1; 14715 14716 if (evt != FCF_EVENT_RPI_ONLINE) { 14717 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14718 "rpi_online_evt_action:%d %s:%s arg=%p. " 14719 "Invalid event type. <", 14720 rpip->RPI, 14721 emlxs_rpi_state_xlate(rpip->state), 14722 emlxs_fcf_event_xlate(evt), arg1); 14723 return (1); 14724 } 14725 14726 switch (rpip->state) { 14727 case RPI_STATE_REG: 14728 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14729 "rpi_online_evt_action:%d flag=%x. Registering.", 14730 rpip->RPI, 14731 rpip->flag); 14732 14733 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG, 14734 FCF_REASON_REENTER, evt, arg1); 14735 break; 14736 14737 default: 14738 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14739 "rpi_online_evt_action:%d flag=%x. Registering.", 14740 rpip->RPI, 14741 rpip->flag); 14742 14743 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG, 14744 FCF_REASON_EVENT, evt, arg1); 14745 break; 14746 } 14747 14748 return (rval); 14749 14750 } /* emlxs_rpi_online_evt_action() */ 14751 14752 14753 /*ARGSUSED*/ 14754 static uint32_t 14755 emlxs_rpi_offline_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14756 void *arg1) 14757 { 14758 uint32_t rval = 1; 14759 14760 if (evt != FCF_EVENT_RPI_OFFLINE) { 14761 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14762 "rpi_offline_evt_action:%d %s:%s arg=%p. " 14763 "Invalid event type. <", 14764 rpip->RPI, 14765 emlxs_rpi_state_xlate(rpip->state), 14766 emlxs_fcf_event_xlate(evt), arg1); 14767 return (1); 14768 } 14769 14770 switch (rpip->state) { 14771 case RPI_STATE_RESERVED: 14772 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14773 "rpi_offline_evt_action:%d flag=%x. Freeing RPI.", 14774 rpip->RPI, 14775 rpip->flag); 14776 14777 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 14778 FCF_REASON_EVENT, evt, arg1); 14779 break; 14780 14781 case RPI_STATE_UNREG: 14782 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14783 "rpi_offline_evt_action:%d flag=%x. " 14784 "Already unregistering. <", 14785 rpip->RPI, 14786 rpip->flag); 14787 14788 break; 14789 14790 default: 14791 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14792 "rpi_offline_evt_action:%d flag=%x. Unregistering.", 14793 rpip->RPI, 14794 rpip->flag); 14795 14796 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 14797 FCF_REASON_EVENT, evt, arg1); 14798 break; 14799 14800 } 14801 14802 return (rval); 14803 14804 } /* emlxs_rpi_offline_evt_action() */ 14805 14806 14807 /*ARGSUSED*/ 14808 static uint32_t 14809 emlxs_rpi_pause_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14810 void *arg1) 14811 { 14812 VPIobj_t *vpip; 14813 uint32_t rval = 1; 14814 14815 vpip = rpip->vpip; 14816 14817 if (evt != FCF_EVENT_RPI_PAUSE) { 14818 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14819 "rpi_pause_evt_action:%d %s:%s arg=%p flag=%x. " 14820 "Invalid event type. <", 14821 rpip->RPI, 14822 emlxs_rpi_state_xlate(rpip->state), 14823 emlxs_fcf_event_xlate(evt), arg1, 14824 rpip->flag); 14825 return (1); 14826 } 14827 14828 switch (rpip->state) { 14829 case RPI_STATE_RESERVED: 14830 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14831 "rpi_pause_evt_action:%d flag=%x. Freeing RPI.", 14832 rpip->RPI, 14833 rpip->flag); 14834 14835 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 14836 FCF_REASON_EVENT, evt, arg1); 14837 break; 14838 14839 case RPI_STATE_UNREG: 14840 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14841 "rpi_pause_evt_action:%d flag=%x. Not online. <", 14842 rpip->RPI, 14843 rpip->flag); 14844 14845 break; 14846 14847 case RPI_STATE_PAUSED: 14848 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14849 "rpi_pause_evt_action:%d flag=%x. Already paused. <", 14850 rpip->RPI, 14851 rpip->flag); 14852 14853 break; 14854 14855 case RPI_STATE_REG: 14856 case RPI_STATE_ONLINE: 14857 case RPI_STATE_RESUME: 14858 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14859 "rpi_pause_evt_action:%d flag=%x. Pausing.", 14860 rpip->RPI, 14861 rpip->flag); 14862 14863 /* Don't pause an RPI, if the VPI is not pausing too */ 14864 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) { 14865 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14866 "rpi_pause_evt_action:%d rpi_online=%d,%d " 14867 "xri_count=%d. VPI:%d pause not requested. " 14868 "Unregistering.", rpip->RPI, 14869 vpip->rpi_online, vpip->rpi_paused, 14870 rpip->xri_count, vpip->VPI); 14871 14872 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 14873 FCF_REASON_EVENT, evt, arg1); 14874 break; 14875 } 14876 14877 rval = emlxs_rpi_state(port, rpip, RPI_STATE_PAUSED, 14878 FCF_REASON_EVENT, evt, arg1); 14879 break; 14880 14881 default: 14882 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14883 "rpi_pause_evt_action:%d flag=%x. <", 14884 rpip->RPI, 14885 rpip->flag); 14886 break; 14887 } 14888 14889 return (rval); 14890 14891 } /* emlxs_rpi_pause_evt_action() */ 14892 14893 14894 /*ARGSUSED*/ 14895 static uint32_t 14896 emlxs_rpi_resume_evt_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14897 void *arg1) 14898 { 14899 uint32_t rval = 1; 14900 14901 if (evt != FCF_EVENT_RPI_RESUME) { 14902 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 14903 "rpi_resume_evt_action:%d %s:%s arg=%p flag=%x. " 14904 "Invalid event type. <", 14905 rpip->RPI, 14906 emlxs_rpi_state_xlate(rpip->state), 14907 emlxs_fcf_event_xlate(evt), arg1, 14908 rpip->flag); 14909 return (1); 14910 } 14911 14912 switch (rpip->state) { 14913 case RPI_STATE_PAUSED: 14914 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14915 "rpi_resume_evt_action:%d flag=%x. Resuming.", 14916 rpip->RPI, 14917 rpip->flag); 14918 14919 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME, 14920 FCF_REASON_EVENT, evt, arg1); 14921 break; 14922 14923 default: 14924 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14925 "rpi_resume_evt_action:%d flag=%x. Not paused. <", 14926 rpip->RPI, 14927 rpip->flag); 14928 break; 14929 } 14930 14931 return (rval); 14932 14933 } /* emlxs_rpi_resume_evt_action() */ 14934 14935 14936 /*ARGSUSED*/ 14937 static uint32_t 14938 emlxs_rpi_reserved_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14939 void *arg1) 14940 { 14941 VPIobj_t *vpip; 14942 14943 vpip = rpip->vpip; 14944 14945 if (rpip->state != RPI_STATE_RESERVED) { 14946 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14947 "rpi_reserved_action:%d %s:%s arg=%p. " 14948 "Invalid state. <", 14949 rpip->RPI, 14950 emlxs_rpi_state_xlate(rpip->state), 14951 emlxs_fcf_event_xlate(evt), arg1); 14952 return (1); 14953 } 14954 14955 if (rpip->prev_state != RPI_STATE_FREE) { 14956 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14957 "rpi_reserved_action:%d %s:%s arg=%p. " 14958 "Invalid previous state. %s <", 14959 rpip->RPI, 14960 emlxs_rpi_state_xlate(rpip->state), 14961 emlxs_fcf_event_xlate(evt), arg1, 14962 emlxs_rpi_state_xlate(rpip->prev_state)); 14963 14964 return (1); 14965 } 14966 14967 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14968 "rpi_reserved_action:%d rpi_online=%d,%d. <", 14969 rpip->RPI, 14970 vpip->rpi_online, vpip->rpi_paused); 14971 14972 return (0); 14973 14974 } /* emlxs_rpi_reserved_action() */ 14975 14976 14977 /*ARGSUSED*/ 14978 static uint32_t 14979 emlxs_rpi_offline_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 14980 void *arg1) 14981 { 14982 uint32_t rval = 0; 14983 VPIobj_t *vpip; 14984 14985 vpip = rpip->vpip; 14986 14987 if (rpip->state != RPI_STATE_OFFLINE) { 14988 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 14989 "rpi_offline_action:%d %s:%s arg=%p. " 14990 "Invalid state. <", 14991 rpip->RPI, 14992 emlxs_rpi_state_xlate(rpip->state), 14993 emlxs_fcf_event_xlate(evt), arg1); 14994 return (1); 14995 } 14996 14997 if (rpip->flag & EMLXS_RPI_PAUSED) { 14998 rpip->flag &= ~EMLXS_RPI_PAUSED; 14999 15000 if (vpip->rpi_paused) { 15001 vpip->rpi_paused--; 15002 } 15003 } 15004 15005 if (rpip->flag & EMLXS_RPI_VPI) { 15006 rpip->flag &= ~EMLXS_RPI_VPI; 15007 15008 if (vpip->rpi_online) { 15009 vpip->rpi_online--; 15010 } 15011 15012 /* Added protection */ 15013 if (vpip->rpi_online < vpip->rpi_paused) { 15014 vpip->rpi_paused = vpip->rpi_online; 15015 } 15016 } 15017 15018 if (rpip->RPI == FABRIC_RPI) { 15019 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15020 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15021 "Fabric RPI offline. Freeing.", 15022 rpip->RPI, 15023 vpip->rpi_online, vpip->rpi_paused, 15024 rpip->xri_count); 15025 15026 /* Free RPI */ 15027 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 15028 15029 return (rval); 15030 } 15031 15032 if ((vpip->rpi_online == 0) || 15033 (vpip->rpi_online == vpip->rpi_paused)) { 15034 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15035 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15036 "RPI offline. " 15037 "Notifying VPI:%d >", 15038 rpip->RPI, 15039 vpip->rpi_online, vpip->rpi_paused, 15040 rpip->xri_count, 15041 vpip->VPI); 15042 15043 /* Notify VPI */ 15044 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_OFFLINE, rpip); 15045 15046 } else { 15047 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15048 "rpi_offline_action:%d rpi_online=%d,%d xri_count=%d. " 15049 "RPI offline. Freeing.", 15050 rpip->RPI, 15051 vpip->rpi_online, vpip->rpi_paused, 15052 rpip->xri_count); 15053 } 15054 15055 /* Free RPI */ 15056 rval = emlxs_rpi_state(port, rpip, RPI_STATE_FREE, 0, 0, 0); 15057 15058 return (rval); 15059 15060 } /* emlxs_rpi_offline_action() */ 15061 15062 15063 /*ARGSUSED*/ 15064 static uint32_t 15065 emlxs_rpi_paused_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15066 void *arg1) 15067 { 15068 VPIobj_t *vpip; 15069 uint32_t rval = 0; 15070 15071 vpip = rpip->vpip; 15072 15073 if (rpip->state != RPI_STATE_PAUSED) { 15074 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15075 "rpi_paused_action:%d %s:%s arg=%p. " 15076 "Invalid state. <", 15077 rpip->RPI, 15078 emlxs_rpi_state_xlate(rpip->state), 15079 emlxs_fcf_event_xlate(evt), arg1); 15080 return (1); 15081 } 15082 15083 if (!(vpip->flag & EMLXS_VPI_PAUSE_REQ)) { 15084 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15085 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15086 "VPI:%d pause not requested. Unregistering.", 15087 rpip->RPI, 15088 vpip->rpi_online, vpip->rpi_paused, 15089 rpip->xri_count, 15090 vpip->VPI); 15091 15092 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15093 FCF_REASON_EVENT, evt, arg1); 15094 return (rval); 15095 } 15096 15097 if (!(rpip->flag & EMLXS_RPI_PAUSED)) { 15098 rpip->flag |= EMLXS_RPI_PAUSED; 15099 vpip->rpi_paused++; 15100 } 15101 15102 /* Check if all RPI's have been paused for a VPI */ 15103 if (vpip->rpi_online == vpip->rpi_paused) { 15104 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15105 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15106 "RPI paused. " 15107 "Notifying VPI:%d >", 15108 rpip->RPI, 15109 vpip->rpi_online, vpip->rpi_paused, 15110 rpip->xri_count, 15111 vpip->VPI); 15112 15113 /* Notify VPI */ 15114 (void) emlxs_vpi_event(port, FCF_EVENT_RPI_PAUSE, rpip); 15115 15116 } else { 15117 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15118 "rpi_paused_action:%d rpi_online=%d,%d xri_count=%d. " 15119 "RPI paused. <", 15120 rpip->RPI, 15121 vpip->rpi_online, vpip->rpi_paused, 15122 rpip->xri_count); 15123 } 15124 15125 return (0); 15126 15127 } /* emlxs_rpi_paused_action() */ 15128 15129 15130 /*ARGSUSED*/ 15131 static uint32_t 15132 emlxs_rpi_unreg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15133 void *arg1) 15134 { 15135 uint32_t rval = 0; 15136 15137 rpip->attempts++; 15138 15139 if (rpip->state != RPI_STATE_UNREG_FAILED) { 15140 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15141 "rpi_unreg_failed_action:%d %s:%s arg=%p attempt=%d. " 15142 "Invalid state. <", 15143 rpip->RPI, 15144 emlxs_rpi_state_xlate(rpip->state), 15145 emlxs_fcf_event_xlate(evt), arg1, 15146 rpip->attempts); 15147 return (1); 15148 } 15149 15150 if ((rpip->reason == FCF_REASON_SEND_FAILED) || 15151 !(rpip->flag & EMLXS_RPI_REG)) { 15152 15153 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15154 "rpi_unreg_failed_action:%d reason=%x flag=%x. " 15155 "Going offline.", 15156 rpip->RPI, 15157 rpip->reason, 15158 rpip->flag); 15159 15160 rpip->flag &= ~EMLXS_RPI_REG; 15161 15162 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15163 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15164 } else { 15165 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15166 "rpi_unreg_failed_action:%d flag=%x. Going online.", 15167 rpip->RPI, 15168 rpip->flag); 15169 15170 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15171 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15172 } 15173 15174 return (rval); 15175 15176 } /* emlxs_rpi_unreg_failed_action() */ 15177 15178 15179 static void 15180 emlxs_rpi_unreg_handler(emlxs_port_t *port, RPIobj_t *rpip) 15181 { 15182 emlxs_hba_t *hba = HBA; 15183 VPIobj_t *vpip = rpip->vpip; 15184 emlxs_node_t *node = rpip->node; 15185 XRIobj_t *xrip; 15186 XRIobj_t *next_xrip; 15187 15188 /* Special handling for Fabric RPI */ 15189 if (rpip->RPI == FABRIC_RPI) { 15190 if (node) { 15191 (void) emlxs_tx_node_flush(port, node, 0, 0, 0); 15192 (void) emlxs_chipq_node_flush(port, 0, node, 0); 15193 } 15194 15195 /* Clear all reserved XRIs under this RPI */ 15196 mutex_enter(&EMLXS_FCTAB_LOCK); 15197 xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 15198 while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 15199 next_xrip = xrip->_f; 15200 /* We don't need to worry about xrip->reserved_rpip */ 15201 /* here because the Fabric RPI can never be reserved */ 15202 /* by an xri. */ 15203 if ((xrip->rpip == rpip) && 15204 (xrip->flag & EMLXS_XRI_RESERVED)) { 15205 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15206 "rpi_unreg_action:%d xri_count=%d. " 15207 "Unreserving XRI:%d iotag:%d.", 15208 rpip->RPI, 15209 rpip->xri_count, 15210 xrip->XRI, xrip->iotag); 15211 15212 (void) emlxs_sli4_unreserve_xri(port, 15213 xrip->XRI, 0); 15214 } 15215 xrip = next_xrip; 15216 } 15217 mutex_exit(&EMLXS_FCTAB_LOCK); 15218 } 15219 15220 rpip->flag &= ~EMLXS_RPI_REG; 15221 15222 if (rpip->flag & EMLXS_RPI_PAUSED) { 15223 rpip->flag &= ~EMLXS_RPI_PAUSED; 15224 15225 if (vpip->rpi_paused) { 15226 vpip->rpi_paused--; 15227 } 15228 } 15229 15230 if (rpip->flag & EMLXS_RPI_VPI) { 15231 rpip->flag &= ~EMLXS_RPI_VPI; 15232 15233 if (vpip->rpi_online) { 15234 vpip->rpi_online--; 15235 } 15236 15237 /* Added protection */ 15238 if (vpip->rpi_online < vpip->rpi_paused) { 15239 vpip->rpi_paused = vpip->rpi_online; 15240 } 15241 } 15242 15243 rw_enter(&port->node_rwlock, RW_WRITER); 15244 if (node) { 15245 rpip->node = NULL; 15246 node->rpip = NULL; 15247 } 15248 rw_exit(&port->node_rwlock); 15249 15250 if (node) { 15251 emlxs_node_rm(port, node); 15252 } 15253 15254 return; 15255 15256 } /* emlxs_rpi_unreg_handler() */ 15257 15258 15259 /*ARGSUSED*/ 15260 static uint32_t 15261 emlxs_rpi_unreg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15262 { 15263 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15264 MAILBOX4 *mb4; 15265 RPIobj_t *rpip; 15266 15267 mutex_enter(&EMLXS_FCF_LOCK); 15268 15269 rpip = (RPIobj_t *)mbq->context; 15270 15271 mb4 = (MAILBOX4 *)mbq; 15272 15273 if (rpip->state != RPI_STATE_UNREG) { 15274 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15275 "rpi_unreg_mbcmpl:%d state=%s. " 15276 "No longer in RPI_STATE_UNREG.", 15277 rpip->RPI, 15278 emlxs_rpi_state_xlate(rpip->state)); 15279 15280 mutex_exit(&EMLXS_FCF_LOCK); 15281 return (0); 15282 } 15283 15284 if (mb4->mbxStatus) { 15285 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15286 "rpi_unreg_mbcmpl:%d failed. %s. >", 15287 rpip->RPI, 15288 emlxs_mb_xlate_status(mb4->mbxStatus)); 15289 15290 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15291 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 15292 15293 mutex_exit(&EMLXS_FCF_LOCK); 15294 return (0); 15295 } 15296 15297 emlxs_rpi_unreg_handler(port, rpip); 15298 15299 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15300 "rpi_unreg_mbcmpl:%d Unregistered. Unreg complete. >", 15301 rpip->RPI); 15302 15303 (void) emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_CMPL, 15304 0, 0, 0); 15305 15306 mutex_exit(&EMLXS_FCF_LOCK); 15307 return (0); 15308 15309 } /* emlxs_rpi_unreg_mbcmpl() */ 15310 15311 15312 /*ARGSUSED*/ 15313 static uint32_t 15314 emlxs_rpi_unreg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15315 void *arg1) 15316 { 15317 emlxs_hba_t *hba = HBA; 15318 MAILBOX4 *mb4; 15319 MAILBOXQ *mbq; 15320 uint32_t rval = 0; 15321 VPIobj_t *vpip = rpip->vpip; 15322 15323 if (rpip->state != RPI_STATE_UNREG) { 15324 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15325 "rpi_unreg_action:%d %s:%s arg=%p. " 15326 "Invalid state. <", 15327 rpip->RPI, 15328 emlxs_rpi_state_xlate(rpip->state), 15329 emlxs_fcf_event_xlate(evt), arg1); 15330 return (1); 15331 } 15332 15333 if (!(rpip->flag & EMLXS_RPI_REG)) { 15334 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15335 "rpi_unreg_action:%d. Not registered. Going offline.", 15336 rpip->RPI); 15337 15338 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15339 FCF_REASON_EVENT, evt, arg1); 15340 15341 return (rval); 15342 } 15343 15344 if (rpip->prev_state != RPI_STATE_UNREG_FAILED) { 15345 rpip->attempts = 0; 15346 } 15347 15348 if (rpip->RPI == FABRIC_RPI) { 15349 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15350 "rpi_unreg_action:%d did=%x vpi=%d. Fabric RPI. " 15351 "Going offline.", 15352 rpip->RPI, 15353 rpip->did, 15354 rpip->vpip->VPI); 15355 15356 /* Don't send UNREG_RPI, but process it as if we did */ 15357 emlxs_rpi_unreg_handler(port, rpip); 15358 15359 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15360 FCF_REASON_EVENT, evt, arg1); 15361 15362 return (rval); 15363 } 15364 15365 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15366 "rpi_unreg_action:%d attempts=%d. Sending UNREG_RPI. <", 15367 rpip->RPI, 15368 rpip->attempts); 15369 15370 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15371 15372 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15373 FCF_REASON_NO_MBOX, 0, arg1); 15374 15375 return (rval); 15376 } 15377 mb4 = (MAILBOX4*)mbq; 15378 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15379 15380 mbq->nonembed = NULL; 15381 mbq->mbox_cmpl = emlxs_rpi_unreg_mbcmpl; 15382 mbq->context = (void *)rpip; 15383 mbq->port = (void *)port; 15384 15385 mb4->mbxCommand = MBX_UNREG_RPI; 15386 mb4->mbxOwner = OWN_HOST; 15387 mb4->un.varUnregLogin.rpi = rpip->RPI; 15388 mb4->un.varUnregLogin.vpi = vpip->VPI; 15389 15390 if (rpip->cmpl) { 15391 mbq->sbp = rpip->cmpl->arg1; 15392 mbq->ubp = rpip->cmpl->arg2; 15393 mbq->iocbq = rpip->cmpl->arg3; 15394 } 15395 15396 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15397 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15398 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15399 15400 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG_FAILED, 15401 FCF_REASON_SEND_FAILED, rval, arg1); 15402 15403 return (rval); 15404 } 15405 15406 if (rpip->cmpl) { 15407 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15408 rpip->cmpl = 0; 15409 } 15410 15411 return (0); 15412 15413 } /* emlxs_rpi_unreg_action() */ 15414 15415 15416 /*ARGSUSED*/ 15417 static uint32_t 15418 emlxs_rpi_unreg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15419 void *arg1) 15420 { 15421 uint32_t rval = 0; 15422 15423 if (rpip->state != RPI_STATE_UNREG_CMPL) { 15424 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15425 "rpi_unreg_cmpl_action:%d %s:%s arg=%p. " 15426 "Invalid state. <", 15427 rpip->RPI, 15428 emlxs_rpi_state_xlate(rpip->state), 15429 emlxs_fcf_event_xlate(evt), arg1); 15430 return (1); 15431 } 15432 15433 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15434 "rpi_unreg_cmpl_action:%d flag=%x. Going offline.", 15435 rpip->RPI, 15436 rpip->flag); 15437 15438 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15439 FCF_REASON_EVENT, evt, arg1); 15440 15441 return (rval); 15442 15443 } /* emlxs_rpi_unreg_cmpl_action() */ 15444 15445 15446 /*ARGSUSED*/ 15447 static uint32_t 15448 emlxs_rpi_reg_failed_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15449 void *arg1) 15450 { 15451 uint32_t rval = 0; 15452 15453 rpip->attempts++; 15454 15455 if (rpip->state != RPI_STATE_REG_FAILED) { 15456 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15457 "rpi_reg_failed_action:%d %s:%s arg=%p attempt=%d. " 15458 "Invalid state. <", 15459 rpip->RPI, 15460 emlxs_rpi_state_xlate(rpip->state), 15461 emlxs_fcf_event_xlate(evt), arg1, 15462 rpip->attempts); 15463 return (1); 15464 } 15465 15466 if ((rpip->reason == FCF_REASON_SEND_FAILED) || 15467 !(rpip->flag & EMLXS_RPI_REG)) { 15468 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15469 "rpi_reg_failed_action:%d reason=%x flag=%x. " 15470 "Going offline.", 15471 rpip->RPI, 15472 rpip->reason, 15473 rpip->flag); 15474 15475 rpip->flag &= ~EMLXS_RPI_REG; 15476 15477 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15478 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15479 } else { 15480 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15481 "rpi_reg_failed_action:%d flag=%x. Unregistering", 15482 rpip->RPI, 15483 rpip->flag); 15484 15485 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15486 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15487 } 15488 15489 return (rval); 15490 15491 } /* emlxs_rpi_reg_failed_action() */ 15492 15493 15494 static uint32_t 15495 emlxs_rpi_reg_handler(emlxs_port_t *port, RPIobj_t *rpip) 15496 { 15497 emlxs_hba_t *hba = HBA; 15498 VPIobj_t *vpip; 15499 emlxs_node_t *node; 15500 15501 vpip = rpip->vpip; 15502 15503 rpip->flag |= EMLXS_RPI_REG; 15504 15505 if (rpip->flag & EMLXS_RPI_PAUSED) { 15506 rpip->flag &= ~EMLXS_RPI_PAUSED; 15507 15508 if (vpip->rpi_paused) { 15509 vpip->rpi_paused--; 15510 } 15511 } 15512 15513 if (!(rpip->flag & EMLXS_RPI_VPI) && (rpip->RPI != FABRIC_RPI)) { 15514 rpip->flag |= EMLXS_RPI_VPI; 15515 vpip->rpi_online++; 15516 } 15517 15518 /* If private loop and this is fabric RPI, then exit now */ 15519 if (!(hba->flag & FC_FABRIC_ATTACHED) && (rpip->RPI == FABRIC_RPI)) { 15520 return (0); 15521 } 15522 15523 /* Create or update the node */ 15524 node = emlxs_node_create(port, rpip->did, rpip->RPI, &rpip->sparam); 15525 15526 if (!node) { 15527 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15528 "rpi_reg_handler:%d. Node create failed. Reg failed.", 15529 rpip->RPI); 15530 15531 return (FCF_REASON_NO_NODE); 15532 } 15533 15534 return (0); 15535 15536 } /* emlxs_rpi_reg_handler() */ 15537 15538 15539 /*ARGSUSED*/ 15540 static uint32_t 15541 emlxs_rpi_reg_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15542 { 15543 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15544 MAILBOX4 *mb4; 15545 RPIobj_t *rpip; 15546 emlxs_node_t *node; 15547 uint32_t rval = 0; 15548 15549 mutex_enter(&EMLXS_FCF_LOCK); 15550 15551 rpip = (RPIobj_t *)mbq->context; 15552 mb4 = (MAILBOX4 *)mbq; 15553 15554 if (rpip->state != RPI_STATE_REG) { 15555 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15556 "rpi_reg_mbcmpl:%d state=%s. No longer in RPI_STATE_REG.", 15557 rpip->RPI, 15558 emlxs_rpi_state_xlate(rpip->state)); 15559 15560 mutex_exit(&EMLXS_FCF_LOCK); 15561 return (0); 15562 } 15563 15564 if (mb4->mbxStatus) { 15565 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15566 "rpi_reg_mbcmpl:%d failed. %s. >", 15567 rpip->RPI, 15568 emlxs_mb_xlate_status(mb4->mbxStatus)); 15569 15570 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15571 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, 0); 15572 15573 mutex_exit(&EMLXS_FCF_LOCK); 15574 return (0); 15575 } 15576 15577 rval = emlxs_rpi_reg_handler(port, rpip); 15578 15579 if (rval) { 15580 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15581 "rpi_reg_mbcmpl:%d. Reg failed. >", 15582 rpip->RPI); 15583 15584 mb4->mbxStatus = MBX_FAILURE; 15585 15586 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15587 rval, 0, 0); 15588 15589 mutex_exit(&EMLXS_FCF_LOCK); 15590 return (0); 15591 } 15592 15593 node = rpip->node; 15594 15595 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15596 "rpi_reg_mbcmpl:%d Registered. Reg complete. >", 15597 rpip->RPI); 15598 15599 (void) emlxs_rpi_state(port, rpip, RPI_STATE_REG_CMPL, 0, 0, 0); 15600 15601 mutex_exit(&EMLXS_FCF_LOCK); 15602 15603 /* Needed for FCT trigger in emlxs_mb_deferred_cmpl */ 15604 if (mbq->sbp) { 15605 ((emlxs_buf_t *)mbq->sbp)->node = node; 15606 } 15607 15608 #ifdef DHCHAP_SUPPORT 15609 if (mbq->sbp || mbq->ubp) { 15610 if (emlxs_dhc_auth_start(port, node, (uint8_t *)mbq->sbp, 15611 (uint8_t *)mbq->ubp) == 0) { 15612 /* Auth started - auth completion will */ 15613 /* handle sbp and ubp now */ 15614 mbq->sbp = NULL; 15615 mbq->ubp = NULL; 15616 } 15617 } 15618 #endif /* DHCHAP_SUPPORT */ 15619 15620 return (0); 15621 15622 } /* emlxs_rpi_reg_mbcmpl() */ 15623 15624 15625 /*ARGSUSED*/ 15626 static uint32_t 15627 emlxs_rpi_reg_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15628 void *arg1) 15629 { 15630 emlxs_hba_t *hba = HBA; 15631 MAILBOX4 *mb4; 15632 MAILBOXQ *mbq; 15633 MATCHMAP *mp; 15634 uint32_t rval = 0; 15635 15636 if (rpip->state != RPI_STATE_REG) { 15637 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15638 "rpi_reg_action:%d %s:%s arg=%p. " 15639 "Invalid state. <", 15640 rpip->RPI, 15641 emlxs_rpi_state_xlate(rpip->state), 15642 emlxs_fcf_event_xlate(evt), arg1); 15643 return (1); 15644 } 15645 15646 if (rpip->RPI == FABRIC_RPI) { 15647 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15648 "rpi_reg_action:%d did=%x vpi=%d. Fabric RPI. " 15649 "Going online.", 15650 rpip->RPI, 15651 rpip->did, 15652 rpip->vpip->VPI); 15653 15654 /* Don't send REG_RPI, but process it as if we did */ 15655 rval = emlxs_rpi_reg_handler(port, rpip); 15656 15657 if (rval) { 15658 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15659 rval, 0, 0); 15660 15661 return (rval); 15662 } 15663 15664 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15665 FCF_REASON_EVENT, evt, arg1); 15666 15667 return (rval); 15668 } 15669 15670 if (rpip->prev_state != RPI_STATE_REG_FAILED) { 15671 rpip->attempts = 0; 15672 } 15673 15674 if (rpip->flag & EMLXS_RPI_REG) { 15675 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15676 "rpi_reg_action:%d attempts=%d. " 15677 "Updating REG_RPI. <", 15678 rpip->RPI, 15679 rpip->attempts); 15680 } else { 15681 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15682 "rpi_reg_action:%d attempts=%d. " 15683 "Sending REG_RPI. <", 15684 rpip->RPI, 15685 rpip->attempts); 15686 } 15687 15688 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15689 15690 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15691 FCF_REASON_NO_MBOX, 0, arg1); 15692 15693 return (rval); 15694 } 15695 15696 mb4 = (MAILBOX4*)mbq; 15697 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15698 15699 if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) { 15700 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15701 15702 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15703 FCF_REASON_NO_BUFFER, 0, arg1); 15704 15705 return (rval); 15706 } 15707 15708 mbq->bp = (void *)mp; 15709 mbq->nonembed = NULL; 15710 15711 mbq->mbox_cmpl = emlxs_rpi_reg_mbcmpl; 15712 mbq->context = (void *)rpip; 15713 mbq->port = (void *)port; 15714 15715 mb4->mbxCommand = MBX_REG_RPI; 15716 mb4->mbxOwner = OWN_HOST; 15717 15718 mb4->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM); 15719 mb4->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys); 15720 mb4->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys); 15721 mb4->un.varRegLogin.did = rpip->did; 15722 mb4->un.varWords[30] = 0; /* flags */ 15723 15724 mb4->un.varRegLogin.vpi = rpip->vpip->VPI; 15725 mb4->un.varRegLogin.rpi = rpip->RPI; 15726 mb4->un.varRegLogin.update = (rpip->flag & EMLXS_RPI_REG)? 1:0; 15727 15728 bcopy((void *)&rpip->sparam, (void *)mp->virt, sizeof (SERV_PARM)); 15729 15730 if (rpip->cmpl) { 15731 mbq->sbp = rpip->cmpl->arg1; 15732 mbq->ubp = rpip->cmpl->arg2; 15733 mbq->iocbq = rpip->cmpl->arg3; 15734 } 15735 15736 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15737 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15738 emlxs_mem_put(hba, MEM_BUF, (void *)mp); 15739 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15740 15741 rval = emlxs_rpi_state(port, rpip, RPI_STATE_REG_FAILED, 15742 FCF_REASON_SEND_FAILED, rval, arg1); 15743 15744 return (rval); 15745 } 15746 15747 if (rpip->cmpl) { 15748 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15749 rpip->cmpl = 0; 15750 } 15751 15752 return (0); 15753 15754 } /* emlxs_rpi_reg_action() */ 15755 15756 15757 /*ARGSUSED*/ 15758 static uint32_t 15759 emlxs_rpi_reg_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15760 void *arg1) 15761 { 15762 uint32_t rval = 0; 15763 15764 if (rpip->state != RPI_STATE_REG_CMPL) { 15765 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15766 "rpi_reg_cmpl_action:%d %s:%s arg=%p. " 15767 "Invalid state. <", 15768 rpip->RPI, 15769 emlxs_rpi_state_xlate(rpip->state), 15770 emlxs_fcf_event_xlate(evt), arg1); 15771 return (1); 15772 } 15773 15774 if (rpip->flag & EMLXS_RPI_REG) { 15775 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15776 "rpi_reg_cmpl_action:%d flag=%x. Going online.", 15777 rpip->RPI, 15778 rpip->flag); 15779 15780 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15781 FCF_REASON_EVENT, evt, arg1); 15782 } else { 15783 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15784 "rpi_reg_cmpl_action:%d flag=%x. Going offline.", 15785 rpip->RPI, 15786 rpip->flag); 15787 15788 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 15789 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15790 } 15791 15792 return (rval); 15793 15794 } /* emlxs_rpi_reg_cmpl_action() */ 15795 15796 15797 /*ARGSUSED*/ 15798 static uint32_t 15799 emlxs_rpi_resume_failed_action(emlxs_port_t *port, RPIobj_t *rpip, 15800 uint32_t evt, void *arg1) 15801 { 15802 uint32_t rval = 0; 15803 15804 rpip->attempts++; 15805 15806 if (rpip->state != RPI_STATE_RESUME_FAILED) { 15807 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15808 "rpi_resume_failed_action:%d %s:%s arg=%p attempt=%d. " 15809 "Invalid state. <", 15810 rpip->RPI, 15811 emlxs_rpi_state_xlate(rpip->state), 15812 emlxs_fcf_event_xlate(evt), arg1, 15813 rpip->attempts); 15814 return (1); 15815 } 15816 15817 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15818 "rpi_resume_failed_action:%d attempt=%d. Unregistering.", 15819 rpip->RPI, 15820 rpip->attempts); 15821 15822 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 15823 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 15824 15825 return (rval); 15826 15827 } /* emlxs_rpi_resume_failed_action() */ 15828 15829 15830 /*ARGSUSED*/ 15831 static void 15832 emlxs_rpi_resume_handler(emlxs_port_t *port, RPIobj_t *rpip) 15833 { 15834 if (rpip->flag & EMLXS_RPI_PAUSED) { 15835 rpip->flag &= ~EMLXS_RPI_PAUSED; 15836 15837 if (rpip->vpip->rpi_paused) { 15838 rpip->vpip->rpi_paused--; 15839 } 15840 } 15841 15842 return; 15843 15844 } /* emlxs_rpi_resume_handler() */ 15845 15846 15847 /*ARGSUSED*/ 15848 static uint32_t 15849 emlxs_rpi_resume_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq) 15850 { 15851 emlxs_port_t *port = (emlxs_port_t *)mbq->port; 15852 MAILBOX4 *mb4; 15853 RPIobj_t *rpip; 15854 15855 mutex_enter(&EMLXS_FCF_LOCK); 15856 15857 rpip = (RPIobj_t *)mbq->context; 15858 mb4 = (MAILBOX4 *)mbq; 15859 15860 if (rpip->state != RPI_STATE_RESUME) { 15861 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15862 "rpi_resume_mbcmpl:%d state=%s. " 15863 "No longer in RPI_STATE_RESUME.", 15864 rpip->RPI, 15865 emlxs_rpi_state_xlate(rpip->state)); 15866 15867 mutex_exit(&EMLXS_FCF_LOCK); 15868 return (0); 15869 } 15870 15871 if (mb4->mbxStatus) { 15872 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15873 "rpi_resume_mbcmpl:%d failed. %s. >", 15874 rpip->RPI, 15875 emlxs_mb_xlate_status(mb4->mbxStatus)); 15876 15877 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15878 FCF_REASON_MBOX_FAILED, mb4->mbxStatus, (void *)mbq->sbp); 15879 15880 mutex_exit(&EMLXS_FCF_LOCK); 15881 return (0); 15882 } 15883 15884 emlxs_rpi_resume_handler(port, rpip); 15885 15886 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15887 "rpi_resume_mbcmpl:%d Resumed. Resume complete. >", 15888 rpip->RPI); 15889 15890 (void) emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_CMPL, 0, 0, 0); 15891 15892 mutex_exit(&EMLXS_FCF_LOCK); 15893 15894 return (0); 15895 15896 } /* emlxs_rpi_resume_mbcmpl() */ 15897 15898 15899 /*ARGSUSED*/ 15900 static uint32_t 15901 emlxs_rpi_resume_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 15902 void *arg1) 15903 { 15904 emlxs_hba_t *hba = HBA; 15905 MAILBOX4 *mb4; 15906 MAILBOXQ *mbq; 15907 uint32_t rval = 0; 15908 15909 if (rpip->state != RPI_STATE_RESUME) { 15910 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 15911 "rpi_resume_action:%d %s:%s arg=%p. " 15912 "Invalid state. <", 15913 rpip->RPI, 15914 emlxs_rpi_state_xlate(rpip->state), 15915 emlxs_fcf_event_xlate(evt), arg1); 15916 return (1); 15917 } 15918 15919 if (!(rpip->flag & EMLXS_RPI_PAUSED)) { 15920 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15921 "rpi_resume_action:%d flag=%x. Not Paused. Going online.", 15922 rpip->RPI, rpip->flag); 15923 15924 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15925 FCF_REASON_EVENT, evt, arg1); 15926 15927 return (rval); 15928 } 15929 15930 if (rpip->RPI == FABRIC_RPI) { 15931 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15932 "rpi_resume_action:%d. Fabric RPI. " 15933 "Going online.", 15934 rpip->RPI); 15935 15936 /* Don't send RESUME_RPI, but process it as if we did */ 15937 emlxs_rpi_resume_handler(port, rpip); 15938 15939 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 15940 FCF_REASON_EVENT, evt, arg1); 15941 15942 return (rval); 15943 } 15944 15945 if (rpip->prev_state != RPI_STATE_RESUME_FAILED) { 15946 rpip->attempts = 0; 15947 } 15948 15949 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 15950 "rpi_resume_action:%d attempts=%d. Sending RESUME_RPI. <", 15951 rpip->RPI, 15952 rpip->attempts); 15953 15954 if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) { 15955 15956 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15957 FCF_REASON_NO_MBOX, 0, arg1); 15958 15959 return (rval); 15960 } 15961 mb4 = (MAILBOX4*)mbq; 15962 bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE); 15963 15964 mbq->nonembed = NULL; 15965 mbq->mbox_cmpl = emlxs_rpi_resume_mbcmpl; 15966 mbq->context = (void *)rpip; 15967 mbq->port = (void *)port; 15968 15969 mb4->mbxCommand = MBX_RESUME_RPI; 15970 mb4->mbxOwner = OWN_HOST; 15971 15972 mb4->un.varResumeRPI.EventTag = hba->link_event_tag; 15973 mb4->un.varResumeRPI.RPI = rpip->RPI; 15974 15975 if (rpip->cmpl) { 15976 mbq->sbp = rpip->cmpl->arg1; 15977 mbq->ubp = rpip->cmpl->arg2; 15978 mbq->iocbq = rpip->cmpl->arg3; 15979 } 15980 15981 rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0); 15982 if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) { 15983 emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 15984 15985 rval = emlxs_rpi_state(port, rpip, RPI_STATE_RESUME_FAILED, 15986 FCF_REASON_SEND_FAILED, rval, arg1); 15987 15988 return (rval); 15989 } 15990 15991 if (rpip->cmpl) { 15992 kmem_free(rpip->cmpl, sizeof (emlxs_deferred_cmpl_t)); 15993 rpip->cmpl = 0; 15994 } 15995 15996 return (0); 15997 15998 } /* emlxs_rpi_resume_action() */ 15999 16000 16001 static uint32_t 16002 emlxs_rpi_resume_cmpl_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 16003 void *arg1) 16004 { 16005 uint32_t rval = 0; 16006 16007 if (rpip->state != RPI_STATE_RESUME_CMPL) { 16008 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_error_msg, 16009 "rpi_resume_cmpl_action:%d %s:%s arg=%p. " 16010 "Invalid state. <", 16011 rpip->RPI, 16012 emlxs_rpi_state_xlate(rpip->state), 16013 emlxs_fcf_event_xlate(evt), arg1); 16014 return (1); 16015 } 16016 16017 if (rpip->flag & EMLXS_RPI_PAUSED) { 16018 if (rpip->flag & EMLXS_RPI_REG) { 16019 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16020 "rpi_reg_cmpl_action:%d flag=%x. Unregistering.", 16021 rpip->RPI, 16022 rpip->flag); 16023 16024 rval = emlxs_rpi_state(port, rpip, RPI_STATE_UNREG, 16025 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16026 } else { 16027 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16028 "rpi_reg_cmpl_action:%d flag=%x. Going offline.", 16029 rpip->RPI, 16030 rpip->flag); 16031 16032 rval = emlxs_rpi_state(port, rpip, RPI_STATE_OFFLINE, 16033 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16034 } 16035 } else { 16036 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16037 "rpi_resume_cmpl_action:%d flag=%x. Going online.", 16038 rpip->RPI, 16039 rpip->flag); 16040 16041 rval = emlxs_rpi_state(port, rpip, RPI_STATE_ONLINE, 16042 FCF_REASON_OP_FAILED, rpip->attempts, arg1); 16043 } 16044 16045 return (rval); 16046 16047 } /* emlxs_rpi_resume_cmpl_action() */ 16048 16049 16050 /*ARGSUSED*/ 16051 static uint32_t 16052 emlxs_rpi_online_action(emlxs_port_t *port, RPIobj_t *rpip, uint32_t evt, 16053 void *arg1) 16054 { 16055 emlxs_hba_t *hba = HBA; 16056 uint32_t rval = 0; 16057 RPIobj_t *p2p_rpip; 16058 16059 if (rpip->state != RPI_STATE_ONLINE) { 16060 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16061 "rpi_online_action:%d %s:%s arg=%p. " 16062 "Invalid state. <", 16063 rpip->RPI, 16064 emlxs_rpi_state_xlate(rpip->state), 16065 emlxs_fcf_event_xlate(evt), arg1); 16066 return (1); 16067 } 16068 16069 if (rpip->RPI == FABRIC_RPI) { 16070 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16071 "rpi_online_action:%d did=%x. Fabric RPI online. <", 16072 rpip->RPI, 16073 rpip->did, 16074 rpip->vpip->VPI); 16075 16076 /* Now register the p2p_rpip */ 16077 p2p_rpip = rpip->vpip->p2p_rpip; 16078 if (p2p_rpip) { 16079 rpip->vpip->p2p_rpip = NULL; 16080 16081 rval = emlxs_rpi_state(port, p2p_rpip, RPI_STATE_REG, 16082 FCF_REASON_EVENT, evt, arg1); 16083 } 16084 16085 EMLXS_STATE_CHANGE(hba, FC_READY); 16086 16087 if (rpip->cmpl) { 16088 emlxs_rpi_deferred_cmpl(port, rpip, 0); 16089 } 16090 16091 return (0); 16092 } 16093 16094 EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fcf_detail_msg, 16095 "rpi_online_action:%d did=%x. RPI online. Notifying VPI:%d. >", 16096 rpip->RPI, 16097 rpip->did, 16098 rpip->vpip->VPI); 16099 16100 /* Notify VPI */ 16101 rval = emlxs_vpi_event(port, FCF_EVENT_RPI_ONLINE, rpip); 16102 16103 return (rval); 16104 16105 } /* emlxs_rpi_online_action() */ 16106