1 /* 2 * Copyright (c) 2005-2010 Brocade Communications Systems, Inc. 3 * All rights reserved 4 * www.brocade.com 5 * 6 * Linux driver for Brocade Fibre Channel Host Bus Adapter. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License (GPL) Version 2 as 10 * published by the Free Software Foundation 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 */ 17 18 #include "bfad_drv.h" 19 #include "bfa_modules.h" 20 21 BFA_TRC_FILE(HAL, FCPIM); 22 23 /* 24 * BFA ITNIM Related definitions 25 */ 26 static void bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim); 27 28 #define BFA_ITNIM_FROM_TAG(_fcpim, _tag) \ 29 (((_fcpim)->itnim_arr + ((_tag) & ((_fcpim)->num_itnims - 1)))) 30 31 #define bfa_fcpim_additn(__itnim) \ 32 list_add_tail(&(__itnim)->qe, &(__itnim)->fcpim->itnim_q) 33 #define bfa_fcpim_delitn(__itnim) do { \ 34 WARN_ON(!bfa_q_is_on_q(&(__itnim)->fcpim->itnim_q, __itnim)); \ 35 bfa_itnim_update_del_itn_stats(__itnim); \ 36 list_del(&(__itnim)->qe); \ 37 WARN_ON(!list_empty(&(__itnim)->io_q)); \ 38 WARN_ON(!list_empty(&(__itnim)->io_cleanup_q)); \ 39 WARN_ON(!list_empty(&(__itnim)->pending_q)); \ 40 } while (0) 41 42 #define bfa_itnim_online_cb(__itnim) do { \ 43 if ((__itnim)->bfa->fcs) \ 44 bfa_cb_itnim_online((__itnim)->ditn); \ 45 else { \ 46 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ 47 __bfa_cb_itnim_online, (__itnim)); \ 48 } \ 49 } while (0) 50 51 #define bfa_itnim_offline_cb(__itnim) do { \ 52 if ((__itnim)->bfa->fcs) \ 53 bfa_cb_itnim_offline((__itnim)->ditn); \ 54 else { \ 55 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ 56 __bfa_cb_itnim_offline, (__itnim)); \ 57 } \ 58 } while (0) 59 60 #define bfa_itnim_sler_cb(__itnim) do { \ 61 if ((__itnim)->bfa->fcs) \ 62 bfa_cb_itnim_sler((__itnim)->ditn); \ 63 else { \ 64 bfa_cb_queue((__itnim)->bfa, &(__itnim)->hcb_qe, \ 65 __bfa_cb_itnim_sler, (__itnim)); \ 66 } \ 67 } while (0) 68 69 /* 70 * itnim state machine event 71 */ 72 enum bfa_itnim_event { 73 BFA_ITNIM_SM_CREATE = 1, /* itnim is created */ 74 BFA_ITNIM_SM_ONLINE = 2, /* itnim is online */ 75 BFA_ITNIM_SM_OFFLINE = 3, /* itnim is offline */ 76 BFA_ITNIM_SM_FWRSP = 4, /* firmware response */ 77 BFA_ITNIM_SM_DELETE = 5, /* deleting an existing itnim */ 78 BFA_ITNIM_SM_CLEANUP = 6, /* IO cleanup completion */ 79 BFA_ITNIM_SM_SLER = 7, /* second level error recovery */ 80 BFA_ITNIM_SM_HWFAIL = 8, /* IOC h/w failure event */ 81 BFA_ITNIM_SM_QRESUME = 9, /* queue space available */ 82 }; 83 84 /* 85 * BFA IOIM related definitions 86 */ 87 #define bfa_ioim_move_to_comp_q(__ioim) do { \ 88 list_del(&(__ioim)->qe); \ 89 list_add_tail(&(__ioim)->qe, &(__ioim)->fcpim->ioim_comp_q); \ 90 } while (0) 91 92 93 #define bfa_ioim_cb_profile_comp(__fcpim, __ioim) do { \ 94 if ((__fcpim)->profile_comp) \ 95 (__fcpim)->profile_comp(__ioim); \ 96 } while (0) 97 98 #define bfa_ioim_cb_profile_start(__fcpim, __ioim) do { \ 99 if ((__fcpim)->profile_start) \ 100 (__fcpim)->profile_start(__ioim); \ 101 } while (0) 102 103 /* 104 * IO state machine events 105 */ 106 enum bfa_ioim_event { 107 BFA_IOIM_SM_START = 1, /* io start request from host */ 108 BFA_IOIM_SM_COMP_GOOD = 2, /* io good comp, resource free */ 109 BFA_IOIM_SM_COMP = 3, /* io comp, resource is free */ 110 BFA_IOIM_SM_COMP_UTAG = 4, /* io comp, resource is free */ 111 BFA_IOIM_SM_DONE = 5, /* io comp, resource not free */ 112 BFA_IOIM_SM_FREE = 6, /* io resource is freed */ 113 BFA_IOIM_SM_ABORT = 7, /* abort request from scsi stack */ 114 BFA_IOIM_SM_ABORT_COMP = 8, /* abort from f/w */ 115 BFA_IOIM_SM_ABORT_DONE = 9, /* abort completion from f/w */ 116 BFA_IOIM_SM_QRESUME = 10, /* CQ space available to queue IO */ 117 BFA_IOIM_SM_SGALLOCED = 11, /* SG page allocation successful */ 118 BFA_IOIM_SM_SQRETRY = 12, /* sequence recovery retry */ 119 BFA_IOIM_SM_HCB = 13, /* bfa callback complete */ 120 BFA_IOIM_SM_CLEANUP = 14, /* IO cleanup from itnim */ 121 BFA_IOIM_SM_TMSTART = 15, /* IO cleanup from tskim */ 122 BFA_IOIM_SM_TMDONE = 16, /* IO cleanup from tskim */ 123 BFA_IOIM_SM_HWFAIL = 17, /* IOC h/w failure event */ 124 BFA_IOIM_SM_IOTOV = 18, /* ITN offline TOV */ 125 }; 126 127 128 /* 129 * BFA TSKIM related definitions 130 */ 131 132 /* 133 * task management completion handling 134 */ 135 #define bfa_tskim_qcomp(__tskim, __cbfn) do { \ 136 bfa_cb_queue((__tskim)->bfa, &(__tskim)->hcb_qe, __cbfn, (__tskim));\ 137 bfa_tskim_notify_comp(__tskim); \ 138 } while (0) 139 140 #define bfa_tskim_notify_comp(__tskim) do { \ 141 if ((__tskim)->notify) \ 142 bfa_itnim_tskdone((__tskim)->itnim); \ 143 } while (0) 144 145 146 enum bfa_tskim_event { 147 BFA_TSKIM_SM_START = 1, /* TM command start */ 148 BFA_TSKIM_SM_DONE = 2, /* TM completion */ 149 BFA_TSKIM_SM_QRESUME = 3, /* resume after qfull */ 150 BFA_TSKIM_SM_HWFAIL = 5, /* IOC h/w failure event */ 151 BFA_TSKIM_SM_HCB = 6, /* BFA callback completion */ 152 BFA_TSKIM_SM_IOS_DONE = 7, /* IO and sub TM completions */ 153 BFA_TSKIM_SM_CLEANUP = 8, /* TM cleanup on ITN offline */ 154 BFA_TSKIM_SM_CLEANUP_DONE = 9, /* TM abort completion */ 155 }; 156 157 /* 158 * forward declaration for BFA ITNIM functions 159 */ 160 static void bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim); 161 static bfa_boolean_t bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim); 162 static bfa_boolean_t bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim); 163 static void bfa_itnim_cleanp_comp(void *itnim_cbarg); 164 static void bfa_itnim_cleanup(struct bfa_itnim_s *itnim); 165 static void __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete); 166 static void __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete); 167 static void __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete); 168 static void bfa_itnim_iotov_online(struct bfa_itnim_s *itnim); 169 static void bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim); 170 static void bfa_itnim_iotov(void *itnim_arg); 171 static void bfa_itnim_iotov_start(struct bfa_itnim_s *itnim); 172 static void bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim); 173 static void bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim); 174 175 /* 176 * forward declaration of ITNIM state machine 177 */ 178 static void bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, 179 enum bfa_itnim_event event); 180 static void bfa_itnim_sm_created(struct bfa_itnim_s *itnim, 181 enum bfa_itnim_event event); 182 static void bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, 183 enum bfa_itnim_event event); 184 static void bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, 185 enum bfa_itnim_event event); 186 static void bfa_itnim_sm_online(struct bfa_itnim_s *itnim, 187 enum bfa_itnim_event event); 188 static void bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, 189 enum bfa_itnim_event event); 190 static void bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, 191 enum bfa_itnim_event event); 192 static void bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, 193 enum bfa_itnim_event event); 194 static void bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, 195 enum bfa_itnim_event event); 196 static void bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, 197 enum bfa_itnim_event event); 198 static void bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, 199 enum bfa_itnim_event event); 200 static void bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, 201 enum bfa_itnim_event event); 202 static void bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, 203 enum bfa_itnim_event event); 204 static void bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, 205 enum bfa_itnim_event event); 206 static void bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, 207 enum bfa_itnim_event event); 208 209 /* 210 * forward declaration for BFA IOIM functions 211 */ 212 static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim); 213 static bfa_boolean_t bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim); 214 static bfa_boolean_t bfa_ioim_send_abort(struct bfa_ioim_s *ioim); 215 static void bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim); 216 static void __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete); 217 static void __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete); 218 static void __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete); 219 static void __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete); 220 static void __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete); 221 static bfa_boolean_t bfa_ioim_is_abortable(struct bfa_ioim_s *ioim); 222 223 /* 224 * forward declaration of BFA IO state machine 225 */ 226 static void bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, 227 enum bfa_ioim_event event); 228 static void bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, 229 enum bfa_ioim_event event); 230 static void bfa_ioim_sm_active(struct bfa_ioim_s *ioim, 231 enum bfa_ioim_event event); 232 static void bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, 233 enum bfa_ioim_event event); 234 static void bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, 235 enum bfa_ioim_event event); 236 static void bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, 237 enum bfa_ioim_event event); 238 static void bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, 239 enum bfa_ioim_event event); 240 static void bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, 241 enum bfa_ioim_event event); 242 static void bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, 243 enum bfa_ioim_event event); 244 static void bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, 245 enum bfa_ioim_event event); 246 static void bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, 247 enum bfa_ioim_event event); 248 static void bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, 249 enum bfa_ioim_event event); 250 /* 251 * forward declaration for BFA TSKIM functions 252 */ 253 static void __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete); 254 static void __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete); 255 static bfa_boolean_t bfa_tskim_match_scope(struct bfa_tskim_s *tskim, 256 struct scsi_lun lun); 257 static void bfa_tskim_gather_ios(struct bfa_tskim_s *tskim); 258 static void bfa_tskim_cleanp_comp(void *tskim_cbarg); 259 static void bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim); 260 static bfa_boolean_t bfa_tskim_send(struct bfa_tskim_s *tskim); 261 static bfa_boolean_t bfa_tskim_send_abort(struct bfa_tskim_s *tskim); 262 static void bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim); 263 264 /* 265 * forward declaration of BFA TSKIM state machine 266 */ 267 static void bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, 268 enum bfa_tskim_event event); 269 static void bfa_tskim_sm_active(struct bfa_tskim_s *tskim, 270 enum bfa_tskim_event event); 271 static void bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, 272 enum bfa_tskim_event event); 273 static void bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, 274 enum bfa_tskim_event event); 275 static void bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, 276 enum bfa_tskim_event event); 277 static void bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, 278 enum bfa_tskim_event event); 279 static void bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, 280 enum bfa_tskim_event event); 281 /* 282 * BFA FCP Initiator Mode module 283 */ 284 285 /* 286 * Compute and return memory needed by FCP(im) module. 287 */ 288 static void 289 bfa_fcpim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len) 290 { 291 bfa_itnim_meminfo(cfg, km_len); 292 293 /* 294 * IO memory 295 */ 296 *km_len += cfg->fwcfg.num_ioim_reqs * 297 (sizeof(struct bfa_ioim_s) + sizeof(struct bfa_ioim_sp_s)); 298 299 /* 300 * task management command memory 301 */ 302 if (cfg->fwcfg.num_tskim_reqs < BFA_TSKIM_MIN) 303 cfg->fwcfg.num_tskim_reqs = BFA_TSKIM_MIN; 304 *km_len += cfg->fwcfg.num_tskim_reqs * sizeof(struct bfa_tskim_s); 305 } 306 307 308 static void 309 bfa_fcpim_attach(struct bfa_fcp_mod_s *fcp, void *bfad, 310 struct bfa_iocfc_cfg_s *cfg, struct bfa_pcidev_s *pcidev) 311 { 312 struct bfa_fcpim_s *fcpim = &fcp->fcpim; 313 struct bfa_s *bfa = fcp->bfa; 314 315 bfa_trc(bfa, cfg->drvcfg.path_tov); 316 bfa_trc(bfa, cfg->fwcfg.num_rports); 317 bfa_trc(bfa, cfg->fwcfg.num_ioim_reqs); 318 bfa_trc(bfa, cfg->fwcfg.num_tskim_reqs); 319 320 fcpim->fcp = fcp; 321 fcpim->bfa = bfa; 322 fcpim->num_itnims = cfg->fwcfg.num_rports; 323 fcpim->num_tskim_reqs = cfg->fwcfg.num_tskim_reqs; 324 fcpim->path_tov = cfg->drvcfg.path_tov; 325 fcpim->delay_comp = cfg->drvcfg.delay_comp; 326 fcpim->profile_comp = NULL; 327 fcpim->profile_start = NULL; 328 329 bfa_itnim_attach(fcpim); 330 bfa_tskim_attach(fcpim); 331 bfa_ioim_attach(fcpim); 332 } 333 334 static void 335 bfa_fcpim_iocdisable(struct bfa_fcp_mod_s *fcp) 336 { 337 struct bfa_fcpim_s *fcpim = &fcp->fcpim; 338 struct bfa_itnim_s *itnim; 339 struct list_head *qe, *qen; 340 341 /* Enqueue unused ioim resources to free_q */ 342 list_splice_tail_init(&fcpim->tskim_unused_q, &fcpim->tskim_free_q); 343 344 list_for_each_safe(qe, qen, &fcpim->itnim_q) { 345 itnim = (struct bfa_itnim_s *) qe; 346 bfa_itnim_iocdisable(itnim); 347 } 348 } 349 350 void 351 bfa_fcpim_path_tov_set(struct bfa_s *bfa, u16 path_tov) 352 { 353 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 354 355 fcpim->path_tov = path_tov * 1000; 356 if (fcpim->path_tov > BFA_FCPIM_PATHTOV_MAX) 357 fcpim->path_tov = BFA_FCPIM_PATHTOV_MAX; 358 } 359 360 u16 361 bfa_fcpim_path_tov_get(struct bfa_s *bfa) 362 { 363 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 364 365 return fcpim->path_tov / 1000; 366 } 367 368 #define bfa_fcpim_add_iostats(__l, __r, __stats) \ 369 (__l->__stats += __r->__stats) 370 371 void 372 bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *lstats, 373 struct bfa_itnim_iostats_s *rstats) 374 { 375 bfa_fcpim_add_iostats(lstats, rstats, total_ios); 376 bfa_fcpim_add_iostats(lstats, rstats, qresumes); 377 bfa_fcpim_add_iostats(lstats, rstats, no_iotags); 378 bfa_fcpim_add_iostats(lstats, rstats, io_aborts); 379 bfa_fcpim_add_iostats(lstats, rstats, no_tskims); 380 bfa_fcpim_add_iostats(lstats, rstats, iocomp_ok); 381 bfa_fcpim_add_iostats(lstats, rstats, iocomp_underrun); 382 bfa_fcpim_add_iostats(lstats, rstats, iocomp_overrun); 383 bfa_fcpim_add_iostats(lstats, rstats, iocomp_aborted); 384 bfa_fcpim_add_iostats(lstats, rstats, iocomp_timedout); 385 bfa_fcpim_add_iostats(lstats, rstats, iocom_nexus_abort); 386 bfa_fcpim_add_iostats(lstats, rstats, iocom_proto_err); 387 bfa_fcpim_add_iostats(lstats, rstats, iocom_dif_err); 388 bfa_fcpim_add_iostats(lstats, rstats, iocom_sqer_needed); 389 bfa_fcpim_add_iostats(lstats, rstats, iocom_res_free); 390 bfa_fcpim_add_iostats(lstats, rstats, iocom_hostabrts); 391 bfa_fcpim_add_iostats(lstats, rstats, iocom_utags); 392 bfa_fcpim_add_iostats(lstats, rstats, io_cleanups); 393 bfa_fcpim_add_iostats(lstats, rstats, io_tmaborts); 394 bfa_fcpim_add_iostats(lstats, rstats, onlines); 395 bfa_fcpim_add_iostats(lstats, rstats, offlines); 396 bfa_fcpim_add_iostats(lstats, rstats, creates); 397 bfa_fcpim_add_iostats(lstats, rstats, deletes); 398 bfa_fcpim_add_iostats(lstats, rstats, create_comps); 399 bfa_fcpim_add_iostats(lstats, rstats, delete_comps); 400 bfa_fcpim_add_iostats(lstats, rstats, sler_events); 401 bfa_fcpim_add_iostats(lstats, rstats, fw_create); 402 bfa_fcpim_add_iostats(lstats, rstats, fw_delete); 403 bfa_fcpim_add_iostats(lstats, rstats, ioc_disabled); 404 bfa_fcpim_add_iostats(lstats, rstats, cleanup_comps); 405 bfa_fcpim_add_iostats(lstats, rstats, tm_cmnds); 406 bfa_fcpim_add_iostats(lstats, rstats, tm_fw_rsps); 407 bfa_fcpim_add_iostats(lstats, rstats, tm_success); 408 bfa_fcpim_add_iostats(lstats, rstats, tm_failures); 409 bfa_fcpim_add_iostats(lstats, rstats, tm_io_comps); 410 bfa_fcpim_add_iostats(lstats, rstats, tm_qresumes); 411 bfa_fcpim_add_iostats(lstats, rstats, tm_iocdowns); 412 bfa_fcpim_add_iostats(lstats, rstats, tm_cleanups); 413 bfa_fcpim_add_iostats(lstats, rstats, tm_cleanup_comps); 414 bfa_fcpim_add_iostats(lstats, rstats, io_comps); 415 bfa_fcpim_add_iostats(lstats, rstats, input_reqs); 416 bfa_fcpim_add_iostats(lstats, rstats, output_reqs); 417 bfa_fcpim_add_iostats(lstats, rstats, rd_throughput); 418 bfa_fcpim_add_iostats(lstats, rstats, wr_throughput); 419 } 420 421 bfa_status_t 422 bfa_fcpim_port_iostats(struct bfa_s *bfa, 423 struct bfa_itnim_iostats_s *stats, u8 lp_tag) 424 { 425 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 426 struct list_head *qe, *qen; 427 struct bfa_itnim_s *itnim; 428 429 /* accumulate IO stats from itnim */ 430 memset(stats, 0, sizeof(struct bfa_itnim_iostats_s)); 431 list_for_each_safe(qe, qen, &fcpim->itnim_q) { 432 itnim = (struct bfa_itnim_s *) qe; 433 if (itnim->rport->rport_info.lp_tag != lp_tag) 434 continue; 435 bfa_fcpim_add_stats(stats, &(itnim->stats)); 436 } 437 return BFA_STATUS_OK; 438 } 439 440 u16 441 bfa_fcpim_qdepth_get(struct bfa_s *bfa) 442 { 443 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 444 445 return fcpim->q_depth; 446 } 447 448 /* 449 * BFA ITNIM module state machine functions 450 */ 451 452 /* 453 * Beginning/unallocated state - no events expected. 454 */ 455 static void 456 bfa_itnim_sm_uninit(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 457 { 458 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 459 bfa_trc(itnim->bfa, event); 460 461 switch (event) { 462 case BFA_ITNIM_SM_CREATE: 463 bfa_sm_set_state(itnim, bfa_itnim_sm_created); 464 itnim->is_online = BFA_FALSE; 465 bfa_fcpim_additn(itnim); 466 break; 467 468 default: 469 bfa_sm_fault(itnim->bfa, event); 470 } 471 } 472 473 /* 474 * Beginning state, only online event expected. 475 */ 476 static void 477 bfa_itnim_sm_created(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 478 { 479 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 480 bfa_trc(itnim->bfa, event); 481 482 switch (event) { 483 case BFA_ITNIM_SM_ONLINE: 484 if (bfa_itnim_send_fwcreate(itnim)) 485 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); 486 else 487 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); 488 break; 489 490 case BFA_ITNIM_SM_DELETE: 491 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 492 bfa_fcpim_delitn(itnim); 493 break; 494 495 case BFA_ITNIM_SM_HWFAIL: 496 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 497 break; 498 499 default: 500 bfa_sm_fault(itnim->bfa, event); 501 } 502 } 503 504 /* 505 * Waiting for itnim create response from firmware. 506 */ 507 static void 508 bfa_itnim_sm_fwcreate(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 509 { 510 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 511 bfa_trc(itnim->bfa, event); 512 513 switch (event) { 514 case BFA_ITNIM_SM_FWRSP: 515 bfa_sm_set_state(itnim, bfa_itnim_sm_online); 516 itnim->is_online = BFA_TRUE; 517 bfa_itnim_iotov_online(itnim); 518 bfa_itnim_online_cb(itnim); 519 break; 520 521 case BFA_ITNIM_SM_DELETE: 522 bfa_sm_set_state(itnim, bfa_itnim_sm_delete_pending); 523 break; 524 525 case BFA_ITNIM_SM_OFFLINE: 526 if (bfa_itnim_send_fwdelete(itnim)) 527 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); 528 else 529 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); 530 break; 531 532 case BFA_ITNIM_SM_HWFAIL: 533 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 534 break; 535 536 default: 537 bfa_sm_fault(itnim->bfa, event); 538 } 539 } 540 541 static void 542 bfa_itnim_sm_fwcreate_qfull(struct bfa_itnim_s *itnim, 543 enum bfa_itnim_event event) 544 { 545 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 546 bfa_trc(itnim->bfa, event); 547 548 switch (event) { 549 case BFA_ITNIM_SM_QRESUME: 550 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); 551 bfa_itnim_send_fwcreate(itnim); 552 break; 553 554 case BFA_ITNIM_SM_DELETE: 555 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 556 bfa_reqq_wcancel(&itnim->reqq_wait); 557 bfa_fcpim_delitn(itnim); 558 break; 559 560 case BFA_ITNIM_SM_OFFLINE: 561 bfa_sm_set_state(itnim, bfa_itnim_sm_offline); 562 bfa_reqq_wcancel(&itnim->reqq_wait); 563 bfa_itnim_offline_cb(itnim); 564 break; 565 566 case BFA_ITNIM_SM_HWFAIL: 567 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 568 bfa_reqq_wcancel(&itnim->reqq_wait); 569 break; 570 571 default: 572 bfa_sm_fault(itnim->bfa, event); 573 } 574 } 575 576 /* 577 * Waiting for itnim create response from firmware, a delete is pending. 578 */ 579 static void 580 bfa_itnim_sm_delete_pending(struct bfa_itnim_s *itnim, 581 enum bfa_itnim_event event) 582 { 583 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 584 bfa_trc(itnim->bfa, event); 585 586 switch (event) { 587 case BFA_ITNIM_SM_FWRSP: 588 if (bfa_itnim_send_fwdelete(itnim)) 589 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); 590 else 591 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); 592 break; 593 594 case BFA_ITNIM_SM_HWFAIL: 595 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 596 bfa_fcpim_delitn(itnim); 597 break; 598 599 default: 600 bfa_sm_fault(itnim->bfa, event); 601 } 602 } 603 604 /* 605 * Online state - normal parking state. 606 */ 607 static void 608 bfa_itnim_sm_online(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 609 { 610 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 611 bfa_trc(itnim->bfa, event); 612 613 switch (event) { 614 case BFA_ITNIM_SM_OFFLINE: 615 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); 616 itnim->is_online = BFA_FALSE; 617 bfa_itnim_iotov_start(itnim); 618 bfa_itnim_cleanup(itnim); 619 break; 620 621 case BFA_ITNIM_SM_DELETE: 622 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); 623 itnim->is_online = BFA_FALSE; 624 bfa_itnim_cleanup(itnim); 625 break; 626 627 case BFA_ITNIM_SM_SLER: 628 bfa_sm_set_state(itnim, bfa_itnim_sm_sler); 629 itnim->is_online = BFA_FALSE; 630 bfa_itnim_iotov_start(itnim); 631 bfa_itnim_sler_cb(itnim); 632 break; 633 634 case BFA_ITNIM_SM_HWFAIL: 635 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 636 itnim->is_online = BFA_FALSE; 637 bfa_itnim_iotov_start(itnim); 638 bfa_itnim_iocdisable_cleanup(itnim); 639 break; 640 641 default: 642 bfa_sm_fault(itnim->bfa, event); 643 } 644 } 645 646 /* 647 * Second level error recovery need. 648 */ 649 static void 650 bfa_itnim_sm_sler(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 651 { 652 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 653 bfa_trc(itnim->bfa, event); 654 655 switch (event) { 656 case BFA_ITNIM_SM_OFFLINE: 657 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_offline); 658 bfa_itnim_cleanup(itnim); 659 break; 660 661 case BFA_ITNIM_SM_DELETE: 662 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); 663 bfa_itnim_cleanup(itnim); 664 bfa_itnim_iotov_delete(itnim); 665 break; 666 667 case BFA_ITNIM_SM_HWFAIL: 668 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 669 bfa_itnim_iocdisable_cleanup(itnim); 670 break; 671 672 default: 673 bfa_sm_fault(itnim->bfa, event); 674 } 675 } 676 677 /* 678 * Going offline. Waiting for active IO cleanup. 679 */ 680 static void 681 bfa_itnim_sm_cleanup_offline(struct bfa_itnim_s *itnim, 682 enum bfa_itnim_event event) 683 { 684 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 685 bfa_trc(itnim->bfa, event); 686 687 switch (event) { 688 case BFA_ITNIM_SM_CLEANUP: 689 if (bfa_itnim_send_fwdelete(itnim)) 690 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); 691 else 692 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete_qfull); 693 break; 694 695 case BFA_ITNIM_SM_DELETE: 696 bfa_sm_set_state(itnim, bfa_itnim_sm_cleanup_delete); 697 bfa_itnim_iotov_delete(itnim); 698 break; 699 700 case BFA_ITNIM_SM_HWFAIL: 701 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 702 bfa_itnim_iocdisable_cleanup(itnim); 703 bfa_itnim_offline_cb(itnim); 704 break; 705 706 case BFA_ITNIM_SM_SLER: 707 break; 708 709 default: 710 bfa_sm_fault(itnim->bfa, event); 711 } 712 } 713 714 /* 715 * Deleting itnim. Waiting for active IO cleanup. 716 */ 717 static void 718 bfa_itnim_sm_cleanup_delete(struct bfa_itnim_s *itnim, 719 enum bfa_itnim_event event) 720 { 721 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 722 bfa_trc(itnim->bfa, event); 723 724 switch (event) { 725 case BFA_ITNIM_SM_CLEANUP: 726 if (bfa_itnim_send_fwdelete(itnim)) 727 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); 728 else 729 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); 730 break; 731 732 case BFA_ITNIM_SM_HWFAIL: 733 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 734 bfa_itnim_iocdisable_cleanup(itnim); 735 break; 736 737 default: 738 bfa_sm_fault(itnim->bfa, event); 739 } 740 } 741 742 /* 743 * Rport offline. Fimrware itnim is being deleted - awaiting f/w response. 744 */ 745 static void 746 bfa_itnim_sm_fwdelete(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 747 { 748 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 749 bfa_trc(itnim->bfa, event); 750 751 switch (event) { 752 case BFA_ITNIM_SM_FWRSP: 753 bfa_sm_set_state(itnim, bfa_itnim_sm_offline); 754 bfa_itnim_offline_cb(itnim); 755 break; 756 757 case BFA_ITNIM_SM_DELETE: 758 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); 759 break; 760 761 case BFA_ITNIM_SM_HWFAIL: 762 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 763 bfa_itnim_offline_cb(itnim); 764 break; 765 766 default: 767 bfa_sm_fault(itnim->bfa, event); 768 } 769 } 770 771 static void 772 bfa_itnim_sm_fwdelete_qfull(struct bfa_itnim_s *itnim, 773 enum bfa_itnim_event event) 774 { 775 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 776 bfa_trc(itnim->bfa, event); 777 778 switch (event) { 779 case BFA_ITNIM_SM_QRESUME: 780 bfa_sm_set_state(itnim, bfa_itnim_sm_fwdelete); 781 bfa_itnim_send_fwdelete(itnim); 782 break; 783 784 case BFA_ITNIM_SM_DELETE: 785 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting_qfull); 786 break; 787 788 case BFA_ITNIM_SM_HWFAIL: 789 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 790 bfa_reqq_wcancel(&itnim->reqq_wait); 791 bfa_itnim_offline_cb(itnim); 792 break; 793 794 default: 795 bfa_sm_fault(itnim->bfa, event); 796 } 797 } 798 799 /* 800 * Offline state. 801 */ 802 static void 803 bfa_itnim_sm_offline(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 804 { 805 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 806 bfa_trc(itnim->bfa, event); 807 808 switch (event) { 809 case BFA_ITNIM_SM_DELETE: 810 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 811 bfa_itnim_iotov_delete(itnim); 812 bfa_fcpim_delitn(itnim); 813 break; 814 815 case BFA_ITNIM_SM_ONLINE: 816 if (bfa_itnim_send_fwcreate(itnim)) 817 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); 818 else 819 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); 820 break; 821 822 case BFA_ITNIM_SM_HWFAIL: 823 bfa_sm_set_state(itnim, bfa_itnim_sm_iocdisable); 824 break; 825 826 default: 827 bfa_sm_fault(itnim->bfa, event); 828 } 829 } 830 831 static void 832 bfa_itnim_sm_iocdisable(struct bfa_itnim_s *itnim, 833 enum bfa_itnim_event event) 834 { 835 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 836 bfa_trc(itnim->bfa, event); 837 838 switch (event) { 839 case BFA_ITNIM_SM_DELETE: 840 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 841 bfa_itnim_iotov_delete(itnim); 842 bfa_fcpim_delitn(itnim); 843 break; 844 845 case BFA_ITNIM_SM_OFFLINE: 846 bfa_itnim_offline_cb(itnim); 847 break; 848 849 case BFA_ITNIM_SM_ONLINE: 850 if (bfa_itnim_send_fwcreate(itnim)) 851 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate); 852 else 853 bfa_sm_set_state(itnim, bfa_itnim_sm_fwcreate_qfull); 854 break; 855 856 case BFA_ITNIM_SM_HWFAIL: 857 break; 858 859 default: 860 bfa_sm_fault(itnim->bfa, event); 861 } 862 } 863 864 /* 865 * Itnim is deleted, waiting for firmware response to delete. 866 */ 867 static void 868 bfa_itnim_sm_deleting(struct bfa_itnim_s *itnim, enum bfa_itnim_event event) 869 { 870 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 871 bfa_trc(itnim->bfa, event); 872 873 switch (event) { 874 case BFA_ITNIM_SM_FWRSP: 875 case BFA_ITNIM_SM_HWFAIL: 876 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 877 bfa_fcpim_delitn(itnim); 878 break; 879 880 default: 881 bfa_sm_fault(itnim->bfa, event); 882 } 883 } 884 885 static void 886 bfa_itnim_sm_deleting_qfull(struct bfa_itnim_s *itnim, 887 enum bfa_itnim_event event) 888 { 889 bfa_trc(itnim->bfa, itnim->rport->rport_tag); 890 bfa_trc(itnim->bfa, event); 891 892 switch (event) { 893 case BFA_ITNIM_SM_QRESUME: 894 bfa_sm_set_state(itnim, bfa_itnim_sm_deleting); 895 bfa_itnim_send_fwdelete(itnim); 896 break; 897 898 case BFA_ITNIM_SM_HWFAIL: 899 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 900 bfa_reqq_wcancel(&itnim->reqq_wait); 901 bfa_fcpim_delitn(itnim); 902 break; 903 904 default: 905 bfa_sm_fault(itnim->bfa, event); 906 } 907 } 908 909 /* 910 * Initiate cleanup of all IOs on an IOC failure. 911 */ 912 static void 913 bfa_itnim_iocdisable_cleanup(struct bfa_itnim_s *itnim) 914 { 915 struct bfa_tskim_s *tskim; 916 struct bfa_ioim_s *ioim; 917 struct list_head *qe, *qen; 918 919 list_for_each_safe(qe, qen, &itnim->tsk_q) { 920 tskim = (struct bfa_tskim_s *) qe; 921 bfa_tskim_iocdisable(tskim); 922 } 923 924 list_for_each_safe(qe, qen, &itnim->io_q) { 925 ioim = (struct bfa_ioim_s *) qe; 926 bfa_ioim_iocdisable(ioim); 927 } 928 929 /* 930 * For IO request in pending queue, we pretend an early timeout. 931 */ 932 list_for_each_safe(qe, qen, &itnim->pending_q) { 933 ioim = (struct bfa_ioim_s *) qe; 934 bfa_ioim_tov(ioim); 935 } 936 937 list_for_each_safe(qe, qen, &itnim->io_cleanup_q) { 938 ioim = (struct bfa_ioim_s *) qe; 939 bfa_ioim_iocdisable(ioim); 940 } 941 } 942 943 /* 944 * IO cleanup completion 945 */ 946 static void 947 bfa_itnim_cleanp_comp(void *itnim_cbarg) 948 { 949 struct bfa_itnim_s *itnim = itnim_cbarg; 950 951 bfa_stats(itnim, cleanup_comps); 952 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CLEANUP); 953 } 954 955 /* 956 * Initiate cleanup of all IOs. 957 */ 958 static void 959 bfa_itnim_cleanup(struct bfa_itnim_s *itnim) 960 { 961 struct bfa_ioim_s *ioim; 962 struct bfa_tskim_s *tskim; 963 struct list_head *qe, *qen; 964 965 bfa_wc_init(&itnim->wc, bfa_itnim_cleanp_comp, itnim); 966 967 list_for_each_safe(qe, qen, &itnim->io_q) { 968 ioim = (struct bfa_ioim_s *) qe; 969 970 /* 971 * Move IO to a cleanup queue from active queue so that a later 972 * TM will not pickup this IO. 973 */ 974 list_del(&ioim->qe); 975 list_add_tail(&ioim->qe, &itnim->io_cleanup_q); 976 977 bfa_wc_up(&itnim->wc); 978 bfa_ioim_cleanup(ioim); 979 } 980 981 list_for_each_safe(qe, qen, &itnim->tsk_q) { 982 tskim = (struct bfa_tskim_s *) qe; 983 bfa_wc_up(&itnim->wc); 984 bfa_tskim_cleanup(tskim); 985 } 986 987 bfa_wc_wait(&itnim->wc); 988 } 989 990 static void 991 __bfa_cb_itnim_online(void *cbarg, bfa_boolean_t complete) 992 { 993 struct bfa_itnim_s *itnim = cbarg; 994 995 if (complete) 996 bfa_cb_itnim_online(itnim->ditn); 997 } 998 999 static void 1000 __bfa_cb_itnim_offline(void *cbarg, bfa_boolean_t complete) 1001 { 1002 struct bfa_itnim_s *itnim = cbarg; 1003 1004 if (complete) 1005 bfa_cb_itnim_offline(itnim->ditn); 1006 } 1007 1008 static void 1009 __bfa_cb_itnim_sler(void *cbarg, bfa_boolean_t complete) 1010 { 1011 struct bfa_itnim_s *itnim = cbarg; 1012 1013 if (complete) 1014 bfa_cb_itnim_sler(itnim->ditn); 1015 } 1016 1017 /* 1018 * Call to resume any I/O requests waiting for room in request queue. 1019 */ 1020 static void 1021 bfa_itnim_qresume(void *cbarg) 1022 { 1023 struct bfa_itnim_s *itnim = cbarg; 1024 1025 bfa_sm_send_event(itnim, BFA_ITNIM_SM_QRESUME); 1026 } 1027 1028 /* 1029 * bfa_itnim_public 1030 */ 1031 1032 void 1033 bfa_itnim_iodone(struct bfa_itnim_s *itnim) 1034 { 1035 bfa_wc_down(&itnim->wc); 1036 } 1037 1038 void 1039 bfa_itnim_tskdone(struct bfa_itnim_s *itnim) 1040 { 1041 bfa_wc_down(&itnim->wc); 1042 } 1043 1044 void 1045 bfa_itnim_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len) 1046 { 1047 /* 1048 * ITN memory 1049 */ 1050 *km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itnim_s); 1051 } 1052 1053 void 1054 bfa_itnim_attach(struct bfa_fcpim_s *fcpim) 1055 { 1056 struct bfa_s *bfa = fcpim->bfa; 1057 struct bfa_fcp_mod_s *fcp = fcpim->fcp; 1058 struct bfa_itnim_s *itnim; 1059 int i, j; 1060 1061 INIT_LIST_HEAD(&fcpim->itnim_q); 1062 1063 itnim = (struct bfa_itnim_s *) bfa_mem_kva_curp(fcp); 1064 fcpim->itnim_arr = itnim; 1065 1066 for (i = 0; i < fcpim->num_itnims; i++, itnim++) { 1067 memset(itnim, 0, sizeof(struct bfa_itnim_s)); 1068 itnim->bfa = bfa; 1069 itnim->fcpim = fcpim; 1070 itnim->reqq = BFA_REQQ_QOS_LO; 1071 itnim->rport = BFA_RPORT_FROM_TAG(bfa, i); 1072 itnim->iotov_active = BFA_FALSE; 1073 bfa_reqq_winit(&itnim->reqq_wait, bfa_itnim_qresume, itnim); 1074 1075 INIT_LIST_HEAD(&itnim->io_q); 1076 INIT_LIST_HEAD(&itnim->io_cleanup_q); 1077 INIT_LIST_HEAD(&itnim->pending_q); 1078 INIT_LIST_HEAD(&itnim->tsk_q); 1079 INIT_LIST_HEAD(&itnim->delay_comp_q); 1080 for (j = 0; j < BFA_IOBUCKET_MAX; j++) 1081 itnim->ioprofile.io_latency.min[j] = ~0; 1082 bfa_sm_set_state(itnim, bfa_itnim_sm_uninit); 1083 } 1084 1085 bfa_mem_kva_curp(fcp) = (u8 *) itnim; 1086 } 1087 1088 void 1089 bfa_itnim_iocdisable(struct bfa_itnim_s *itnim) 1090 { 1091 bfa_stats(itnim, ioc_disabled); 1092 bfa_sm_send_event(itnim, BFA_ITNIM_SM_HWFAIL); 1093 } 1094 1095 static bfa_boolean_t 1096 bfa_itnim_send_fwcreate(struct bfa_itnim_s *itnim) 1097 { 1098 struct bfi_itn_create_req_s *m; 1099 1100 itnim->msg_no++; 1101 1102 /* 1103 * check for room in queue to send request now 1104 */ 1105 m = bfa_reqq_next(itnim->bfa, itnim->reqq); 1106 if (!m) { 1107 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); 1108 return BFA_FALSE; 1109 } 1110 1111 bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_CREATE_REQ, 1112 bfa_fn_lpu(itnim->bfa)); 1113 m->fw_handle = itnim->rport->fw_handle; 1114 m->class = FC_CLASS_3; 1115 m->seq_rec = itnim->seq_rec; 1116 m->msg_no = itnim->msg_no; 1117 bfa_stats(itnim, fw_create); 1118 1119 /* 1120 * queue I/O message to firmware 1121 */ 1122 bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh); 1123 return BFA_TRUE; 1124 } 1125 1126 static bfa_boolean_t 1127 bfa_itnim_send_fwdelete(struct bfa_itnim_s *itnim) 1128 { 1129 struct bfi_itn_delete_req_s *m; 1130 1131 /* 1132 * check for room in queue to send request now 1133 */ 1134 m = bfa_reqq_next(itnim->bfa, itnim->reqq); 1135 if (!m) { 1136 bfa_reqq_wait(itnim->bfa, itnim->reqq, &itnim->reqq_wait); 1137 return BFA_FALSE; 1138 } 1139 1140 bfi_h2i_set(m->mh, BFI_MC_ITN, BFI_ITN_H2I_DELETE_REQ, 1141 bfa_fn_lpu(itnim->bfa)); 1142 m->fw_handle = itnim->rport->fw_handle; 1143 bfa_stats(itnim, fw_delete); 1144 1145 /* 1146 * queue I/O message to firmware 1147 */ 1148 bfa_reqq_produce(itnim->bfa, itnim->reqq, m->mh); 1149 return BFA_TRUE; 1150 } 1151 1152 /* 1153 * Cleanup all pending failed inflight requests. 1154 */ 1155 static void 1156 bfa_itnim_delayed_comp(struct bfa_itnim_s *itnim, bfa_boolean_t iotov) 1157 { 1158 struct bfa_ioim_s *ioim; 1159 struct list_head *qe, *qen; 1160 1161 list_for_each_safe(qe, qen, &itnim->delay_comp_q) { 1162 ioim = (struct bfa_ioim_s *)qe; 1163 bfa_ioim_delayed_comp(ioim, iotov); 1164 } 1165 } 1166 1167 /* 1168 * Start all pending IO requests. 1169 */ 1170 static void 1171 bfa_itnim_iotov_online(struct bfa_itnim_s *itnim) 1172 { 1173 struct bfa_ioim_s *ioim; 1174 1175 bfa_itnim_iotov_stop(itnim); 1176 1177 /* 1178 * Abort all inflight IO requests in the queue 1179 */ 1180 bfa_itnim_delayed_comp(itnim, BFA_FALSE); 1181 1182 /* 1183 * Start all pending IO requests. 1184 */ 1185 while (!list_empty(&itnim->pending_q)) { 1186 bfa_q_deq(&itnim->pending_q, &ioim); 1187 list_add_tail(&ioim->qe, &itnim->io_q); 1188 bfa_ioim_start(ioim); 1189 } 1190 } 1191 1192 /* 1193 * Fail all pending IO requests 1194 */ 1195 static void 1196 bfa_itnim_iotov_cleanup(struct bfa_itnim_s *itnim) 1197 { 1198 struct bfa_ioim_s *ioim; 1199 1200 /* 1201 * Fail all inflight IO requests in the queue 1202 */ 1203 bfa_itnim_delayed_comp(itnim, BFA_TRUE); 1204 1205 /* 1206 * Fail any pending IO requests. 1207 */ 1208 while (!list_empty(&itnim->pending_q)) { 1209 bfa_q_deq(&itnim->pending_q, &ioim); 1210 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); 1211 bfa_ioim_tov(ioim); 1212 } 1213 } 1214 1215 /* 1216 * IO TOV timer callback. Fail any pending IO requests. 1217 */ 1218 static void 1219 bfa_itnim_iotov(void *itnim_arg) 1220 { 1221 struct bfa_itnim_s *itnim = itnim_arg; 1222 1223 itnim->iotov_active = BFA_FALSE; 1224 1225 bfa_cb_itnim_tov_begin(itnim->ditn); 1226 bfa_itnim_iotov_cleanup(itnim); 1227 bfa_cb_itnim_tov(itnim->ditn); 1228 } 1229 1230 /* 1231 * Start IO TOV timer for failing back pending IO requests in offline state. 1232 */ 1233 static void 1234 bfa_itnim_iotov_start(struct bfa_itnim_s *itnim) 1235 { 1236 if (itnim->fcpim->path_tov > 0) { 1237 1238 itnim->iotov_active = BFA_TRUE; 1239 WARN_ON(!bfa_itnim_hold_io(itnim)); 1240 bfa_timer_start(itnim->bfa, &itnim->timer, 1241 bfa_itnim_iotov, itnim, itnim->fcpim->path_tov); 1242 } 1243 } 1244 1245 /* 1246 * Stop IO TOV timer. 1247 */ 1248 static void 1249 bfa_itnim_iotov_stop(struct bfa_itnim_s *itnim) 1250 { 1251 if (itnim->iotov_active) { 1252 itnim->iotov_active = BFA_FALSE; 1253 bfa_timer_stop(&itnim->timer); 1254 } 1255 } 1256 1257 /* 1258 * Stop IO TOV timer. 1259 */ 1260 static void 1261 bfa_itnim_iotov_delete(struct bfa_itnim_s *itnim) 1262 { 1263 bfa_boolean_t pathtov_active = BFA_FALSE; 1264 1265 if (itnim->iotov_active) 1266 pathtov_active = BFA_TRUE; 1267 1268 bfa_itnim_iotov_stop(itnim); 1269 if (pathtov_active) 1270 bfa_cb_itnim_tov_begin(itnim->ditn); 1271 bfa_itnim_iotov_cleanup(itnim); 1272 if (pathtov_active) 1273 bfa_cb_itnim_tov(itnim->ditn); 1274 } 1275 1276 static void 1277 bfa_itnim_update_del_itn_stats(struct bfa_itnim_s *itnim) 1278 { 1279 struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa); 1280 fcpim->del_itn_stats.del_itn_iocomp_aborted += 1281 itnim->stats.iocomp_aborted; 1282 fcpim->del_itn_stats.del_itn_iocomp_timedout += 1283 itnim->stats.iocomp_timedout; 1284 fcpim->del_itn_stats.del_itn_iocom_sqer_needed += 1285 itnim->stats.iocom_sqer_needed; 1286 fcpim->del_itn_stats.del_itn_iocom_res_free += 1287 itnim->stats.iocom_res_free; 1288 fcpim->del_itn_stats.del_itn_iocom_hostabrts += 1289 itnim->stats.iocom_hostabrts; 1290 fcpim->del_itn_stats.del_itn_total_ios += itnim->stats.total_ios; 1291 fcpim->del_itn_stats.del_io_iocdowns += itnim->stats.io_iocdowns; 1292 fcpim->del_itn_stats.del_tm_iocdowns += itnim->stats.tm_iocdowns; 1293 } 1294 1295 /* 1296 * bfa_itnim_public 1297 */ 1298 1299 /* 1300 * Itnim interrupt processing. 1301 */ 1302 void 1303 bfa_itnim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 1304 { 1305 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 1306 union bfi_itn_i2h_msg_u msg; 1307 struct bfa_itnim_s *itnim; 1308 1309 bfa_trc(bfa, m->mhdr.msg_id); 1310 1311 msg.msg = m; 1312 1313 switch (m->mhdr.msg_id) { 1314 case BFI_ITN_I2H_CREATE_RSP: 1315 itnim = BFA_ITNIM_FROM_TAG(fcpim, 1316 msg.create_rsp->bfa_handle); 1317 WARN_ON(msg.create_rsp->status != BFA_STATUS_OK); 1318 bfa_stats(itnim, create_comps); 1319 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); 1320 break; 1321 1322 case BFI_ITN_I2H_DELETE_RSP: 1323 itnim = BFA_ITNIM_FROM_TAG(fcpim, 1324 msg.delete_rsp->bfa_handle); 1325 WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK); 1326 bfa_stats(itnim, delete_comps); 1327 bfa_sm_send_event(itnim, BFA_ITNIM_SM_FWRSP); 1328 break; 1329 1330 case BFI_ITN_I2H_SLER_EVENT: 1331 itnim = BFA_ITNIM_FROM_TAG(fcpim, 1332 msg.sler_event->bfa_handle); 1333 bfa_stats(itnim, sler_events); 1334 bfa_sm_send_event(itnim, BFA_ITNIM_SM_SLER); 1335 break; 1336 1337 default: 1338 bfa_trc(bfa, m->mhdr.msg_id); 1339 WARN_ON(1); 1340 } 1341 } 1342 1343 /* 1344 * bfa_itnim_api 1345 */ 1346 1347 struct bfa_itnim_s * 1348 bfa_itnim_create(struct bfa_s *bfa, struct bfa_rport_s *rport, void *ditn) 1349 { 1350 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 1351 struct bfa_itnim_s *itnim; 1352 1353 bfa_itn_create(bfa, rport, bfa_itnim_isr); 1354 1355 itnim = BFA_ITNIM_FROM_TAG(fcpim, rport->rport_tag); 1356 WARN_ON(itnim->rport != rport); 1357 1358 itnim->ditn = ditn; 1359 1360 bfa_stats(itnim, creates); 1361 bfa_sm_send_event(itnim, BFA_ITNIM_SM_CREATE); 1362 1363 return itnim; 1364 } 1365 1366 void 1367 bfa_itnim_delete(struct bfa_itnim_s *itnim) 1368 { 1369 bfa_stats(itnim, deletes); 1370 bfa_sm_send_event(itnim, BFA_ITNIM_SM_DELETE); 1371 } 1372 1373 void 1374 bfa_itnim_online(struct bfa_itnim_s *itnim, bfa_boolean_t seq_rec) 1375 { 1376 itnim->seq_rec = seq_rec; 1377 bfa_stats(itnim, onlines); 1378 bfa_sm_send_event(itnim, BFA_ITNIM_SM_ONLINE); 1379 } 1380 1381 void 1382 bfa_itnim_offline(struct bfa_itnim_s *itnim) 1383 { 1384 bfa_stats(itnim, offlines); 1385 bfa_sm_send_event(itnim, BFA_ITNIM_SM_OFFLINE); 1386 } 1387 1388 /* 1389 * Return true if itnim is considered offline for holding off IO request. 1390 * IO is not held if itnim is being deleted. 1391 */ 1392 bfa_boolean_t 1393 bfa_itnim_hold_io(struct bfa_itnim_s *itnim) 1394 { 1395 return itnim->fcpim->path_tov && itnim->iotov_active && 1396 (bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwcreate) || 1397 bfa_sm_cmp_state(itnim, bfa_itnim_sm_sler) || 1398 bfa_sm_cmp_state(itnim, bfa_itnim_sm_cleanup_offline) || 1399 bfa_sm_cmp_state(itnim, bfa_itnim_sm_fwdelete) || 1400 bfa_sm_cmp_state(itnim, bfa_itnim_sm_offline) || 1401 bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable)); 1402 } 1403 1404 void 1405 bfa_itnim_clear_stats(struct bfa_itnim_s *itnim) 1406 { 1407 int j; 1408 memset(&itnim->stats, 0, sizeof(itnim->stats)); 1409 memset(&itnim->ioprofile, 0, sizeof(itnim->ioprofile)); 1410 for (j = 0; j < BFA_IOBUCKET_MAX; j++) 1411 itnim->ioprofile.io_latency.min[j] = ~0; 1412 } 1413 1414 /* 1415 * BFA IO module state machine functions 1416 */ 1417 1418 /* 1419 * IO is not started (unallocated). 1420 */ 1421 static void 1422 bfa_ioim_sm_uninit(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1423 { 1424 switch (event) { 1425 case BFA_IOIM_SM_START: 1426 if (!bfa_itnim_is_online(ioim->itnim)) { 1427 if (!bfa_itnim_hold_io(ioim->itnim)) { 1428 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1429 list_del(&ioim->qe); 1430 list_add_tail(&ioim->qe, 1431 &ioim->fcpim->ioim_comp_q); 1432 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1433 __bfa_cb_ioim_pathtov, ioim); 1434 } else { 1435 list_del(&ioim->qe); 1436 list_add_tail(&ioim->qe, 1437 &ioim->itnim->pending_q); 1438 } 1439 break; 1440 } 1441 1442 if (ioim->nsges > BFI_SGE_INLINE) { 1443 if (!bfa_ioim_sgpg_alloc(ioim)) { 1444 bfa_sm_set_state(ioim, bfa_ioim_sm_sgalloc); 1445 return; 1446 } 1447 } 1448 1449 if (!bfa_ioim_send_ioreq(ioim)) { 1450 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull); 1451 break; 1452 } 1453 1454 bfa_sm_set_state(ioim, bfa_ioim_sm_active); 1455 break; 1456 1457 case BFA_IOIM_SM_IOTOV: 1458 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1459 bfa_ioim_move_to_comp_q(ioim); 1460 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1461 __bfa_cb_ioim_pathtov, ioim); 1462 break; 1463 1464 case BFA_IOIM_SM_ABORT: 1465 /* 1466 * IO in pending queue can get abort requests. Complete abort 1467 * requests immediately. 1468 */ 1469 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1470 WARN_ON(!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim)); 1471 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1472 __bfa_cb_ioim_abort, ioim); 1473 break; 1474 1475 default: 1476 bfa_sm_fault(ioim->bfa, event); 1477 } 1478 } 1479 1480 /* 1481 * IO is waiting for SG pages. 1482 */ 1483 static void 1484 bfa_ioim_sm_sgalloc(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1485 { 1486 bfa_trc(ioim->bfa, ioim->iotag); 1487 bfa_trc(ioim->bfa, event); 1488 1489 switch (event) { 1490 case BFA_IOIM_SM_SGALLOCED: 1491 if (!bfa_ioim_send_ioreq(ioim)) { 1492 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull); 1493 break; 1494 } 1495 bfa_sm_set_state(ioim, bfa_ioim_sm_active); 1496 break; 1497 1498 case BFA_IOIM_SM_CLEANUP: 1499 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1500 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); 1501 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1502 ioim); 1503 bfa_ioim_notify_cleanup(ioim); 1504 break; 1505 1506 case BFA_IOIM_SM_ABORT: 1507 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1508 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); 1509 bfa_ioim_move_to_comp_q(ioim); 1510 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1511 ioim); 1512 break; 1513 1514 case BFA_IOIM_SM_HWFAIL: 1515 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1516 bfa_sgpg_wcancel(ioim->bfa, &ioim->iosp->sgpg_wqe); 1517 bfa_ioim_move_to_comp_q(ioim); 1518 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1519 ioim); 1520 break; 1521 1522 default: 1523 bfa_sm_fault(ioim->bfa, event); 1524 } 1525 } 1526 1527 /* 1528 * IO is active. 1529 */ 1530 static void 1531 bfa_ioim_sm_active(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1532 { 1533 switch (event) { 1534 case BFA_IOIM_SM_COMP_GOOD: 1535 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1536 bfa_ioim_move_to_comp_q(ioim); 1537 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1538 __bfa_cb_ioim_good_comp, ioim); 1539 break; 1540 1541 case BFA_IOIM_SM_COMP: 1542 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1543 bfa_ioim_move_to_comp_q(ioim); 1544 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, 1545 ioim); 1546 break; 1547 1548 case BFA_IOIM_SM_DONE: 1549 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1550 bfa_ioim_move_to_comp_q(ioim); 1551 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_comp, 1552 ioim); 1553 break; 1554 1555 case BFA_IOIM_SM_ABORT: 1556 ioim->iosp->abort_explicit = BFA_TRUE; 1557 ioim->io_cbfn = __bfa_cb_ioim_abort; 1558 1559 if (bfa_ioim_send_abort(ioim)) 1560 bfa_sm_set_state(ioim, bfa_ioim_sm_abort); 1561 else { 1562 bfa_sm_set_state(ioim, bfa_ioim_sm_abort_qfull); 1563 bfa_stats(ioim->itnim, qwait); 1564 bfa_reqq_wait(ioim->bfa, ioim->reqq, 1565 &ioim->iosp->reqq_wait); 1566 } 1567 break; 1568 1569 case BFA_IOIM_SM_CLEANUP: 1570 ioim->iosp->abort_explicit = BFA_FALSE; 1571 ioim->io_cbfn = __bfa_cb_ioim_failed; 1572 1573 if (bfa_ioim_send_abort(ioim)) 1574 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); 1575 else { 1576 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); 1577 bfa_stats(ioim->itnim, qwait); 1578 bfa_reqq_wait(ioim->bfa, ioim->reqq, 1579 &ioim->iosp->reqq_wait); 1580 } 1581 break; 1582 1583 case BFA_IOIM_SM_HWFAIL: 1584 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1585 bfa_ioim_move_to_comp_q(ioim); 1586 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1587 ioim); 1588 break; 1589 1590 case BFA_IOIM_SM_SQRETRY: 1591 if (bfa_ioim_maxretry_reached(ioim)) { 1592 /* max retry reached, free IO */ 1593 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1594 bfa_ioim_move_to_comp_q(ioim); 1595 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1596 __bfa_cb_ioim_failed, ioim); 1597 break; 1598 } 1599 /* waiting for IO tag resource free */ 1600 bfa_sm_set_state(ioim, bfa_ioim_sm_cmnd_retry); 1601 break; 1602 1603 default: 1604 bfa_sm_fault(ioim->bfa, event); 1605 } 1606 } 1607 1608 /* 1609 * IO is retried with new tag. 1610 */ 1611 static void 1612 bfa_ioim_sm_cmnd_retry(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1613 { 1614 switch (event) { 1615 case BFA_IOIM_SM_FREE: 1616 /* abts and rrq done. Now retry the IO with new tag */ 1617 bfa_ioim_update_iotag(ioim); 1618 if (!bfa_ioim_send_ioreq(ioim)) { 1619 bfa_sm_set_state(ioim, bfa_ioim_sm_qfull); 1620 break; 1621 } 1622 bfa_sm_set_state(ioim, bfa_ioim_sm_active); 1623 break; 1624 1625 case BFA_IOIM_SM_CLEANUP: 1626 ioim->iosp->abort_explicit = BFA_FALSE; 1627 ioim->io_cbfn = __bfa_cb_ioim_failed; 1628 1629 if (bfa_ioim_send_abort(ioim)) 1630 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); 1631 else { 1632 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); 1633 bfa_stats(ioim->itnim, qwait); 1634 bfa_reqq_wait(ioim->bfa, ioim->reqq, 1635 &ioim->iosp->reqq_wait); 1636 } 1637 break; 1638 1639 case BFA_IOIM_SM_HWFAIL: 1640 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1641 bfa_ioim_move_to_comp_q(ioim); 1642 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, 1643 __bfa_cb_ioim_failed, ioim); 1644 break; 1645 1646 case BFA_IOIM_SM_ABORT: 1647 /* in this state IO abort is done. 1648 * Waiting for IO tag resource free. 1649 */ 1650 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1651 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1652 ioim); 1653 break; 1654 1655 default: 1656 bfa_sm_fault(ioim->bfa, event); 1657 } 1658 } 1659 1660 /* 1661 * IO is being aborted, waiting for completion from firmware. 1662 */ 1663 static void 1664 bfa_ioim_sm_abort(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1665 { 1666 bfa_trc(ioim->bfa, ioim->iotag); 1667 bfa_trc(ioim->bfa, event); 1668 1669 switch (event) { 1670 case BFA_IOIM_SM_COMP_GOOD: 1671 case BFA_IOIM_SM_COMP: 1672 case BFA_IOIM_SM_DONE: 1673 case BFA_IOIM_SM_FREE: 1674 break; 1675 1676 case BFA_IOIM_SM_ABORT_DONE: 1677 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1678 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1679 ioim); 1680 break; 1681 1682 case BFA_IOIM_SM_ABORT_COMP: 1683 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1684 bfa_ioim_move_to_comp_q(ioim); 1685 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1686 ioim); 1687 break; 1688 1689 case BFA_IOIM_SM_COMP_UTAG: 1690 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1691 bfa_ioim_move_to_comp_q(ioim); 1692 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1693 ioim); 1694 break; 1695 1696 case BFA_IOIM_SM_CLEANUP: 1697 WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE); 1698 ioim->iosp->abort_explicit = BFA_FALSE; 1699 1700 if (bfa_ioim_send_abort(ioim)) 1701 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); 1702 else { 1703 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); 1704 bfa_stats(ioim->itnim, qwait); 1705 bfa_reqq_wait(ioim->bfa, ioim->reqq, 1706 &ioim->iosp->reqq_wait); 1707 } 1708 break; 1709 1710 case BFA_IOIM_SM_HWFAIL: 1711 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1712 bfa_ioim_move_to_comp_q(ioim); 1713 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1714 ioim); 1715 break; 1716 1717 default: 1718 bfa_sm_fault(ioim->bfa, event); 1719 } 1720 } 1721 1722 /* 1723 * IO is being cleaned up (implicit abort), waiting for completion from 1724 * firmware. 1725 */ 1726 static void 1727 bfa_ioim_sm_cleanup(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1728 { 1729 bfa_trc(ioim->bfa, ioim->iotag); 1730 bfa_trc(ioim->bfa, event); 1731 1732 switch (event) { 1733 case BFA_IOIM_SM_COMP_GOOD: 1734 case BFA_IOIM_SM_COMP: 1735 case BFA_IOIM_SM_DONE: 1736 case BFA_IOIM_SM_FREE: 1737 break; 1738 1739 case BFA_IOIM_SM_ABORT: 1740 /* 1741 * IO is already being aborted implicitly 1742 */ 1743 ioim->io_cbfn = __bfa_cb_ioim_abort; 1744 break; 1745 1746 case BFA_IOIM_SM_ABORT_DONE: 1747 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1748 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 1749 bfa_ioim_notify_cleanup(ioim); 1750 break; 1751 1752 case BFA_IOIM_SM_ABORT_COMP: 1753 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1754 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 1755 bfa_ioim_notify_cleanup(ioim); 1756 break; 1757 1758 case BFA_IOIM_SM_COMP_UTAG: 1759 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1760 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 1761 bfa_ioim_notify_cleanup(ioim); 1762 break; 1763 1764 case BFA_IOIM_SM_HWFAIL: 1765 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1766 bfa_ioim_move_to_comp_q(ioim); 1767 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1768 ioim); 1769 break; 1770 1771 case BFA_IOIM_SM_CLEANUP: 1772 /* 1773 * IO can be in cleanup state already due to TM command. 1774 * 2nd cleanup request comes from ITN offline event. 1775 */ 1776 break; 1777 1778 default: 1779 bfa_sm_fault(ioim->bfa, event); 1780 } 1781 } 1782 1783 /* 1784 * IO is waiting for room in request CQ 1785 */ 1786 static void 1787 bfa_ioim_sm_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1788 { 1789 bfa_trc(ioim->bfa, ioim->iotag); 1790 bfa_trc(ioim->bfa, event); 1791 1792 switch (event) { 1793 case BFA_IOIM_SM_QRESUME: 1794 bfa_sm_set_state(ioim, bfa_ioim_sm_active); 1795 bfa_ioim_send_ioreq(ioim); 1796 break; 1797 1798 case BFA_IOIM_SM_ABORT: 1799 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1800 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1801 bfa_ioim_move_to_comp_q(ioim); 1802 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1803 ioim); 1804 break; 1805 1806 case BFA_IOIM_SM_CLEANUP: 1807 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1808 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1809 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1810 ioim); 1811 bfa_ioim_notify_cleanup(ioim); 1812 break; 1813 1814 case BFA_IOIM_SM_HWFAIL: 1815 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1816 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1817 bfa_ioim_move_to_comp_q(ioim); 1818 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1819 ioim); 1820 break; 1821 1822 default: 1823 bfa_sm_fault(ioim->bfa, event); 1824 } 1825 } 1826 1827 /* 1828 * Active IO is being aborted, waiting for room in request CQ. 1829 */ 1830 static void 1831 bfa_ioim_sm_abort_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1832 { 1833 bfa_trc(ioim->bfa, ioim->iotag); 1834 bfa_trc(ioim->bfa, event); 1835 1836 switch (event) { 1837 case BFA_IOIM_SM_QRESUME: 1838 bfa_sm_set_state(ioim, bfa_ioim_sm_abort); 1839 bfa_ioim_send_abort(ioim); 1840 break; 1841 1842 case BFA_IOIM_SM_CLEANUP: 1843 WARN_ON(ioim->iosp->abort_explicit != BFA_TRUE); 1844 ioim->iosp->abort_explicit = BFA_FALSE; 1845 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup_qfull); 1846 break; 1847 1848 case BFA_IOIM_SM_COMP_GOOD: 1849 case BFA_IOIM_SM_COMP: 1850 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1851 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1852 bfa_ioim_move_to_comp_q(ioim); 1853 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1854 ioim); 1855 break; 1856 1857 case BFA_IOIM_SM_DONE: 1858 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1859 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1860 bfa_ioim_move_to_comp_q(ioim); 1861 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_abort, 1862 ioim); 1863 break; 1864 1865 case BFA_IOIM_SM_HWFAIL: 1866 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1867 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1868 bfa_ioim_move_to_comp_q(ioim); 1869 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1870 ioim); 1871 break; 1872 1873 default: 1874 bfa_sm_fault(ioim->bfa, event); 1875 } 1876 } 1877 1878 /* 1879 * Active IO is being cleaned up, waiting for room in request CQ. 1880 */ 1881 static void 1882 bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1883 { 1884 bfa_trc(ioim->bfa, ioim->iotag); 1885 bfa_trc(ioim->bfa, event); 1886 1887 switch (event) { 1888 case BFA_IOIM_SM_QRESUME: 1889 bfa_sm_set_state(ioim, bfa_ioim_sm_cleanup); 1890 bfa_ioim_send_abort(ioim); 1891 break; 1892 1893 case BFA_IOIM_SM_ABORT: 1894 /* 1895 * IO is already being cleaned up implicitly 1896 */ 1897 ioim->io_cbfn = __bfa_cb_ioim_abort; 1898 break; 1899 1900 case BFA_IOIM_SM_COMP_GOOD: 1901 case BFA_IOIM_SM_COMP: 1902 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1903 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1904 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 1905 bfa_ioim_notify_cleanup(ioim); 1906 break; 1907 1908 case BFA_IOIM_SM_DONE: 1909 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb_free); 1910 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1911 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 1912 bfa_ioim_notify_cleanup(ioim); 1913 break; 1914 1915 case BFA_IOIM_SM_HWFAIL: 1916 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1917 bfa_reqq_wcancel(&ioim->iosp->reqq_wait); 1918 bfa_ioim_move_to_comp_q(ioim); 1919 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, __bfa_cb_ioim_failed, 1920 ioim); 1921 break; 1922 1923 default: 1924 bfa_sm_fault(ioim->bfa, event); 1925 } 1926 } 1927 1928 /* 1929 * IO bfa callback is pending. 1930 */ 1931 static void 1932 bfa_ioim_sm_hcb(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1933 { 1934 switch (event) { 1935 case BFA_IOIM_SM_HCB: 1936 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); 1937 bfa_ioim_free(ioim); 1938 break; 1939 1940 case BFA_IOIM_SM_CLEANUP: 1941 bfa_ioim_notify_cleanup(ioim); 1942 break; 1943 1944 case BFA_IOIM_SM_HWFAIL: 1945 break; 1946 1947 default: 1948 bfa_sm_fault(ioim->bfa, event); 1949 } 1950 } 1951 1952 /* 1953 * IO bfa callback is pending. IO resource cannot be freed. 1954 */ 1955 static void 1956 bfa_ioim_sm_hcb_free(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1957 { 1958 bfa_trc(ioim->bfa, ioim->iotag); 1959 bfa_trc(ioim->bfa, event); 1960 1961 switch (event) { 1962 case BFA_IOIM_SM_HCB: 1963 bfa_sm_set_state(ioim, bfa_ioim_sm_resfree); 1964 list_del(&ioim->qe); 1965 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_resfree_q); 1966 break; 1967 1968 case BFA_IOIM_SM_FREE: 1969 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1970 break; 1971 1972 case BFA_IOIM_SM_CLEANUP: 1973 bfa_ioim_notify_cleanup(ioim); 1974 break; 1975 1976 case BFA_IOIM_SM_HWFAIL: 1977 bfa_sm_set_state(ioim, bfa_ioim_sm_hcb); 1978 break; 1979 1980 default: 1981 bfa_sm_fault(ioim->bfa, event); 1982 } 1983 } 1984 1985 /* 1986 * IO is completed, waiting resource free from firmware. 1987 */ 1988 static void 1989 bfa_ioim_sm_resfree(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) 1990 { 1991 bfa_trc(ioim->bfa, ioim->iotag); 1992 bfa_trc(ioim->bfa, event); 1993 1994 switch (event) { 1995 case BFA_IOIM_SM_FREE: 1996 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); 1997 bfa_ioim_free(ioim); 1998 break; 1999 2000 case BFA_IOIM_SM_CLEANUP: 2001 bfa_ioim_notify_cleanup(ioim); 2002 break; 2003 2004 case BFA_IOIM_SM_HWFAIL: 2005 break; 2006 2007 default: 2008 bfa_sm_fault(ioim->bfa, event); 2009 } 2010 } 2011 2012 2013 static void 2014 __bfa_cb_ioim_good_comp(void *cbarg, bfa_boolean_t complete) 2015 { 2016 struct bfa_ioim_s *ioim = cbarg; 2017 2018 if (!complete) { 2019 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); 2020 return; 2021 } 2022 2023 bfa_cb_ioim_good_comp(ioim->bfa->bfad, ioim->dio); 2024 } 2025 2026 static void 2027 __bfa_cb_ioim_comp(void *cbarg, bfa_boolean_t complete) 2028 { 2029 struct bfa_ioim_s *ioim = cbarg; 2030 struct bfi_ioim_rsp_s *m; 2031 u8 *snsinfo = NULL; 2032 u8 sns_len = 0; 2033 s32 residue = 0; 2034 2035 if (!complete) { 2036 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); 2037 return; 2038 } 2039 2040 m = (struct bfi_ioim_rsp_s *) &ioim->iosp->comp_rspmsg; 2041 if (m->io_status == BFI_IOIM_STS_OK) { 2042 /* 2043 * setup sense information, if present 2044 */ 2045 if ((m->scsi_status == SCSI_STATUS_CHECK_CONDITION) && 2046 m->sns_len) { 2047 sns_len = m->sns_len; 2048 snsinfo = BFA_SNSINFO_FROM_TAG(ioim->fcpim->fcp, 2049 ioim->iotag); 2050 } 2051 2052 /* 2053 * setup residue value correctly for normal completions 2054 */ 2055 if (m->resid_flags == FCP_RESID_UNDER) { 2056 residue = be32_to_cpu(m->residue); 2057 bfa_stats(ioim->itnim, iocomp_underrun); 2058 } 2059 if (m->resid_flags == FCP_RESID_OVER) { 2060 residue = be32_to_cpu(m->residue); 2061 residue = -residue; 2062 bfa_stats(ioim->itnim, iocomp_overrun); 2063 } 2064 } 2065 2066 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, m->io_status, 2067 m->scsi_status, sns_len, snsinfo, residue); 2068 } 2069 2070 static void 2071 __bfa_cb_ioim_failed(void *cbarg, bfa_boolean_t complete) 2072 { 2073 struct bfa_ioim_s *ioim = cbarg; 2074 2075 if (!complete) { 2076 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); 2077 return; 2078 } 2079 2080 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_ABORTED, 2081 0, 0, NULL, 0); 2082 } 2083 2084 static void 2085 __bfa_cb_ioim_pathtov(void *cbarg, bfa_boolean_t complete) 2086 { 2087 struct bfa_ioim_s *ioim = cbarg; 2088 2089 bfa_stats(ioim->itnim, path_tov_expired); 2090 if (!complete) { 2091 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); 2092 return; 2093 } 2094 2095 bfa_cb_ioim_done(ioim->bfa->bfad, ioim->dio, BFI_IOIM_STS_PATHTOV, 2096 0, 0, NULL, 0); 2097 } 2098 2099 static void 2100 __bfa_cb_ioim_abort(void *cbarg, bfa_boolean_t complete) 2101 { 2102 struct bfa_ioim_s *ioim = cbarg; 2103 2104 if (!complete) { 2105 bfa_sm_send_event(ioim, BFA_IOIM_SM_HCB); 2106 return; 2107 } 2108 2109 bfa_cb_ioim_abort(ioim->bfa->bfad, ioim->dio); 2110 } 2111 2112 static void 2113 bfa_ioim_sgpg_alloced(void *cbarg) 2114 { 2115 struct bfa_ioim_s *ioim = cbarg; 2116 2117 ioim->nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); 2118 list_splice_tail_init(&ioim->iosp->sgpg_wqe.sgpg_q, &ioim->sgpg_q); 2119 ioim->sgpg = bfa_q_first(&ioim->sgpg_q); 2120 bfa_sm_send_event(ioim, BFA_IOIM_SM_SGALLOCED); 2121 } 2122 2123 /* 2124 * Send I/O request to firmware. 2125 */ 2126 static bfa_boolean_t 2127 bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim) 2128 { 2129 struct bfa_itnim_s *itnim = ioim->itnim; 2130 struct bfi_ioim_req_s *m; 2131 static struct fcp_cmnd_s cmnd_z0 = { { { 0 } } }; 2132 struct bfi_sge_s *sge, *sgpge; 2133 u32 pgdlen = 0; 2134 u32 fcp_dl; 2135 u64 addr; 2136 struct scatterlist *sg; 2137 struct bfa_sgpg_s *sgpg; 2138 struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio; 2139 u32 i, sge_id, pgcumsz; 2140 enum dma_data_direction dmadir; 2141 2142 /* 2143 * check for room in queue to send request now 2144 */ 2145 m = bfa_reqq_next(ioim->bfa, ioim->reqq); 2146 if (!m) { 2147 bfa_stats(ioim->itnim, qwait); 2148 bfa_reqq_wait(ioim->bfa, ioim->reqq, 2149 &ioim->iosp->reqq_wait); 2150 return BFA_FALSE; 2151 } 2152 2153 /* 2154 * build i/o request message next 2155 */ 2156 m->io_tag = cpu_to_be16(ioim->iotag); 2157 m->rport_hdl = ioim->itnim->rport->fw_handle; 2158 m->io_timeout = 0; 2159 2160 sge = &m->sges[0]; 2161 sgpg = ioim->sgpg; 2162 sge_id = 0; 2163 sgpge = NULL; 2164 pgcumsz = 0; 2165 scsi_for_each_sg(cmnd, sg, ioim->nsges, i) { 2166 if (i == 0) { 2167 /* build inline IO SG element */ 2168 addr = bfa_sgaddr_le(sg_dma_address(sg)); 2169 sge->sga = *(union bfi_addr_u *) &addr; 2170 pgdlen = sg_dma_len(sg); 2171 sge->sg_len = pgdlen; 2172 sge->flags = (ioim->nsges > BFI_SGE_INLINE) ? 2173 BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST; 2174 bfa_sge_to_be(sge); 2175 sge++; 2176 } else { 2177 if (sge_id == 0) 2178 sgpge = sgpg->sgpg->sges; 2179 2180 addr = bfa_sgaddr_le(sg_dma_address(sg)); 2181 sgpge->sga = *(union bfi_addr_u *) &addr; 2182 sgpge->sg_len = sg_dma_len(sg); 2183 pgcumsz += sgpge->sg_len; 2184 2185 /* set flags */ 2186 if (i < (ioim->nsges - 1) && 2187 sge_id < (BFI_SGPG_DATA_SGES - 1)) 2188 sgpge->flags = BFI_SGE_DATA; 2189 else if (i < (ioim->nsges - 1)) 2190 sgpge->flags = BFI_SGE_DATA_CPL; 2191 else 2192 sgpge->flags = BFI_SGE_DATA_LAST; 2193 2194 bfa_sge_to_le(sgpge); 2195 2196 sgpge++; 2197 if (i == (ioim->nsges - 1)) { 2198 sgpge->flags = BFI_SGE_PGDLEN; 2199 sgpge->sga.a32.addr_lo = 0; 2200 sgpge->sga.a32.addr_hi = 0; 2201 sgpge->sg_len = pgcumsz; 2202 bfa_sge_to_le(sgpge); 2203 } else if (++sge_id == BFI_SGPG_DATA_SGES) { 2204 sgpg = (struct bfa_sgpg_s *) bfa_q_next(sgpg); 2205 sgpge->flags = BFI_SGE_LINK; 2206 sgpge->sga = sgpg->sgpg_pa; 2207 sgpge->sg_len = pgcumsz; 2208 bfa_sge_to_le(sgpge); 2209 sge_id = 0; 2210 pgcumsz = 0; 2211 } 2212 } 2213 } 2214 2215 if (ioim->nsges > BFI_SGE_INLINE) { 2216 sge->sga = ioim->sgpg->sgpg_pa; 2217 } else { 2218 sge->sga.a32.addr_lo = 0; 2219 sge->sga.a32.addr_hi = 0; 2220 } 2221 sge->sg_len = pgdlen; 2222 sge->flags = BFI_SGE_PGDLEN; 2223 bfa_sge_to_be(sge); 2224 2225 /* 2226 * set up I/O command parameters 2227 */ 2228 m->cmnd = cmnd_z0; 2229 int_to_scsilun(cmnd->device->lun, &m->cmnd.lun); 2230 dmadir = cmnd->sc_data_direction; 2231 if (dmadir == DMA_TO_DEVICE) 2232 m->cmnd.iodir = FCP_IODIR_WRITE; 2233 else if (dmadir == DMA_FROM_DEVICE) 2234 m->cmnd.iodir = FCP_IODIR_READ; 2235 else 2236 m->cmnd.iodir = FCP_IODIR_NONE; 2237 2238 m->cmnd.cdb = *(struct scsi_cdb_s *) cmnd->cmnd; 2239 fcp_dl = scsi_bufflen(cmnd); 2240 m->cmnd.fcp_dl = cpu_to_be32(fcp_dl); 2241 2242 /* 2243 * set up I/O message header 2244 */ 2245 switch (m->cmnd.iodir) { 2246 case FCP_IODIR_READ: 2247 bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_fn_lpu(ioim->bfa)); 2248 bfa_stats(itnim, input_reqs); 2249 ioim->itnim->stats.rd_throughput += fcp_dl; 2250 break; 2251 case FCP_IODIR_WRITE: 2252 bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_fn_lpu(ioim->bfa)); 2253 bfa_stats(itnim, output_reqs); 2254 ioim->itnim->stats.wr_throughput += fcp_dl; 2255 break; 2256 case FCP_IODIR_RW: 2257 bfa_stats(itnim, input_reqs); 2258 bfa_stats(itnim, output_reqs); 2259 default: 2260 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa)); 2261 } 2262 if (itnim->seq_rec || 2263 (scsi_bufflen(cmnd) & (sizeof(u32) - 1))) 2264 bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_fn_lpu(ioim->bfa)); 2265 2266 /* 2267 * queue I/O message to firmware 2268 */ 2269 bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh); 2270 return BFA_TRUE; 2271 } 2272 2273 /* 2274 * Setup any additional SG pages needed.Inline SG element is setup 2275 * at queuing time. 2276 */ 2277 static bfa_boolean_t 2278 bfa_ioim_sgpg_alloc(struct bfa_ioim_s *ioim) 2279 { 2280 u16 nsgpgs; 2281 2282 WARN_ON(ioim->nsges <= BFI_SGE_INLINE); 2283 2284 /* 2285 * allocate SG pages needed 2286 */ 2287 nsgpgs = BFA_SGPG_NPAGE(ioim->nsges); 2288 if (!nsgpgs) 2289 return BFA_TRUE; 2290 2291 if (bfa_sgpg_malloc(ioim->bfa, &ioim->sgpg_q, nsgpgs) 2292 != BFA_STATUS_OK) { 2293 bfa_sgpg_wait(ioim->bfa, &ioim->iosp->sgpg_wqe, nsgpgs); 2294 return BFA_FALSE; 2295 } 2296 2297 ioim->nsgpgs = nsgpgs; 2298 ioim->sgpg = bfa_q_first(&ioim->sgpg_q); 2299 2300 return BFA_TRUE; 2301 } 2302 2303 /* 2304 * Send I/O abort request to firmware. 2305 */ 2306 static bfa_boolean_t 2307 bfa_ioim_send_abort(struct bfa_ioim_s *ioim) 2308 { 2309 struct bfi_ioim_abort_req_s *m; 2310 enum bfi_ioim_h2i msgop; 2311 2312 /* 2313 * check for room in queue to send request now 2314 */ 2315 m = bfa_reqq_next(ioim->bfa, ioim->reqq); 2316 if (!m) 2317 return BFA_FALSE; 2318 2319 /* 2320 * build i/o request message next 2321 */ 2322 if (ioim->iosp->abort_explicit) 2323 msgop = BFI_IOIM_H2I_IOABORT_REQ; 2324 else 2325 msgop = BFI_IOIM_H2I_IOCLEANUP_REQ; 2326 2327 bfi_h2i_set(m->mh, BFI_MC_IOIM, msgop, bfa_fn_lpu(ioim->bfa)); 2328 m->io_tag = cpu_to_be16(ioim->iotag); 2329 m->abort_tag = ++ioim->abort_tag; 2330 2331 /* 2332 * queue I/O message to firmware 2333 */ 2334 bfa_reqq_produce(ioim->bfa, ioim->reqq, m->mh); 2335 return BFA_TRUE; 2336 } 2337 2338 /* 2339 * Call to resume any I/O requests waiting for room in request queue. 2340 */ 2341 static void 2342 bfa_ioim_qresume(void *cbarg) 2343 { 2344 struct bfa_ioim_s *ioim = cbarg; 2345 2346 bfa_stats(ioim->itnim, qresumes); 2347 bfa_sm_send_event(ioim, BFA_IOIM_SM_QRESUME); 2348 } 2349 2350 2351 static void 2352 bfa_ioim_notify_cleanup(struct bfa_ioim_s *ioim) 2353 { 2354 /* 2355 * Move IO from itnim queue to fcpim global queue since itnim will be 2356 * freed. 2357 */ 2358 list_del(&ioim->qe); 2359 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); 2360 2361 if (!ioim->iosp->tskim) { 2362 if (ioim->fcpim->delay_comp && ioim->itnim->iotov_active) { 2363 bfa_cb_dequeue(&ioim->hcb_qe); 2364 list_del(&ioim->qe); 2365 list_add_tail(&ioim->qe, &ioim->itnim->delay_comp_q); 2366 } 2367 bfa_itnim_iodone(ioim->itnim); 2368 } else 2369 bfa_wc_down(&ioim->iosp->tskim->wc); 2370 } 2371 2372 static bfa_boolean_t 2373 bfa_ioim_is_abortable(struct bfa_ioim_s *ioim) 2374 { 2375 if ((bfa_sm_cmp_state(ioim, bfa_ioim_sm_uninit) && 2376 (!bfa_q_is_on_q(&ioim->itnim->pending_q, ioim))) || 2377 (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort)) || 2378 (bfa_sm_cmp_state(ioim, bfa_ioim_sm_abort_qfull)) || 2379 (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb)) || 2380 (bfa_sm_cmp_state(ioim, bfa_ioim_sm_hcb_free)) || 2381 (bfa_sm_cmp_state(ioim, bfa_ioim_sm_resfree))) 2382 return BFA_FALSE; 2383 2384 return BFA_TRUE; 2385 } 2386 2387 void 2388 bfa_ioim_delayed_comp(struct bfa_ioim_s *ioim, bfa_boolean_t iotov) 2389 { 2390 /* 2391 * If path tov timer expired, failback with PATHTOV status - these 2392 * IO requests are not normally retried by IO stack. 2393 * 2394 * Otherwise device cameback online and fail it with normal failed 2395 * status so that IO stack retries these failed IO requests. 2396 */ 2397 if (iotov) 2398 ioim->io_cbfn = __bfa_cb_ioim_pathtov; 2399 else { 2400 ioim->io_cbfn = __bfa_cb_ioim_failed; 2401 bfa_stats(ioim->itnim, iocom_nexus_abort); 2402 } 2403 bfa_cb_queue(ioim->bfa, &ioim->hcb_qe, ioim->io_cbfn, ioim); 2404 2405 /* 2406 * Move IO to fcpim global queue since itnim will be 2407 * freed. 2408 */ 2409 list_del(&ioim->qe); 2410 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); 2411 } 2412 2413 2414 /* 2415 * Memory allocation and initialization. 2416 */ 2417 void 2418 bfa_ioim_attach(struct bfa_fcpim_s *fcpim) 2419 { 2420 struct bfa_ioim_s *ioim; 2421 struct bfa_fcp_mod_s *fcp = fcpim->fcp; 2422 struct bfa_ioim_sp_s *iosp; 2423 u16 i; 2424 2425 /* 2426 * claim memory first 2427 */ 2428 ioim = (struct bfa_ioim_s *) bfa_mem_kva_curp(fcp); 2429 fcpim->ioim_arr = ioim; 2430 bfa_mem_kva_curp(fcp) = (u8 *) (ioim + fcpim->fcp->num_ioim_reqs); 2431 2432 iosp = (struct bfa_ioim_sp_s *) bfa_mem_kva_curp(fcp); 2433 fcpim->ioim_sp_arr = iosp; 2434 bfa_mem_kva_curp(fcp) = (u8 *) (iosp + fcpim->fcp->num_ioim_reqs); 2435 2436 /* 2437 * Initialize ioim free queues 2438 */ 2439 INIT_LIST_HEAD(&fcpim->ioim_resfree_q); 2440 INIT_LIST_HEAD(&fcpim->ioim_comp_q); 2441 2442 for (i = 0; i < fcpim->fcp->num_ioim_reqs; 2443 i++, ioim++, iosp++) { 2444 /* 2445 * initialize IOIM 2446 */ 2447 memset(ioim, 0, sizeof(struct bfa_ioim_s)); 2448 ioim->iotag = i; 2449 ioim->bfa = fcpim->bfa; 2450 ioim->fcpim = fcpim; 2451 ioim->iosp = iosp; 2452 INIT_LIST_HEAD(&ioim->sgpg_q); 2453 bfa_reqq_winit(&ioim->iosp->reqq_wait, 2454 bfa_ioim_qresume, ioim); 2455 bfa_sgpg_winit(&ioim->iosp->sgpg_wqe, 2456 bfa_ioim_sgpg_alloced, ioim); 2457 bfa_sm_set_state(ioim, bfa_ioim_sm_uninit); 2458 } 2459 } 2460 2461 void 2462 bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 2463 { 2464 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 2465 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m; 2466 struct bfa_ioim_s *ioim; 2467 u16 iotag; 2468 enum bfa_ioim_event evt = BFA_IOIM_SM_COMP; 2469 2470 iotag = be16_to_cpu(rsp->io_tag); 2471 2472 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); 2473 WARN_ON(ioim->iotag != iotag); 2474 2475 bfa_trc(ioim->bfa, ioim->iotag); 2476 bfa_trc(ioim->bfa, rsp->io_status); 2477 bfa_trc(ioim->bfa, rsp->reuse_io_tag); 2478 2479 if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active)) 2480 ioim->iosp->comp_rspmsg = *m; 2481 2482 switch (rsp->io_status) { 2483 case BFI_IOIM_STS_OK: 2484 bfa_stats(ioim->itnim, iocomp_ok); 2485 if (rsp->reuse_io_tag == 0) 2486 evt = BFA_IOIM_SM_DONE; 2487 else 2488 evt = BFA_IOIM_SM_COMP; 2489 break; 2490 2491 case BFI_IOIM_STS_TIMEDOUT: 2492 bfa_stats(ioim->itnim, iocomp_timedout); 2493 case BFI_IOIM_STS_ABORTED: 2494 rsp->io_status = BFI_IOIM_STS_ABORTED; 2495 bfa_stats(ioim->itnim, iocomp_aborted); 2496 if (rsp->reuse_io_tag == 0) 2497 evt = BFA_IOIM_SM_DONE; 2498 else 2499 evt = BFA_IOIM_SM_COMP; 2500 break; 2501 2502 case BFI_IOIM_STS_PROTO_ERR: 2503 bfa_stats(ioim->itnim, iocom_proto_err); 2504 WARN_ON(!rsp->reuse_io_tag); 2505 evt = BFA_IOIM_SM_COMP; 2506 break; 2507 2508 case BFI_IOIM_STS_SQER_NEEDED: 2509 bfa_stats(ioim->itnim, iocom_sqer_needed); 2510 WARN_ON(rsp->reuse_io_tag != 0); 2511 evt = BFA_IOIM_SM_SQRETRY; 2512 break; 2513 2514 case BFI_IOIM_STS_RES_FREE: 2515 bfa_stats(ioim->itnim, iocom_res_free); 2516 evt = BFA_IOIM_SM_FREE; 2517 break; 2518 2519 case BFI_IOIM_STS_HOST_ABORTED: 2520 bfa_stats(ioim->itnim, iocom_hostabrts); 2521 if (rsp->abort_tag != ioim->abort_tag) { 2522 bfa_trc(ioim->bfa, rsp->abort_tag); 2523 bfa_trc(ioim->bfa, ioim->abort_tag); 2524 return; 2525 } 2526 2527 if (rsp->reuse_io_tag) 2528 evt = BFA_IOIM_SM_ABORT_COMP; 2529 else 2530 evt = BFA_IOIM_SM_ABORT_DONE; 2531 break; 2532 2533 case BFI_IOIM_STS_UTAG: 2534 bfa_stats(ioim->itnim, iocom_utags); 2535 evt = BFA_IOIM_SM_COMP_UTAG; 2536 break; 2537 2538 default: 2539 WARN_ON(1); 2540 } 2541 2542 bfa_sm_send_event(ioim, evt); 2543 } 2544 2545 void 2546 bfa_ioim_good_comp_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 2547 { 2548 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 2549 struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m; 2550 struct bfa_ioim_s *ioim; 2551 u16 iotag; 2552 2553 iotag = be16_to_cpu(rsp->io_tag); 2554 2555 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); 2556 WARN_ON(BFA_IOIM_TAG_2_ID(ioim->iotag) != iotag); 2557 2558 bfa_ioim_cb_profile_comp(fcpim, ioim); 2559 bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); 2560 } 2561 2562 /* 2563 * Called by itnim to clean up IO while going offline. 2564 */ 2565 void 2566 bfa_ioim_cleanup(struct bfa_ioim_s *ioim) 2567 { 2568 bfa_trc(ioim->bfa, ioim->iotag); 2569 bfa_stats(ioim->itnim, io_cleanups); 2570 2571 ioim->iosp->tskim = NULL; 2572 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP); 2573 } 2574 2575 void 2576 bfa_ioim_cleanup_tm(struct bfa_ioim_s *ioim, struct bfa_tskim_s *tskim) 2577 { 2578 bfa_trc(ioim->bfa, ioim->iotag); 2579 bfa_stats(ioim->itnim, io_tmaborts); 2580 2581 ioim->iosp->tskim = tskim; 2582 bfa_sm_send_event(ioim, BFA_IOIM_SM_CLEANUP); 2583 } 2584 2585 /* 2586 * IOC failure handling. 2587 */ 2588 void 2589 bfa_ioim_iocdisable(struct bfa_ioim_s *ioim) 2590 { 2591 bfa_trc(ioim->bfa, ioim->iotag); 2592 bfa_stats(ioim->itnim, io_iocdowns); 2593 bfa_sm_send_event(ioim, BFA_IOIM_SM_HWFAIL); 2594 } 2595 2596 /* 2597 * IO offline TOV popped. Fail the pending IO. 2598 */ 2599 void 2600 bfa_ioim_tov(struct bfa_ioim_s *ioim) 2601 { 2602 bfa_trc(ioim->bfa, ioim->iotag); 2603 bfa_sm_send_event(ioim, BFA_IOIM_SM_IOTOV); 2604 } 2605 2606 2607 /* 2608 * Allocate IOIM resource for initiator mode I/O request. 2609 */ 2610 struct bfa_ioim_s * 2611 bfa_ioim_alloc(struct bfa_s *bfa, struct bfad_ioim_s *dio, 2612 struct bfa_itnim_s *itnim, u16 nsges) 2613 { 2614 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 2615 struct bfa_ioim_s *ioim; 2616 struct bfa_iotag_s *iotag = NULL; 2617 2618 /* 2619 * alocate IOIM resource 2620 */ 2621 bfa_q_deq(&fcpim->fcp->iotag_ioim_free_q, &iotag); 2622 if (!iotag) { 2623 bfa_stats(itnim, no_iotags); 2624 return NULL; 2625 } 2626 2627 ioim = BFA_IOIM_FROM_TAG(fcpim, iotag->tag); 2628 2629 ioim->dio = dio; 2630 ioim->itnim = itnim; 2631 ioim->nsges = nsges; 2632 ioim->nsgpgs = 0; 2633 2634 bfa_stats(itnim, total_ios); 2635 fcpim->ios_active++; 2636 2637 list_add_tail(&ioim->qe, &itnim->io_q); 2638 2639 return ioim; 2640 } 2641 2642 void 2643 bfa_ioim_free(struct bfa_ioim_s *ioim) 2644 { 2645 struct bfa_fcpim_s *fcpim = ioim->fcpim; 2646 struct bfa_iotag_s *iotag; 2647 2648 if (ioim->nsgpgs > 0) 2649 bfa_sgpg_mfree(ioim->bfa, &ioim->sgpg_q, ioim->nsgpgs); 2650 2651 bfa_stats(ioim->itnim, io_comps); 2652 fcpim->ios_active--; 2653 2654 ioim->iotag &= BFA_IOIM_IOTAG_MASK; 2655 2656 WARN_ON(!(ioim->iotag < 2657 (fcpim->fcp->num_ioim_reqs + fcpim->fcp->num_fwtio_reqs))); 2658 iotag = BFA_IOTAG_FROM_TAG(fcpim->fcp, ioim->iotag); 2659 2660 if (ioim->iotag < fcpim->fcp->num_ioim_reqs) 2661 list_add_tail(&iotag->qe, &fcpim->fcp->iotag_ioim_free_q); 2662 else 2663 list_add_tail(&iotag->qe, &fcpim->fcp->iotag_tio_free_q); 2664 2665 list_del(&ioim->qe); 2666 } 2667 2668 void 2669 bfa_ioim_start(struct bfa_ioim_s *ioim) 2670 { 2671 bfa_ioim_cb_profile_start(ioim->fcpim, ioim); 2672 2673 /* 2674 * Obtain the queue over which this request has to be issued 2675 */ 2676 ioim->reqq = bfa_fcpim_ioredirect_enabled(ioim->bfa) ? 2677 BFA_FALSE : bfa_itnim_get_reqq(ioim); 2678 2679 bfa_sm_send_event(ioim, BFA_IOIM_SM_START); 2680 } 2681 2682 /* 2683 * Driver I/O abort request. 2684 */ 2685 bfa_status_t 2686 bfa_ioim_abort(struct bfa_ioim_s *ioim) 2687 { 2688 2689 bfa_trc(ioim->bfa, ioim->iotag); 2690 2691 if (!bfa_ioim_is_abortable(ioim)) 2692 return BFA_STATUS_FAILED; 2693 2694 bfa_stats(ioim->itnim, io_aborts); 2695 bfa_sm_send_event(ioim, BFA_IOIM_SM_ABORT); 2696 2697 return BFA_STATUS_OK; 2698 } 2699 2700 /* 2701 * BFA TSKIM state machine functions 2702 */ 2703 2704 /* 2705 * Task management command beginning state. 2706 */ 2707 static void 2708 bfa_tskim_sm_uninit(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2709 { 2710 bfa_trc(tskim->bfa, event); 2711 2712 switch (event) { 2713 case BFA_TSKIM_SM_START: 2714 bfa_sm_set_state(tskim, bfa_tskim_sm_active); 2715 bfa_tskim_gather_ios(tskim); 2716 2717 /* 2718 * If device is offline, do not send TM on wire. Just cleanup 2719 * any pending IO requests and complete TM request. 2720 */ 2721 if (!bfa_itnim_is_online(tskim->itnim)) { 2722 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); 2723 tskim->tsk_status = BFI_TSKIM_STS_OK; 2724 bfa_tskim_cleanup_ios(tskim); 2725 return; 2726 } 2727 2728 if (!bfa_tskim_send(tskim)) { 2729 bfa_sm_set_state(tskim, bfa_tskim_sm_qfull); 2730 bfa_stats(tskim->itnim, tm_qwait); 2731 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq, 2732 &tskim->reqq_wait); 2733 } 2734 break; 2735 2736 default: 2737 bfa_sm_fault(tskim->bfa, event); 2738 } 2739 } 2740 2741 /* 2742 * TM command is active, awaiting completion from firmware to 2743 * cleanup IO requests in TM scope. 2744 */ 2745 static void 2746 bfa_tskim_sm_active(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2747 { 2748 bfa_trc(tskim->bfa, event); 2749 2750 switch (event) { 2751 case BFA_TSKIM_SM_DONE: 2752 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); 2753 bfa_tskim_cleanup_ios(tskim); 2754 break; 2755 2756 case BFA_TSKIM_SM_CLEANUP: 2757 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup); 2758 if (!bfa_tskim_send_abort(tskim)) { 2759 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup_qfull); 2760 bfa_stats(tskim->itnim, tm_qwait); 2761 bfa_reqq_wait(tskim->bfa, tskim->itnim->reqq, 2762 &tskim->reqq_wait); 2763 } 2764 break; 2765 2766 case BFA_TSKIM_SM_HWFAIL: 2767 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2768 bfa_tskim_iocdisable_ios(tskim); 2769 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); 2770 break; 2771 2772 default: 2773 bfa_sm_fault(tskim->bfa, event); 2774 } 2775 } 2776 2777 /* 2778 * An active TM is being cleaned up since ITN is offline. Awaiting cleanup 2779 * completion event from firmware. 2780 */ 2781 static void 2782 bfa_tskim_sm_cleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2783 { 2784 bfa_trc(tskim->bfa, event); 2785 2786 switch (event) { 2787 case BFA_TSKIM_SM_DONE: 2788 /* 2789 * Ignore and wait for ABORT completion from firmware. 2790 */ 2791 break; 2792 2793 case BFA_TSKIM_SM_CLEANUP_DONE: 2794 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); 2795 bfa_tskim_cleanup_ios(tskim); 2796 break; 2797 2798 case BFA_TSKIM_SM_HWFAIL: 2799 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2800 bfa_tskim_iocdisable_ios(tskim); 2801 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); 2802 break; 2803 2804 default: 2805 bfa_sm_fault(tskim->bfa, event); 2806 } 2807 } 2808 2809 static void 2810 bfa_tskim_sm_iocleanup(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2811 { 2812 bfa_trc(tskim->bfa, event); 2813 2814 switch (event) { 2815 case BFA_TSKIM_SM_IOS_DONE: 2816 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2817 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_done); 2818 break; 2819 2820 case BFA_TSKIM_SM_CLEANUP: 2821 /* 2822 * Ignore, TM command completed on wire. 2823 * Notify TM conmpletion on IO cleanup completion. 2824 */ 2825 break; 2826 2827 case BFA_TSKIM_SM_HWFAIL: 2828 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2829 bfa_tskim_iocdisable_ios(tskim); 2830 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); 2831 break; 2832 2833 default: 2834 bfa_sm_fault(tskim->bfa, event); 2835 } 2836 } 2837 2838 /* 2839 * Task management command is waiting for room in request CQ 2840 */ 2841 static void 2842 bfa_tskim_sm_qfull(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2843 { 2844 bfa_trc(tskim->bfa, event); 2845 2846 switch (event) { 2847 case BFA_TSKIM_SM_QRESUME: 2848 bfa_sm_set_state(tskim, bfa_tskim_sm_active); 2849 bfa_tskim_send(tskim); 2850 break; 2851 2852 case BFA_TSKIM_SM_CLEANUP: 2853 /* 2854 * No need to send TM on wire since ITN is offline. 2855 */ 2856 bfa_sm_set_state(tskim, bfa_tskim_sm_iocleanup); 2857 bfa_reqq_wcancel(&tskim->reqq_wait); 2858 bfa_tskim_cleanup_ios(tskim); 2859 break; 2860 2861 case BFA_TSKIM_SM_HWFAIL: 2862 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2863 bfa_reqq_wcancel(&tskim->reqq_wait); 2864 bfa_tskim_iocdisable_ios(tskim); 2865 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); 2866 break; 2867 2868 default: 2869 bfa_sm_fault(tskim->bfa, event); 2870 } 2871 } 2872 2873 /* 2874 * Task management command is active, awaiting for room in request CQ 2875 * to send clean up request. 2876 */ 2877 static void 2878 bfa_tskim_sm_cleanup_qfull(struct bfa_tskim_s *tskim, 2879 enum bfa_tskim_event event) 2880 { 2881 bfa_trc(tskim->bfa, event); 2882 2883 switch (event) { 2884 case BFA_TSKIM_SM_DONE: 2885 bfa_reqq_wcancel(&tskim->reqq_wait); 2886 /* 2887 * Fall through !!! 2888 */ 2889 case BFA_TSKIM_SM_QRESUME: 2890 bfa_sm_set_state(tskim, bfa_tskim_sm_cleanup); 2891 bfa_tskim_send_abort(tskim); 2892 break; 2893 2894 case BFA_TSKIM_SM_HWFAIL: 2895 bfa_sm_set_state(tskim, bfa_tskim_sm_hcb); 2896 bfa_reqq_wcancel(&tskim->reqq_wait); 2897 bfa_tskim_iocdisable_ios(tskim); 2898 bfa_tskim_qcomp(tskim, __bfa_cb_tskim_failed); 2899 break; 2900 2901 default: 2902 bfa_sm_fault(tskim->bfa, event); 2903 } 2904 } 2905 2906 /* 2907 * BFA callback is pending 2908 */ 2909 static void 2910 bfa_tskim_sm_hcb(struct bfa_tskim_s *tskim, enum bfa_tskim_event event) 2911 { 2912 bfa_trc(tskim->bfa, event); 2913 2914 switch (event) { 2915 case BFA_TSKIM_SM_HCB: 2916 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit); 2917 bfa_tskim_free(tskim); 2918 break; 2919 2920 case BFA_TSKIM_SM_CLEANUP: 2921 bfa_tskim_notify_comp(tskim); 2922 break; 2923 2924 case BFA_TSKIM_SM_HWFAIL: 2925 break; 2926 2927 default: 2928 bfa_sm_fault(tskim->bfa, event); 2929 } 2930 } 2931 2932 static void 2933 __bfa_cb_tskim_done(void *cbarg, bfa_boolean_t complete) 2934 { 2935 struct bfa_tskim_s *tskim = cbarg; 2936 2937 if (!complete) { 2938 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB); 2939 return; 2940 } 2941 2942 bfa_stats(tskim->itnim, tm_success); 2943 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, tskim->tsk_status); 2944 } 2945 2946 static void 2947 __bfa_cb_tskim_failed(void *cbarg, bfa_boolean_t complete) 2948 { 2949 struct bfa_tskim_s *tskim = cbarg; 2950 2951 if (!complete) { 2952 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HCB); 2953 return; 2954 } 2955 2956 bfa_stats(tskim->itnim, tm_failures); 2957 bfa_cb_tskim_done(tskim->bfa->bfad, tskim->dtsk, 2958 BFI_TSKIM_STS_FAILED); 2959 } 2960 2961 static bfa_boolean_t 2962 bfa_tskim_match_scope(struct bfa_tskim_s *tskim, struct scsi_lun lun) 2963 { 2964 switch (tskim->tm_cmnd) { 2965 case FCP_TM_TARGET_RESET: 2966 return BFA_TRUE; 2967 2968 case FCP_TM_ABORT_TASK_SET: 2969 case FCP_TM_CLEAR_TASK_SET: 2970 case FCP_TM_LUN_RESET: 2971 case FCP_TM_CLEAR_ACA: 2972 return !memcmp(&tskim->lun, &lun, sizeof(lun)); 2973 2974 default: 2975 WARN_ON(1); 2976 } 2977 2978 return BFA_FALSE; 2979 } 2980 2981 /* 2982 * Gather affected IO requests and task management commands. 2983 */ 2984 static void 2985 bfa_tskim_gather_ios(struct bfa_tskim_s *tskim) 2986 { 2987 struct bfa_itnim_s *itnim = tskim->itnim; 2988 struct bfa_ioim_s *ioim; 2989 struct list_head *qe, *qen; 2990 struct scsi_cmnd *cmnd; 2991 struct scsi_lun scsilun; 2992 2993 INIT_LIST_HEAD(&tskim->io_q); 2994 2995 /* 2996 * Gather any active IO requests first. 2997 */ 2998 list_for_each_safe(qe, qen, &itnim->io_q) { 2999 ioim = (struct bfa_ioim_s *) qe; 3000 cmnd = (struct scsi_cmnd *) ioim->dio; 3001 int_to_scsilun(cmnd->device->lun, &scsilun); 3002 if (bfa_tskim_match_scope(tskim, scsilun)) { 3003 list_del(&ioim->qe); 3004 list_add_tail(&ioim->qe, &tskim->io_q); 3005 } 3006 } 3007 3008 /* 3009 * Failback any pending IO requests immediately. 3010 */ 3011 list_for_each_safe(qe, qen, &itnim->pending_q) { 3012 ioim = (struct bfa_ioim_s *) qe; 3013 cmnd = (struct scsi_cmnd *) ioim->dio; 3014 int_to_scsilun(cmnd->device->lun, &scsilun); 3015 if (bfa_tskim_match_scope(tskim, scsilun)) { 3016 list_del(&ioim->qe); 3017 list_add_tail(&ioim->qe, &ioim->fcpim->ioim_comp_q); 3018 bfa_ioim_tov(ioim); 3019 } 3020 } 3021 } 3022 3023 /* 3024 * IO cleanup completion 3025 */ 3026 static void 3027 bfa_tskim_cleanp_comp(void *tskim_cbarg) 3028 { 3029 struct bfa_tskim_s *tskim = tskim_cbarg; 3030 3031 bfa_stats(tskim->itnim, tm_io_comps); 3032 bfa_sm_send_event(tskim, BFA_TSKIM_SM_IOS_DONE); 3033 } 3034 3035 /* 3036 * Gather affected IO requests and task management commands. 3037 */ 3038 static void 3039 bfa_tskim_cleanup_ios(struct bfa_tskim_s *tskim) 3040 { 3041 struct bfa_ioim_s *ioim; 3042 struct list_head *qe, *qen; 3043 3044 bfa_wc_init(&tskim->wc, bfa_tskim_cleanp_comp, tskim); 3045 3046 list_for_each_safe(qe, qen, &tskim->io_q) { 3047 ioim = (struct bfa_ioim_s *) qe; 3048 bfa_wc_up(&tskim->wc); 3049 bfa_ioim_cleanup_tm(ioim, tskim); 3050 } 3051 3052 bfa_wc_wait(&tskim->wc); 3053 } 3054 3055 /* 3056 * Send task management request to firmware. 3057 */ 3058 static bfa_boolean_t 3059 bfa_tskim_send(struct bfa_tskim_s *tskim) 3060 { 3061 struct bfa_itnim_s *itnim = tskim->itnim; 3062 struct bfi_tskim_req_s *m; 3063 3064 /* 3065 * check for room in queue to send request now 3066 */ 3067 m = bfa_reqq_next(tskim->bfa, itnim->reqq); 3068 if (!m) 3069 return BFA_FALSE; 3070 3071 /* 3072 * build i/o request message next 3073 */ 3074 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_TM_REQ, 3075 bfa_fn_lpu(tskim->bfa)); 3076 3077 m->tsk_tag = cpu_to_be16(tskim->tsk_tag); 3078 m->itn_fhdl = tskim->itnim->rport->fw_handle; 3079 m->t_secs = tskim->tsecs; 3080 m->lun = tskim->lun; 3081 m->tm_flags = tskim->tm_cmnd; 3082 3083 /* 3084 * queue I/O message to firmware 3085 */ 3086 bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh); 3087 return BFA_TRUE; 3088 } 3089 3090 /* 3091 * Send abort request to cleanup an active TM to firmware. 3092 */ 3093 static bfa_boolean_t 3094 bfa_tskim_send_abort(struct bfa_tskim_s *tskim) 3095 { 3096 struct bfa_itnim_s *itnim = tskim->itnim; 3097 struct bfi_tskim_abortreq_s *m; 3098 3099 /* 3100 * check for room in queue to send request now 3101 */ 3102 m = bfa_reqq_next(tskim->bfa, itnim->reqq); 3103 if (!m) 3104 return BFA_FALSE; 3105 3106 /* 3107 * build i/o request message next 3108 */ 3109 bfi_h2i_set(m->mh, BFI_MC_TSKIM, BFI_TSKIM_H2I_ABORT_REQ, 3110 bfa_fn_lpu(tskim->bfa)); 3111 3112 m->tsk_tag = cpu_to_be16(tskim->tsk_tag); 3113 3114 /* 3115 * queue I/O message to firmware 3116 */ 3117 bfa_reqq_produce(tskim->bfa, itnim->reqq, m->mh); 3118 return BFA_TRUE; 3119 } 3120 3121 /* 3122 * Call to resume task management cmnd waiting for room in request queue. 3123 */ 3124 static void 3125 bfa_tskim_qresume(void *cbarg) 3126 { 3127 struct bfa_tskim_s *tskim = cbarg; 3128 3129 bfa_stats(tskim->itnim, tm_qresumes); 3130 bfa_sm_send_event(tskim, BFA_TSKIM_SM_QRESUME); 3131 } 3132 3133 /* 3134 * Cleanup IOs associated with a task mangement command on IOC failures. 3135 */ 3136 static void 3137 bfa_tskim_iocdisable_ios(struct bfa_tskim_s *tskim) 3138 { 3139 struct bfa_ioim_s *ioim; 3140 struct list_head *qe, *qen; 3141 3142 list_for_each_safe(qe, qen, &tskim->io_q) { 3143 ioim = (struct bfa_ioim_s *) qe; 3144 bfa_ioim_iocdisable(ioim); 3145 } 3146 } 3147 3148 /* 3149 * Notification on completions from related ioim. 3150 */ 3151 void 3152 bfa_tskim_iodone(struct bfa_tskim_s *tskim) 3153 { 3154 bfa_wc_down(&tskim->wc); 3155 } 3156 3157 /* 3158 * Handle IOC h/w failure notification from itnim. 3159 */ 3160 void 3161 bfa_tskim_iocdisable(struct bfa_tskim_s *tskim) 3162 { 3163 tskim->notify = BFA_FALSE; 3164 bfa_stats(tskim->itnim, tm_iocdowns); 3165 bfa_sm_send_event(tskim, BFA_TSKIM_SM_HWFAIL); 3166 } 3167 3168 /* 3169 * Cleanup TM command and associated IOs as part of ITNIM offline. 3170 */ 3171 void 3172 bfa_tskim_cleanup(struct bfa_tskim_s *tskim) 3173 { 3174 tskim->notify = BFA_TRUE; 3175 bfa_stats(tskim->itnim, tm_cleanups); 3176 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP); 3177 } 3178 3179 /* 3180 * Memory allocation and initialization. 3181 */ 3182 void 3183 bfa_tskim_attach(struct bfa_fcpim_s *fcpim) 3184 { 3185 struct bfa_tskim_s *tskim; 3186 struct bfa_fcp_mod_s *fcp = fcpim->fcp; 3187 u16 i; 3188 3189 INIT_LIST_HEAD(&fcpim->tskim_free_q); 3190 INIT_LIST_HEAD(&fcpim->tskim_unused_q); 3191 3192 tskim = (struct bfa_tskim_s *) bfa_mem_kva_curp(fcp); 3193 fcpim->tskim_arr = tskim; 3194 3195 for (i = 0; i < fcpim->num_tskim_reqs; i++, tskim++) { 3196 /* 3197 * initialize TSKIM 3198 */ 3199 memset(tskim, 0, sizeof(struct bfa_tskim_s)); 3200 tskim->tsk_tag = i; 3201 tskim->bfa = fcpim->bfa; 3202 tskim->fcpim = fcpim; 3203 tskim->notify = BFA_FALSE; 3204 bfa_reqq_winit(&tskim->reqq_wait, bfa_tskim_qresume, 3205 tskim); 3206 bfa_sm_set_state(tskim, bfa_tskim_sm_uninit); 3207 3208 list_add_tail(&tskim->qe, &fcpim->tskim_free_q); 3209 } 3210 3211 bfa_mem_kva_curp(fcp) = (u8 *) tskim; 3212 } 3213 3214 void 3215 bfa_tskim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 3216 { 3217 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 3218 struct bfi_tskim_rsp_s *rsp = (struct bfi_tskim_rsp_s *) m; 3219 struct bfa_tskim_s *tskim; 3220 u16 tsk_tag = be16_to_cpu(rsp->tsk_tag); 3221 3222 tskim = BFA_TSKIM_FROM_TAG(fcpim, tsk_tag); 3223 WARN_ON(tskim->tsk_tag != tsk_tag); 3224 3225 tskim->tsk_status = rsp->tsk_status; 3226 3227 /* 3228 * Firmware sends BFI_TSKIM_STS_ABORTED status for abort 3229 * requests. All other statuses are for normal completions. 3230 */ 3231 if (rsp->tsk_status == BFI_TSKIM_STS_ABORTED) { 3232 bfa_stats(tskim->itnim, tm_cleanup_comps); 3233 bfa_sm_send_event(tskim, BFA_TSKIM_SM_CLEANUP_DONE); 3234 } else { 3235 bfa_stats(tskim->itnim, tm_fw_rsps); 3236 bfa_sm_send_event(tskim, BFA_TSKIM_SM_DONE); 3237 } 3238 } 3239 3240 3241 struct bfa_tskim_s * 3242 bfa_tskim_alloc(struct bfa_s *bfa, struct bfad_tskim_s *dtsk) 3243 { 3244 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 3245 struct bfa_tskim_s *tskim; 3246 3247 bfa_q_deq(&fcpim->tskim_free_q, &tskim); 3248 3249 if (tskim) 3250 tskim->dtsk = dtsk; 3251 3252 return tskim; 3253 } 3254 3255 void 3256 bfa_tskim_free(struct bfa_tskim_s *tskim) 3257 { 3258 WARN_ON(!bfa_q_is_on_q_func(&tskim->itnim->tsk_q, &tskim->qe)); 3259 list_del(&tskim->qe); 3260 list_add_tail(&tskim->qe, &tskim->fcpim->tskim_free_q); 3261 } 3262 3263 /* 3264 * Start a task management command. 3265 * 3266 * @param[in] tskim BFA task management command instance 3267 * @param[in] itnim i-t nexus for the task management command 3268 * @param[in] lun lun, if applicable 3269 * @param[in] tm_cmnd Task management command code. 3270 * @param[in] t_secs Timeout in seconds 3271 * 3272 * @return None. 3273 */ 3274 void 3275 bfa_tskim_start(struct bfa_tskim_s *tskim, struct bfa_itnim_s *itnim, 3276 struct scsi_lun lun, 3277 enum fcp_tm_cmnd tm_cmnd, u8 tsecs) 3278 { 3279 tskim->itnim = itnim; 3280 tskim->lun = lun; 3281 tskim->tm_cmnd = tm_cmnd; 3282 tskim->tsecs = tsecs; 3283 tskim->notify = BFA_FALSE; 3284 bfa_stats(itnim, tm_cmnds); 3285 3286 list_add_tail(&tskim->qe, &itnim->tsk_q); 3287 bfa_sm_send_event(tskim, BFA_TSKIM_SM_START); 3288 } 3289 3290 void 3291 bfa_tskim_res_recfg(struct bfa_s *bfa, u16 num_tskim_fw) 3292 { 3293 struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa); 3294 struct list_head *qe; 3295 int i; 3296 3297 for (i = 0; i < (fcpim->num_tskim_reqs - num_tskim_fw); i++) { 3298 bfa_q_deq_tail(&fcpim->tskim_free_q, &qe); 3299 list_add_tail(qe, &fcpim->tskim_unused_q); 3300 } 3301 } 3302 3303 /* BFA FCP module - parent module for fcpim */ 3304 3305 BFA_MODULE(fcp); 3306 3307 static void 3308 bfa_fcp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo, 3309 struct bfa_s *bfa) 3310 { 3311 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); 3312 struct bfa_mem_kva_s *fcp_kva = BFA_MEM_FCP_KVA(bfa); 3313 struct bfa_mem_dma_s *seg_ptr; 3314 u16 nsegs, idx, per_seg_ios, num_io_req; 3315 u32 km_len = 0; 3316 3317 /* 3318 * ZERO for num_ioim_reqs and num_fwtio_reqs is allowed config value. 3319 * So if the values are non zero, adjust them appropriately. 3320 */ 3321 if (cfg->fwcfg.num_ioim_reqs && 3322 cfg->fwcfg.num_ioim_reqs < BFA_IOIM_MIN) 3323 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MIN; 3324 else if (cfg->fwcfg.num_ioim_reqs > BFA_IOIM_MAX) 3325 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX; 3326 3327 if (cfg->fwcfg.num_fwtio_reqs > BFA_FWTIO_MAX) 3328 cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX; 3329 3330 num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs); 3331 if (num_io_req > BFA_IO_MAX) { 3332 if (cfg->fwcfg.num_ioim_reqs && cfg->fwcfg.num_fwtio_reqs) { 3333 cfg->fwcfg.num_ioim_reqs = BFA_IO_MAX/2; 3334 cfg->fwcfg.num_fwtio_reqs = BFA_IO_MAX/2; 3335 } else if (cfg->fwcfg.num_fwtio_reqs) 3336 cfg->fwcfg.num_fwtio_reqs = BFA_FWTIO_MAX; 3337 else 3338 cfg->fwcfg.num_ioim_reqs = BFA_IOIM_MAX; 3339 } 3340 3341 bfa_fcpim_meminfo(cfg, &km_len); 3342 3343 num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs); 3344 km_len += num_io_req * sizeof(struct bfa_iotag_s); 3345 km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_itn_s); 3346 3347 /* dma memory */ 3348 nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN); 3349 per_seg_ios = BFI_MEM_NREQS_SEG(BFI_IOIM_SNSLEN); 3350 3351 bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) { 3352 if (num_io_req >= per_seg_ios) { 3353 num_io_req -= per_seg_ios; 3354 bfa_mem_dma_setup(minfo, seg_ptr, 3355 per_seg_ios * BFI_IOIM_SNSLEN); 3356 } else 3357 bfa_mem_dma_setup(minfo, seg_ptr, 3358 num_io_req * BFI_IOIM_SNSLEN); 3359 } 3360 3361 /* kva memory */ 3362 bfa_mem_kva_setup(minfo, fcp_kva, km_len); 3363 } 3364 3365 static void 3366 bfa_fcp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, 3367 struct bfa_pcidev_s *pcidev) 3368 { 3369 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); 3370 struct bfa_mem_dma_s *seg_ptr; 3371 u16 idx, nsegs, num_io_req; 3372 3373 fcp->num_ioim_reqs = cfg->fwcfg.num_ioim_reqs; 3374 fcp->num_fwtio_reqs = cfg->fwcfg.num_fwtio_reqs; 3375 fcp->num_itns = cfg->fwcfg.num_rports; 3376 fcp->bfa = bfa; 3377 3378 /* 3379 * Setup the pool of snsbase addr's, that is passed to fw as 3380 * part of bfi_iocfc_cfg_s. 3381 */ 3382 num_io_req = (cfg->fwcfg.num_ioim_reqs + cfg->fwcfg.num_fwtio_reqs); 3383 nsegs = BFI_MEM_DMA_NSEGS(num_io_req, BFI_IOIM_SNSLEN); 3384 3385 bfa_mem_dma_seg_iter(fcp, seg_ptr, nsegs, idx) { 3386 3387 if (!bfa_mem_dma_virt(seg_ptr)) 3388 break; 3389 3390 fcp->snsbase[idx].pa = bfa_mem_dma_phys(seg_ptr); 3391 fcp->snsbase[idx].kva = bfa_mem_dma_virt(seg_ptr); 3392 bfa_iocfc_set_snsbase(bfa, idx, fcp->snsbase[idx].pa); 3393 } 3394 3395 bfa_fcpim_attach(fcp, bfad, cfg, pcidev); 3396 3397 bfa_iotag_attach(fcp); 3398 3399 fcp->itn_arr = (struct bfa_itn_s *) bfa_mem_kva_curp(fcp); 3400 bfa_mem_kva_curp(fcp) = (u8 *)fcp->itn_arr + 3401 (fcp->num_itns * sizeof(struct bfa_itn_s)); 3402 memset(fcp->itn_arr, 0, 3403 (fcp->num_itns * sizeof(struct bfa_itn_s))); 3404 } 3405 3406 static void 3407 bfa_fcp_detach(struct bfa_s *bfa) 3408 { 3409 } 3410 3411 static void 3412 bfa_fcp_start(struct bfa_s *bfa) 3413 { 3414 } 3415 3416 static void 3417 bfa_fcp_stop(struct bfa_s *bfa) 3418 { 3419 } 3420 3421 static void 3422 bfa_fcp_iocdisable(struct bfa_s *bfa) 3423 { 3424 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); 3425 3426 /* Enqueue unused ioim resources to free_q */ 3427 list_splice_tail_init(&fcp->iotag_unused_q, &fcp->iotag_ioim_free_q); 3428 3429 bfa_fcpim_iocdisable(fcp); 3430 } 3431 3432 void 3433 bfa_fcp_res_recfg(struct bfa_s *bfa, u16 num_ioim_fw) 3434 { 3435 struct bfa_fcp_mod_s *mod = BFA_FCP_MOD(bfa); 3436 struct list_head *qe; 3437 int i; 3438 3439 for (i = 0; i < (mod->num_ioim_reqs - num_ioim_fw); i++) { 3440 bfa_q_deq_tail(&mod->iotag_ioim_free_q, &qe); 3441 list_add_tail(qe, &mod->iotag_unused_q); 3442 } 3443 } 3444 3445 void 3446 bfa_itn_create(struct bfa_s *bfa, struct bfa_rport_s *rport, 3447 void (*isr)(struct bfa_s *bfa, struct bfi_msg_s *m)) 3448 { 3449 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); 3450 struct bfa_itn_s *itn; 3451 3452 itn = BFA_ITN_FROM_TAG(fcp, rport->rport_tag); 3453 itn->isr = isr; 3454 } 3455 3456 /* 3457 * Itn interrupt processing. 3458 */ 3459 void 3460 bfa_itn_isr(struct bfa_s *bfa, struct bfi_msg_s *m) 3461 { 3462 struct bfa_fcp_mod_s *fcp = BFA_FCP_MOD(bfa); 3463 union bfi_itn_i2h_msg_u msg; 3464 struct bfa_itn_s *itn; 3465 3466 msg.msg = m; 3467 itn = BFA_ITN_FROM_TAG(fcp, msg.create_rsp->bfa_handle); 3468 3469 if (itn->isr) 3470 itn->isr(bfa, m); 3471 else 3472 WARN_ON(1); 3473 } 3474 3475 void 3476 bfa_iotag_attach(struct bfa_fcp_mod_s *fcp) 3477 { 3478 struct bfa_iotag_s *iotag; 3479 u16 num_io_req, i; 3480 3481 iotag = (struct bfa_iotag_s *) bfa_mem_kva_curp(fcp); 3482 fcp->iotag_arr = iotag; 3483 3484 INIT_LIST_HEAD(&fcp->iotag_ioim_free_q); 3485 INIT_LIST_HEAD(&fcp->iotag_tio_free_q); 3486 INIT_LIST_HEAD(&fcp->iotag_unused_q); 3487 3488 num_io_req = fcp->num_ioim_reqs + fcp->num_fwtio_reqs; 3489 for (i = 0; i < num_io_req; i++, iotag++) { 3490 memset(iotag, 0, sizeof(struct bfa_iotag_s)); 3491 iotag->tag = i; 3492 if (i < fcp->num_ioim_reqs) 3493 list_add_tail(&iotag->qe, &fcp->iotag_ioim_free_q); 3494 else 3495 list_add_tail(&iotag->qe, &fcp->iotag_tio_free_q); 3496 } 3497 3498 bfa_mem_kva_curp(fcp) = (u8 *) iotag; 3499 } 3500