1 /* 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2016-2023, Broadcom Inc. All rights reserved. 5 * Support: <fbsd-storage-driver.pdl@broadcom.com> 6 * 7 * Authors: Sumit Saxena <sumit.saxena@broadcom.com> 8 * Chandrakanth Patil <chandrakanth.patil@broadcom.com> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are 12 * met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, 15 * this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation and/or other 18 * materials provided with the distribution. 19 * 3. Neither the name of the Broadcom Inc. nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * The views and conclusions contained in the software and documentation are 36 * those of the authors and should not be interpreted as representing 37 * official policies,either expressed or implied, of the FreeBSD Project. 38 * 39 * Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131 40 * 41 * Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD 42 */ 43 44 #include <sys/types.h> 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/module.h> 49 #include <sys/bus.h> 50 #include <sys/conf.h> 51 #include <sys/malloc.h> 52 #include <sys/sysctl.h> 53 #include <sys/uio.h> 54 55 #include <machine/bus.h> 56 #include <machine/resource.h> 57 #include <sys/rman.h> 58 59 #include <dev/pci/pcireg.h> 60 #include <dev/pci/pcivar.h> 61 #include <dev/pci/pci_private.h> 62 63 #include <cam/cam.h> 64 #include <cam/cam_ccb.h> 65 #include <cam/cam_debug.h> 66 #include <cam/cam_sim.h> 67 #include <cam/cam_xpt_sim.h> 68 #include <cam/cam_xpt_periph.h> 69 #include <cam/cam_periph.h> 70 #include <cam/scsi/scsi_all.h> 71 #include <cam/scsi/scsi_message.h> 72 #include <cam/scsi/smp_all.h> 73 #include <sys/queue.h> 74 #include <sys/kthread.h> 75 #include "mpi3mr.h" 76 #include "mpi3mr_cam.h" 77 #include "mpi3mr_app.h" 78 79 static void mpi3mr_repost_reply_buf(struct mpi3mr_softc *sc, 80 U64 reply_dma); 81 static int mpi3mr_complete_admin_cmd(struct mpi3mr_softc *sc); 82 static void mpi3mr_port_enable_complete(struct mpi3mr_softc *sc, 83 struct mpi3mr_drvr_cmd *drvrcmd); 84 static void mpi3mr_flush_io(struct mpi3mr_softc *sc); 85 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type, 86 U32 reset_reason); 87 static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_softc *sc, U16 handle, 88 struct mpi3mr_drvr_cmd *cmdparam, U8 iou_rc); 89 static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_softc *sc, 90 struct mpi3mr_drvr_cmd *drv_cmd); 91 static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_softc *sc, 92 struct mpi3mr_drvr_cmd *drv_cmd); 93 static void mpi3mr_send_evt_ack(struct mpi3mr_softc *sc, U8 event, 94 struct mpi3mr_drvr_cmd *cmdparam, U32 event_ctx); 95 static void mpi3mr_print_fault_info(struct mpi3mr_softc *sc); 96 static inline void mpi3mr_set_diagsave(struct mpi3mr_softc *sc); 97 static const char *mpi3mr_reset_rc_name(enum mpi3mr_reset_reason reason_code); 98 99 void 100 mpi3mr_hexdump(void *buf, int sz, int format) 101 { 102 int i; 103 U32 *buf_loc = (U32 *)buf; 104 105 for (i = 0; i < (sz / sizeof(U32)); i++) { 106 if ((i % format) == 0) { 107 if (i != 0) 108 printf("\n"); 109 printf("%08x: ", (i * 4)); 110 } 111 printf("%08x ", buf_loc[i]); 112 } 113 printf("\n"); 114 } 115 116 void 117 init_completion(struct completion *completion) 118 { 119 completion->done = 0; 120 } 121 122 void 123 complete(struct completion *completion) 124 { 125 completion->done = 1; 126 wakeup(complete); 127 } 128 129 void wait_for_completion_timeout(struct completion *completion, 130 U32 timeout) 131 { 132 U32 count = timeout * 1000; 133 134 while ((completion->done == 0) && count) { 135 DELAY(1000); 136 count--; 137 } 138 139 if (completion->done == 0) { 140 printf("%s: Command is timedout\n", __func__); 141 completion->done = 1; 142 } 143 } 144 void wait_for_completion_timeout_tm(struct completion *completion, 145 U32 timeout, struct mpi3mr_softc *sc) 146 { 147 U32 count = timeout * 1000; 148 149 while ((completion->done == 0) && count) { 150 msleep(&sc->tm_chan, &sc->mpi3mr_mtx, PRIBIO, 151 "TM command", 1 * hz); 152 count--; 153 } 154 155 if (completion->done == 0) { 156 printf("%s: Command is timedout\n", __func__); 157 completion->done = 1; 158 } 159 } 160 161 162 void 163 poll_for_command_completion(struct mpi3mr_softc *sc, 164 struct mpi3mr_drvr_cmd *cmd, U16 wait) 165 { 166 int wait_time = wait * 1000; 167 while (wait_time) { 168 mpi3mr_complete_admin_cmd(sc); 169 if (cmd->state & MPI3MR_CMD_COMPLETE) 170 break; 171 DELAY(1000); 172 wait_time--; 173 } 174 } 175 176 /** 177 * mpi3mr_trigger_snapdump - triggers firmware snapdump 178 * @sc: Adapter instance reference 179 * @reason_code: reason code for the fault. 180 * 181 * This routine will trigger the snapdump and wait for it to 182 * complete or timeout before it returns. 183 * This will be called during initilaization time faults/resets/timeouts 184 * before soft reset invocation. 185 * 186 * Return: None. 187 */ 188 static void 189 mpi3mr_trigger_snapdump(struct mpi3mr_softc *sc, U32 reason_code) 190 { 191 U32 host_diagnostic, timeout = MPI3_SYSIF_DIAG_SAVE_TIMEOUT * 10; 192 193 mpi3mr_dprint(sc, MPI3MR_INFO, "snapdump triggered: reason code: %s\n", 194 mpi3mr_reset_rc_name(reason_code)); 195 196 mpi3mr_set_diagsave(sc); 197 mpi3mr_issue_reset(sc, MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, 198 reason_code); 199 200 do { 201 host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET); 202 if (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS)) 203 break; 204 DELAY(100 * 1000); 205 } while (--timeout); 206 207 return; 208 } 209 210 /** 211 * mpi3mr_check_rh_fault_ioc - check reset history and fault 212 * controller 213 * @sc: Adapter instance reference 214 * @reason_code, reason code for the fault. 215 * 216 * This routine will fault the controller with 217 * the given reason code if it is not already in the fault or 218 * not asynchronosuly reset. This will be used to handle 219 * initilaization time faults/resets/timeout as in those cases 220 * immediate soft reset invocation is not required. 221 * 222 * Return: None. 223 */ 224 static void mpi3mr_check_rh_fault_ioc(struct mpi3mr_softc *sc, U32 reason_code) 225 { 226 U32 ioc_status; 227 228 if (sc->unrecoverable) { 229 mpi3mr_dprint(sc, MPI3MR_ERROR, "controller is unrecoverable\n"); 230 return; 231 } 232 233 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 234 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) || 235 (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) { 236 mpi3mr_print_fault_info(sc); 237 return; 238 } 239 240 mpi3mr_trigger_snapdump(sc, reason_code); 241 242 return; 243 } 244 245 static void * mpi3mr_get_reply_virt_addr(struct mpi3mr_softc *sc, 246 bus_addr_t phys_addr) 247 { 248 if (!phys_addr) 249 return NULL; 250 if ((phys_addr < sc->reply_buf_dma_min_address) || 251 (phys_addr > sc->reply_buf_dma_max_address)) 252 return NULL; 253 254 return sc->reply_buf + (phys_addr - sc->reply_buf_phys); 255 } 256 257 static void * mpi3mr_get_sensebuf_virt_addr(struct mpi3mr_softc *sc, 258 bus_addr_t phys_addr) 259 { 260 if (!phys_addr) 261 return NULL; 262 return sc->sense_buf + (phys_addr - sc->sense_buf_phys); 263 } 264 265 static void mpi3mr_repost_reply_buf(struct mpi3mr_softc *sc, 266 U64 reply_dma) 267 { 268 U32 old_idx = 0; 269 270 mtx_lock_spin(&sc->reply_free_q_lock); 271 old_idx = sc->reply_free_q_host_index; 272 sc->reply_free_q_host_index = ((sc->reply_free_q_host_index == 273 (sc->reply_free_q_sz - 1)) ? 0 : 274 (sc->reply_free_q_host_index + 1)); 275 sc->reply_free_q[old_idx] = reply_dma; 276 mpi3mr_regwrite(sc, MPI3_SYSIF_REPLY_FREE_HOST_INDEX_OFFSET, 277 sc->reply_free_q_host_index); 278 mtx_unlock_spin(&sc->reply_free_q_lock); 279 } 280 281 static void mpi3mr_repost_sense_buf(struct mpi3mr_softc *sc, 282 U64 sense_buf_phys) 283 { 284 U32 old_idx = 0; 285 286 mtx_lock_spin(&sc->sense_buf_q_lock); 287 old_idx = sc->sense_buf_q_host_index; 288 sc->sense_buf_q_host_index = ((sc->sense_buf_q_host_index == 289 (sc->sense_buf_q_sz - 1)) ? 0 : 290 (sc->sense_buf_q_host_index + 1)); 291 sc->sense_buf_q[old_idx] = sense_buf_phys; 292 mpi3mr_regwrite(sc, MPI3_SYSIF_SENSE_BUF_FREE_HOST_INDEX_OFFSET, 293 sc->sense_buf_q_host_index); 294 mtx_unlock_spin(&sc->sense_buf_q_lock); 295 296 } 297 298 void mpi3mr_set_io_divert_for_all_vd_in_tg(struct mpi3mr_softc *sc, 299 struct mpi3mr_throttle_group_info *tg, U8 divert_value) 300 { 301 struct mpi3mr_target *target; 302 303 mtx_lock_spin(&sc->target_lock); 304 TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) { 305 if (target->throttle_group == tg) 306 target->io_divert = divert_value; 307 } 308 mtx_unlock_spin(&sc->target_lock); 309 } 310 311 /** 312 * mpi3mr_submit_admin_cmd - Submit request to admin queue 313 * @mrioc: Adapter reference 314 * @admin_req: MPI3 request 315 * @admin_req_sz: Request size 316 * 317 * Post the MPI3 request into admin request queue and 318 * inform the controller, if the queue is full return 319 * appropriate error. 320 * 321 * Return: 0 on success, non-zero on failure. 322 */ 323 int mpi3mr_submit_admin_cmd(struct mpi3mr_softc *sc, void *admin_req, 324 U16 admin_req_sz) 325 { 326 U16 areq_pi = 0, areq_ci = 0, max_entries = 0; 327 int retval = 0; 328 U8 *areq_entry; 329 330 mtx_lock_spin(&sc->admin_req_lock); 331 areq_pi = sc->admin_req_pi; 332 areq_ci = sc->admin_req_ci; 333 max_entries = sc->num_admin_reqs; 334 335 if (sc->unrecoverable) 336 return -EFAULT; 337 338 if ((areq_ci == (areq_pi + 1)) || ((!areq_ci) && 339 (areq_pi == (max_entries - 1)))) { 340 printf(IOCNAME "AdminReqQ full condition detected\n", 341 sc->name); 342 retval = -EAGAIN; 343 goto out; 344 } 345 areq_entry = (U8 *)sc->admin_req + (areq_pi * 346 MPI3MR_AREQ_FRAME_SZ); 347 memset(areq_entry, 0, MPI3MR_AREQ_FRAME_SZ); 348 memcpy(areq_entry, (U8 *)admin_req, admin_req_sz); 349 350 if (++areq_pi == max_entries) 351 areq_pi = 0; 352 sc->admin_req_pi = areq_pi; 353 354 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REQ_Q_PI_OFFSET, sc->admin_req_pi); 355 356 out: 357 mtx_unlock_spin(&sc->admin_req_lock); 358 return retval; 359 } 360 361 /** 362 * mpi3mr_check_req_qfull - Check request queue is full or not 363 * @op_req_q: Operational reply queue info 364 * 365 * Return: true when queue full, false otherwise. 366 */ 367 static inline bool 368 mpi3mr_check_req_qfull(struct mpi3mr_op_req_queue *op_req_q) 369 { 370 U16 pi, ci, max_entries; 371 bool is_qfull = false; 372 373 pi = op_req_q->pi; 374 ci = op_req_q->ci; 375 max_entries = op_req_q->num_reqs; 376 377 if ((ci == (pi + 1)) || ((!ci) && (pi == (max_entries - 1)))) 378 is_qfull = true; 379 380 return is_qfull; 381 } 382 383 /** 384 * mpi3mr_submit_io - Post IO command to firmware 385 * @sc: Adapter instance reference 386 * @op_req_q: Operational Request queue reference 387 * @req: MPT request data 388 * 389 * This function submits IO command to firmware. 390 * 391 * Return: Nothing 392 */ 393 int mpi3mr_submit_io(struct mpi3mr_softc *sc, 394 struct mpi3mr_op_req_queue *op_req_q, U8 *req) 395 { 396 U16 pi, max_entries; 397 int retval = 0; 398 U8 *req_entry; 399 U16 req_sz = sc->facts.op_req_sz; 400 struct mpi3mr_irq_context *irq_ctx; 401 402 mtx_lock_spin(&op_req_q->q_lock); 403 404 pi = op_req_q->pi; 405 max_entries = op_req_q->num_reqs; 406 if (mpi3mr_check_req_qfull(op_req_q)) { 407 irq_ctx = &sc->irq_ctx[op_req_q->reply_qid - 1]; 408 mpi3mr_complete_io_cmd(sc, irq_ctx); 409 410 if (mpi3mr_check_req_qfull(op_req_q)) { 411 printf(IOCNAME "OpReqQ full condition detected\n", 412 sc->name); 413 retval = -EBUSY; 414 goto out; 415 } 416 } 417 418 req_entry = (U8 *)op_req_q->q_base + (pi * req_sz); 419 memset(req_entry, 0, req_sz); 420 memcpy(req_entry, req, MPI3MR_AREQ_FRAME_SZ); 421 if (++pi == max_entries) 422 pi = 0; 423 op_req_q->pi = pi; 424 425 mpi3mr_atomic_inc(&sc->op_reply_q[op_req_q->reply_qid - 1].pend_ios); 426 427 mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REQ_Q_N_PI_OFFSET(op_req_q->qid), op_req_q->pi); 428 if (sc->mpi3mr_debug & MPI3MR_TRACE) { 429 device_printf(sc->mpi3mr_dev, "IO submission: QID:%d PI:0x%x\n", op_req_q->qid, op_req_q->pi); 430 mpi3mr_hexdump(req_entry, MPI3MR_AREQ_FRAME_SZ, 8); 431 } 432 433 out: 434 mtx_unlock_spin(&op_req_q->q_lock); 435 return retval; 436 } 437 438 inline void 439 mpi3mr_add_sg_single(void *paddr, U8 flags, U32 length, 440 bus_addr_t dma_addr) 441 { 442 Mpi3SGESimple_t *sgel = paddr; 443 444 sgel->Flags = flags; 445 sgel->Length = (length); 446 sgel->Address = (U64)dma_addr; 447 } 448 449 void mpi3mr_build_zero_len_sge(void *paddr) 450 { 451 U8 sgl_flags = (MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE | 452 MPI3_SGE_FLAGS_DLAS_SYSTEM | MPI3_SGE_FLAGS_END_OF_LIST); 453 454 mpi3mr_add_sg_single(paddr, sgl_flags, 0, -1); 455 456 } 457 458 void mpi3mr_enable_interrupts(struct mpi3mr_softc *sc) 459 { 460 sc->intr_enabled = 1; 461 } 462 463 void mpi3mr_disable_interrupts(struct mpi3mr_softc *sc) 464 { 465 sc->intr_enabled = 0; 466 } 467 468 void 469 mpi3mr_memaddr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 470 { 471 bus_addr_t *addr; 472 473 addr = arg; 474 *addr = segs[0].ds_addr; 475 } 476 477 static int mpi3mr_delete_op_reply_queue(struct mpi3mr_softc *sc, U16 qid) 478 { 479 Mpi3DeleteReplyQueueRequest_t delq_req; 480 struct mpi3mr_op_reply_queue *op_reply_q; 481 int retval = 0; 482 483 484 op_reply_q = &sc->op_reply_q[qid - 1]; 485 486 if (!op_reply_q->qid) 487 { 488 retval = -1; 489 printf(IOCNAME "Issue DelRepQ: called with invalid Reply QID\n", 490 sc->name); 491 goto out; 492 } 493 494 memset(&delq_req, 0, sizeof(delq_req)); 495 496 mtx_lock(&sc->init_cmds.completion.lock); 497 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 498 retval = -1; 499 printf(IOCNAME "Issue DelRepQ: Init command is in use\n", 500 sc->name); 501 mtx_unlock(&sc->init_cmds.completion.lock); 502 goto out; 503 } 504 505 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 506 retval = -1; 507 printf(IOCNAME "Issue DelRepQ: Init command is in use\n", 508 sc->name); 509 goto out; 510 } 511 sc->init_cmds.state = MPI3MR_CMD_PENDING; 512 sc->init_cmds.is_waiting = 1; 513 sc->init_cmds.callback = NULL; 514 delq_req.HostTag = MPI3MR_HOSTTAG_INITCMDS; 515 delq_req.Function = MPI3_FUNCTION_DELETE_REPLY_QUEUE; 516 delq_req.QueueID = qid; 517 518 init_completion(&sc->init_cmds.completion); 519 retval = mpi3mr_submit_admin_cmd(sc, &delq_req, sizeof(delq_req)); 520 if (retval) { 521 printf(IOCNAME "Issue DelRepQ: Admin Post failed\n", 522 sc->name); 523 goto out_unlock; 524 } 525 wait_for_completion_timeout(&sc->init_cmds.completion, 526 (MPI3MR_INTADMCMD_TIMEOUT)); 527 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 528 printf(IOCNAME "Issue DelRepQ: command timed out\n", 529 sc->name); 530 mpi3mr_check_rh_fault_ioc(sc, 531 MPI3MR_RESET_FROM_DELREPQ_TIMEOUT); 532 sc->unrecoverable = 1; 533 534 retval = -1; 535 goto out_unlock; 536 } 537 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 538 != MPI3_IOCSTATUS_SUCCESS ) { 539 printf(IOCNAME "Issue DelRepQ: Failed IOCStatus(0x%04x) " 540 " Loginfo(0x%08x) \n" , sc->name, 541 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 542 sc->init_cmds.ioc_loginfo); 543 retval = -1; 544 goto out_unlock; 545 } 546 sc->irq_ctx[qid - 1].op_reply_q = NULL; 547 548 if (sc->op_reply_q[qid - 1].q_base_phys != 0) 549 bus_dmamap_unload(sc->op_reply_q[qid - 1].q_base_tag, sc->op_reply_q[qid - 1].q_base_dmamap); 550 if (sc->op_reply_q[qid - 1].q_base != NULL) 551 bus_dmamem_free(sc->op_reply_q[qid - 1].q_base_tag, sc->op_reply_q[qid - 1].q_base, sc->op_reply_q[qid - 1].q_base_dmamap); 552 if (sc->op_reply_q[qid - 1].q_base_tag != NULL) 553 bus_dma_tag_destroy(sc->op_reply_q[qid - 1].q_base_tag); 554 555 sc->op_reply_q[qid - 1].q_base = NULL; 556 sc->op_reply_q[qid - 1].qid = 0; 557 out_unlock: 558 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 559 mtx_unlock(&sc->init_cmds.completion.lock); 560 out: 561 return retval; 562 } 563 564 /** 565 * mpi3mr_create_op_reply_queue - create operational reply queue 566 * @sc: Adapter instance reference 567 * @qid: operational reply queue id 568 * 569 * Create operatinal reply queue by issuing MPI request 570 * through admin queue. 571 * 572 * Return: 0 on success, non-zero on failure. 573 */ 574 static int mpi3mr_create_op_reply_queue(struct mpi3mr_softc *sc, U16 qid) 575 { 576 Mpi3CreateReplyQueueRequest_t create_req; 577 struct mpi3mr_op_reply_queue *op_reply_q; 578 int retval = 0; 579 char q_lock_name[32]; 580 581 op_reply_q = &sc->op_reply_q[qid - 1]; 582 583 if (op_reply_q->qid) 584 { 585 retval = -1; 586 printf(IOCNAME "CreateRepQ: called for duplicate qid %d\n", 587 sc->name, op_reply_q->qid); 588 return retval; 589 } 590 591 op_reply_q->ci = 0; 592 if (pci_get_revid(sc->mpi3mr_dev) == SAS4116_CHIP_REV_A0) 593 op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD_A0; 594 else 595 op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD; 596 597 op_reply_q->qsz = op_reply_q->num_replies * sc->op_reply_sz; 598 op_reply_q->ephase = 1; 599 600 if (!op_reply_q->q_base) { 601 snprintf(q_lock_name, 32, "Reply Queue Lock[%d]", qid); 602 mtx_init(&op_reply_q->q_lock, q_lock_name, NULL, MTX_SPIN); 603 604 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 605 4, 0, /* algnmnt, boundary */ 606 sc->dma_loaddr, /* lowaddr */ 607 BUS_SPACE_MAXADDR, /* highaddr */ 608 NULL, NULL, /* filter, filterarg */ 609 op_reply_q->qsz, /* maxsize */ 610 1, /* nsegments */ 611 op_reply_q->qsz, /* maxsegsize */ 612 0, /* flags */ 613 NULL, NULL, /* lockfunc, lockarg */ 614 &op_reply_q->q_base_tag)) { 615 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Operational reply DMA tag\n"); 616 return (ENOMEM); 617 } 618 619 if (bus_dmamem_alloc(op_reply_q->q_base_tag, (void **)&op_reply_q->q_base, 620 BUS_DMA_NOWAIT, &op_reply_q->q_base_dmamap)) { 621 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 622 return (ENOMEM); 623 } 624 bzero(op_reply_q->q_base, op_reply_q->qsz); 625 bus_dmamap_load(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap, op_reply_q->q_base, op_reply_q->qsz, 626 mpi3mr_memaddr_cb, &op_reply_q->q_base_phys, BUS_DMA_NOWAIT); 627 mpi3mr_dprint(sc, MPI3MR_XINFO, "Operational Reply queue ID: %d phys addr= %#016jx virt_addr: %pa size= %d\n", 628 qid, (uintmax_t)op_reply_q->q_base_phys, op_reply_q->q_base, op_reply_q->qsz); 629 630 if (!op_reply_q->q_base) 631 { 632 retval = -1; 633 printf(IOCNAME "CreateRepQ: memory alloc failed for qid %d\n", 634 sc->name, qid); 635 goto out; 636 } 637 } 638 639 memset(&create_req, 0, sizeof(create_req)); 640 641 mtx_lock(&sc->init_cmds.completion.lock); 642 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 643 retval = -1; 644 printf(IOCNAME "CreateRepQ: Init command is in use\n", 645 sc->name); 646 mtx_unlock(&sc->init_cmds.completion.lock); 647 goto out; 648 } 649 650 sc->init_cmds.state = MPI3MR_CMD_PENDING; 651 sc->init_cmds.is_waiting = 1; 652 sc->init_cmds.callback = NULL; 653 create_req.HostTag = MPI3MR_HOSTTAG_INITCMDS; 654 create_req.Function = MPI3_FUNCTION_CREATE_REPLY_QUEUE; 655 create_req.QueueID = qid; 656 create_req.Flags = MPI3_CREATE_REPLY_QUEUE_FLAGS_INT_ENABLE_ENABLE; 657 create_req.MSIxIndex = sc->irq_ctx[qid - 1].msix_index; 658 create_req.BaseAddress = (U64)op_reply_q->q_base_phys; 659 create_req.Size = op_reply_q->num_replies; 660 661 init_completion(&sc->init_cmds.completion); 662 retval = mpi3mr_submit_admin_cmd(sc, &create_req, 663 sizeof(create_req)); 664 if (retval) { 665 printf(IOCNAME "CreateRepQ: Admin Post failed\n", 666 sc->name); 667 goto out_unlock; 668 } 669 670 wait_for_completion_timeout(&sc->init_cmds.completion, 671 MPI3MR_INTADMCMD_TIMEOUT); 672 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 673 printf(IOCNAME "CreateRepQ: command timed out\n", 674 sc->name); 675 mpi3mr_check_rh_fault_ioc(sc, 676 MPI3MR_RESET_FROM_CREATEREPQ_TIMEOUT); 677 sc->unrecoverable = 1; 678 retval = -1; 679 goto out_unlock; 680 } 681 682 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 683 != MPI3_IOCSTATUS_SUCCESS ) { 684 printf(IOCNAME "CreateRepQ: Failed IOCStatus(0x%04x) " 685 " Loginfo(0x%08x) \n" , sc->name, 686 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 687 sc->init_cmds.ioc_loginfo); 688 retval = -1; 689 goto out_unlock; 690 } 691 op_reply_q->qid = qid; 692 sc->irq_ctx[qid - 1].op_reply_q = op_reply_q; 693 694 out_unlock: 695 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 696 mtx_unlock(&sc->init_cmds.completion.lock); 697 out: 698 if (retval) { 699 if (op_reply_q->q_base_phys != 0) 700 bus_dmamap_unload(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap); 701 if (op_reply_q->q_base != NULL) 702 bus_dmamem_free(op_reply_q->q_base_tag, op_reply_q->q_base, op_reply_q->q_base_dmamap); 703 if (op_reply_q->q_base_tag != NULL) 704 bus_dma_tag_destroy(op_reply_q->q_base_tag); 705 op_reply_q->q_base = NULL; 706 op_reply_q->qid = 0; 707 } 708 709 return retval; 710 } 711 712 /** 713 * mpi3mr_create_op_req_queue - create operational request queue 714 * @sc: Adapter instance reference 715 * @req_qid: operational request queue id 716 * @reply_qid: Reply queue ID 717 * 718 * Create operatinal request queue by issuing MPI request 719 * through admin queue. 720 * 721 * Return: 0 on success, non-zero on failure. 722 */ 723 static int mpi3mr_create_op_req_queue(struct mpi3mr_softc *sc, U16 req_qid, U8 reply_qid) 724 { 725 Mpi3CreateRequestQueueRequest_t create_req; 726 struct mpi3mr_op_req_queue *op_req_q; 727 int retval = 0; 728 char q_lock_name[32]; 729 730 op_req_q = &sc->op_req_q[req_qid - 1]; 731 732 if (op_req_q->qid) 733 { 734 retval = -1; 735 printf(IOCNAME "CreateReqQ: called for duplicate qid %d\n", 736 sc->name, op_req_q->qid); 737 return retval; 738 } 739 740 op_req_q->ci = 0; 741 op_req_q->pi = 0; 742 op_req_q->num_reqs = MPI3MR_OP_REQ_Q_QD; 743 op_req_q->qsz = op_req_q->num_reqs * sc->facts.op_req_sz; 744 op_req_q->reply_qid = reply_qid; 745 746 if (!op_req_q->q_base) { 747 snprintf(q_lock_name, 32, "Request Queue Lock[%d]", req_qid); 748 mtx_init(&op_req_q->q_lock, q_lock_name, NULL, MTX_SPIN); 749 750 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 751 4, 0, /* algnmnt, boundary */ 752 sc->dma_loaddr, /* lowaddr */ 753 BUS_SPACE_MAXADDR, /* highaddr */ 754 NULL, NULL, /* filter, filterarg */ 755 op_req_q->qsz, /* maxsize */ 756 1, /* nsegments */ 757 op_req_q->qsz, /* maxsegsize */ 758 0, /* flags */ 759 NULL, NULL, /* lockfunc, lockarg */ 760 &op_req_q->q_base_tag)) { 761 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 762 return (ENOMEM); 763 } 764 765 if (bus_dmamem_alloc(op_req_q->q_base_tag, (void **)&op_req_q->q_base, 766 BUS_DMA_NOWAIT, &op_req_q->q_base_dmamap)) { 767 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 768 return (ENOMEM); 769 } 770 771 bzero(op_req_q->q_base, op_req_q->qsz); 772 773 bus_dmamap_load(op_req_q->q_base_tag, op_req_q->q_base_dmamap, op_req_q->q_base, op_req_q->qsz, 774 mpi3mr_memaddr_cb, &op_req_q->q_base_phys, BUS_DMA_NOWAIT); 775 776 mpi3mr_dprint(sc, MPI3MR_XINFO, "Operational Request QID: %d phys addr= %#016jx virt addr= %pa size= %d associated Reply QID: %d\n", 777 req_qid, (uintmax_t)op_req_q->q_base_phys, op_req_q->q_base, op_req_q->qsz, reply_qid); 778 779 if (!op_req_q->q_base) { 780 retval = -1; 781 printf(IOCNAME "CreateReqQ: memory alloc failed for qid %d\n", 782 sc->name, req_qid); 783 goto out; 784 } 785 } 786 787 memset(&create_req, 0, sizeof(create_req)); 788 789 mtx_lock(&sc->init_cmds.completion.lock); 790 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 791 retval = -1; 792 printf(IOCNAME "CreateReqQ: Init command is in use\n", 793 sc->name); 794 mtx_unlock(&sc->init_cmds.completion.lock); 795 goto out; 796 } 797 798 sc->init_cmds.state = MPI3MR_CMD_PENDING; 799 sc->init_cmds.is_waiting = 1; 800 sc->init_cmds.callback = NULL; 801 create_req.HostTag = MPI3MR_HOSTTAG_INITCMDS; 802 create_req.Function = MPI3_FUNCTION_CREATE_REQUEST_QUEUE; 803 create_req.QueueID = req_qid; 804 create_req.Flags = 0; 805 create_req.ReplyQueueID = reply_qid; 806 create_req.BaseAddress = (U64)op_req_q->q_base_phys; 807 create_req.Size = op_req_q->num_reqs; 808 809 init_completion(&sc->init_cmds.completion); 810 retval = mpi3mr_submit_admin_cmd(sc, &create_req, 811 sizeof(create_req)); 812 if (retval) { 813 printf(IOCNAME "CreateReqQ: Admin Post failed\n", 814 sc->name); 815 goto out_unlock; 816 } 817 818 wait_for_completion_timeout(&sc->init_cmds.completion, 819 (MPI3MR_INTADMCMD_TIMEOUT)); 820 821 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 822 printf(IOCNAME "CreateReqQ: command timed out\n", 823 sc->name); 824 mpi3mr_check_rh_fault_ioc(sc, 825 MPI3MR_RESET_FROM_CREATEREQQ_TIMEOUT); 826 sc->unrecoverable = 1; 827 retval = -1; 828 goto out_unlock; 829 } 830 831 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 832 != MPI3_IOCSTATUS_SUCCESS ) { 833 printf(IOCNAME "CreateReqQ: Failed IOCStatus(0x%04x) " 834 " Loginfo(0x%08x) \n" , sc->name, 835 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 836 sc->init_cmds.ioc_loginfo); 837 retval = -1; 838 goto out_unlock; 839 } 840 op_req_q->qid = req_qid; 841 842 out_unlock: 843 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 844 mtx_unlock(&sc->init_cmds.completion.lock); 845 out: 846 if (retval) { 847 if (op_req_q->q_base_phys != 0) 848 bus_dmamap_unload(op_req_q->q_base_tag, op_req_q->q_base_dmamap); 849 if (op_req_q->q_base != NULL) 850 bus_dmamem_free(op_req_q->q_base_tag, op_req_q->q_base, op_req_q->q_base_dmamap); 851 if (op_req_q->q_base_tag != NULL) 852 bus_dma_tag_destroy(op_req_q->q_base_tag); 853 op_req_q->q_base = NULL; 854 op_req_q->qid = 0; 855 } 856 return retval; 857 } 858 859 /** 860 * mpi3mr_create_op_queues - create operational queues 861 * @sc: Adapter instance reference 862 * 863 * Create operatinal queues(request queues and reply queues). 864 * Return: 0 on success, non-zero on failure. 865 */ 866 static int mpi3mr_create_op_queues(struct mpi3mr_softc *sc) 867 { 868 int retval = 0; 869 U16 num_queues = 0, i = 0, qid; 870 871 num_queues = min(sc->facts.max_op_reply_q, 872 sc->facts.max_op_req_q); 873 num_queues = min(num_queues, sc->msix_count); 874 875 /* 876 * During reset set the num_queues to the number of queues 877 * that was set before the reset. 878 */ 879 if (sc->num_queues) 880 num_queues = sc->num_queues; 881 882 mpi3mr_dprint(sc, MPI3MR_XINFO, "Trying to create %d Operational Q pairs\n", 883 num_queues); 884 885 if (!sc->op_req_q) { 886 sc->op_req_q = malloc(sizeof(struct mpi3mr_op_req_queue) * 887 num_queues, M_MPI3MR, M_NOWAIT | M_ZERO); 888 889 if (!sc->op_req_q) { 890 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to alloc memory for Request queue info\n"); 891 retval = -1; 892 goto out_failed; 893 } 894 } 895 896 if (!sc->op_reply_q) { 897 sc->op_reply_q = malloc(sizeof(struct mpi3mr_op_reply_queue) * num_queues, 898 M_MPI3MR, M_NOWAIT | M_ZERO); 899 900 if (!sc->op_reply_q) { 901 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to alloc memory for Reply queue info\n"); 902 retval = -1; 903 goto out_failed; 904 } 905 } 906 907 sc->num_hosttag_op_req_q = (sc->max_host_ios + 1) / num_queues; 908 909 /*Operational Request and reply queue ID starts with 1*/ 910 for (i = 0; i < num_queues; i++) { 911 qid = i + 1; 912 if (mpi3mr_create_op_reply_queue(sc, qid)) { 913 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create Reply queue %d\n", 914 qid); 915 break; 916 } 917 if (mpi3mr_create_op_req_queue(sc, qid, 918 sc->op_reply_q[qid - 1].qid)) { 919 mpi3mr_delete_op_reply_queue(sc, qid); 920 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create Request queue %d\n", 921 qid); 922 break; 923 } 924 925 } 926 927 /* Not even one queue is created successfully*/ 928 if (i == 0) { 929 retval = -1; 930 goto out_failed; 931 } 932 933 if (!sc->num_queues) { 934 sc->num_queues = i; 935 } else { 936 if (num_queues != i) { 937 mpi3mr_dprint(sc, MPI3MR_ERROR, "Number of queues (%d) post reset are not same as" 938 "queues allocated (%d) during driver init\n", i, num_queues); 939 goto out_failed; 940 } 941 } 942 943 mpi3mr_dprint(sc, MPI3MR_INFO, "Successfully created %d Operational Queue pairs\n", 944 sc->num_queues); 945 mpi3mr_dprint(sc, MPI3MR_INFO, "Request Queue QD: %d Reply queue QD: %d\n", 946 sc->op_req_q[0].num_reqs, sc->op_reply_q[0].num_replies); 947 948 return retval; 949 out_failed: 950 if (sc->op_req_q) { 951 free(sc->op_req_q, M_MPI3MR); 952 sc->op_req_q = NULL; 953 } 954 if (sc->op_reply_q) { 955 free(sc->op_reply_q, M_MPI3MR); 956 sc->op_reply_q = NULL; 957 } 958 return retval; 959 } 960 961 /** 962 * mpi3mr_setup_admin_qpair - Setup admin queue pairs 963 * @sc: Adapter instance reference 964 * 965 * Allocation and setup admin queues(request queues and reply queues). 966 * Return: 0 on success, non-zero on failure. 967 */ 968 static int mpi3mr_setup_admin_qpair(struct mpi3mr_softc *sc) 969 { 970 int retval = 0; 971 U32 num_adm_entries = 0; 972 973 sc->admin_req_q_sz = MPI3MR_AREQQ_SIZE; 974 sc->num_admin_reqs = sc->admin_req_q_sz / MPI3MR_AREQ_FRAME_SZ; 975 sc->admin_req_ci = sc->admin_req_pi = 0; 976 977 sc->admin_reply_q_sz = MPI3MR_AREPQ_SIZE; 978 sc->num_admin_replies = sc->admin_reply_q_sz/ MPI3MR_AREP_FRAME_SZ; 979 sc->admin_reply_ci = 0; 980 sc->admin_reply_ephase = 1; 981 982 if (!sc->admin_req) { 983 /* 984 * We need to create the tag for the admin queue to get the 985 * iofacts to see how many bits the controller decodes. Solve 986 * this chicken and egg problem by only doing lower 4GB DMA. 987 */ 988 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 989 4, 0, /* algnmnt, boundary */ 990 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 991 BUS_SPACE_MAXADDR, /* highaddr */ 992 NULL, NULL, /* filter, filterarg */ 993 sc->admin_req_q_sz, /* maxsize */ 994 1, /* nsegments */ 995 sc->admin_req_q_sz, /* maxsegsize */ 996 0, /* flags */ 997 NULL, NULL, /* lockfunc, lockarg */ 998 &sc->admin_req_tag)) { 999 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 1000 return (ENOMEM); 1001 } 1002 1003 if (bus_dmamem_alloc(sc->admin_req_tag, (void **)&sc->admin_req, 1004 BUS_DMA_NOWAIT, &sc->admin_req_dmamap)) { 1005 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 1006 return (ENOMEM); 1007 } 1008 bzero(sc->admin_req, sc->admin_req_q_sz); 1009 bus_dmamap_load(sc->admin_req_tag, sc->admin_req_dmamap, sc->admin_req, sc->admin_req_q_sz, 1010 mpi3mr_memaddr_cb, &sc->admin_req_phys, BUS_DMA_NOWAIT); 1011 mpi3mr_dprint(sc, MPI3MR_XINFO, "Admin Req queue phys addr= %#016jx size= %d\n", 1012 (uintmax_t)sc->admin_req_phys, sc->admin_req_q_sz); 1013 1014 if (!sc->admin_req) 1015 { 1016 retval = -1; 1017 printf(IOCNAME "Memory alloc for AdminReqQ: failed\n", 1018 sc->name); 1019 goto out_failed; 1020 } 1021 } 1022 1023 if (!sc->admin_reply) { 1024 mtx_init(&sc->admin_reply_lock, "Admin Reply Queue Lock", NULL, MTX_SPIN); 1025 1026 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1027 4, 0, /* algnmnt, boundary */ 1028 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 1029 BUS_SPACE_MAXADDR, /* highaddr */ 1030 NULL, NULL, /* filter, filterarg */ 1031 sc->admin_reply_q_sz, /* maxsize */ 1032 1, /* nsegments */ 1033 sc->admin_reply_q_sz, /* maxsegsize */ 1034 0, /* flags */ 1035 NULL, NULL, /* lockfunc, lockarg */ 1036 &sc->admin_reply_tag)) { 1037 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate reply DMA tag\n"); 1038 return (ENOMEM); 1039 } 1040 1041 if (bus_dmamem_alloc(sc->admin_reply_tag, (void **)&sc->admin_reply, 1042 BUS_DMA_NOWAIT, &sc->admin_reply_dmamap)) { 1043 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 1044 return (ENOMEM); 1045 } 1046 bzero(sc->admin_reply, sc->admin_reply_q_sz); 1047 bus_dmamap_load(sc->admin_reply_tag, sc->admin_reply_dmamap, sc->admin_reply, sc->admin_reply_q_sz, 1048 mpi3mr_memaddr_cb, &sc->admin_reply_phys, BUS_DMA_NOWAIT); 1049 mpi3mr_dprint(sc, MPI3MR_XINFO, "Admin Reply queue phys addr= %#016jx size= %d\n", 1050 (uintmax_t)sc->admin_reply_phys, sc->admin_req_q_sz); 1051 1052 1053 if (!sc->admin_reply) 1054 { 1055 retval = -1; 1056 printf(IOCNAME "Memory alloc for AdminRepQ: failed\n", 1057 sc->name); 1058 goto out_failed; 1059 } 1060 } 1061 1062 num_adm_entries = (sc->num_admin_replies << 16) | 1063 (sc->num_admin_reqs); 1064 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_Q_NUM_ENTRIES_OFFSET, num_adm_entries); 1065 mpi3mr_regwrite64(sc, MPI3_SYSIF_ADMIN_REQ_Q_ADDR_LOW_OFFSET, sc->admin_req_phys); 1066 mpi3mr_regwrite64(sc, MPI3_SYSIF_ADMIN_REPLY_Q_ADDR_LOW_OFFSET, sc->admin_reply_phys); 1067 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REQ_Q_PI_OFFSET, sc->admin_req_pi); 1068 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, sc->admin_reply_ci); 1069 1070 return retval; 1071 1072 out_failed: 1073 /* Free Admin reply*/ 1074 if (sc->admin_reply_phys) 1075 bus_dmamap_unload(sc->admin_reply_tag, sc->admin_reply_dmamap); 1076 1077 if (sc->admin_reply != NULL) 1078 bus_dmamem_free(sc->admin_reply_tag, sc->admin_reply, 1079 sc->admin_reply_dmamap); 1080 1081 if (sc->admin_reply_tag != NULL) 1082 bus_dma_tag_destroy(sc->admin_reply_tag); 1083 1084 /* Free Admin request*/ 1085 if (sc->admin_req_phys) 1086 bus_dmamap_unload(sc->admin_req_tag, sc->admin_req_dmamap); 1087 1088 if (sc->admin_req != NULL) 1089 bus_dmamem_free(sc->admin_req_tag, sc->admin_req, 1090 sc->admin_req_dmamap); 1091 1092 if (sc->admin_req_tag != NULL) 1093 bus_dma_tag_destroy(sc->admin_req_tag); 1094 1095 return retval; 1096 } 1097 1098 /** 1099 * mpi3mr_print_fault_info - Display fault information 1100 * @sc: Adapter instance reference 1101 * 1102 * Display the controller fault information if there is a 1103 * controller fault. 1104 * 1105 * Return: Nothing. 1106 */ 1107 static void mpi3mr_print_fault_info(struct mpi3mr_softc *sc) 1108 { 1109 U32 ioc_status, code, code1, code2, code3; 1110 1111 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 1112 1113 if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) { 1114 code = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) & 1115 MPI3_SYSIF_FAULT_CODE_MASK; 1116 code1 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO0_OFFSET); 1117 code2 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO1_OFFSET); 1118 code3 = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_INFO2_OFFSET); 1119 printf(IOCNAME "fault codes 0x%04x:0x%04x:0x%04x:0x%04x\n", 1120 sc->name, code, code1, code2, code3); 1121 } 1122 } 1123 1124 enum mpi3mr_iocstate mpi3mr_get_iocstate(struct mpi3mr_softc *sc) 1125 { 1126 U32 ioc_status, ioc_control; 1127 U8 ready, enabled; 1128 1129 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 1130 ioc_control = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1131 1132 if(sc->unrecoverable) 1133 return MRIOC_STATE_UNRECOVERABLE; 1134 if (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) 1135 return MRIOC_STATE_FAULT; 1136 1137 ready = (ioc_status & MPI3_SYSIF_IOC_STATUS_READY); 1138 enabled = (ioc_control & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC); 1139 1140 if (ready && enabled) 1141 return MRIOC_STATE_READY; 1142 if ((!ready) && (!enabled)) 1143 return MRIOC_STATE_RESET; 1144 if ((!ready) && (enabled)) 1145 return MRIOC_STATE_BECOMING_READY; 1146 1147 return MRIOC_STATE_RESET_REQUESTED; 1148 } 1149 1150 static inline void mpi3mr_clear_resethistory(struct mpi3mr_softc *sc) 1151 { 1152 U32 ioc_status; 1153 1154 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 1155 if (ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) 1156 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_STATUS_OFFSET, ioc_status); 1157 1158 } 1159 1160 /** 1161 * mpi3mr_mur_ioc - Message unit Reset handler 1162 * @sc: Adapter instance reference 1163 * @reset_reason: Reset reason code 1164 * 1165 * Issue Message unit Reset to the controller and wait for it to 1166 * be complete. 1167 * 1168 * Return: 0 on success, -1 on failure. 1169 */ 1170 static int mpi3mr_mur_ioc(struct mpi3mr_softc *sc, U32 reset_reason) 1171 { 1172 U32 ioc_config, timeout, ioc_status; 1173 int retval = -1; 1174 1175 mpi3mr_dprint(sc, MPI3MR_INFO, "Issuing Message Unit Reset(MUR)\n"); 1176 if (sc->unrecoverable) { 1177 mpi3mr_dprint(sc, MPI3MR_ERROR, "IOC is unrecoverable MUR not issued\n"); 1178 return retval; 1179 } 1180 mpi3mr_clear_resethistory(sc); 1181 mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, reset_reason); 1182 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1183 ioc_config &= ~MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC; 1184 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config); 1185 1186 timeout = MPI3MR_MUR_TIMEOUT * 10; 1187 do { 1188 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 1189 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY)) { 1190 mpi3mr_clear_resethistory(sc); 1191 ioc_config = 1192 mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1193 if (!((ioc_status & MPI3_SYSIF_IOC_STATUS_READY) || 1194 (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) || 1195 (ioc_config & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC))) { 1196 retval = 0; 1197 break; 1198 } 1199 } 1200 DELAY(100 * 1000); 1201 } while (--timeout); 1202 1203 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 1204 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1205 1206 mpi3mr_dprint(sc, MPI3MR_INFO, "IOC Status/Config after %s MUR is (0x%x)/(0x%x)\n", 1207 !retval ? "successful":"failed", ioc_status, ioc_config); 1208 return retval; 1209 } 1210 1211 /** 1212 * mpi3mr_bring_ioc_ready - Bring controller to ready state 1213 * @sc: Adapter instance reference 1214 * 1215 * Set Enable IOC bit in IOC configuration register and wait for 1216 * the controller to become ready. 1217 * 1218 * Return: 0 on success, appropriate error on failure. 1219 */ 1220 static int mpi3mr_bring_ioc_ready(struct mpi3mr_softc *sc) 1221 { 1222 U32 ioc_config, timeout; 1223 enum mpi3mr_iocstate current_state; 1224 1225 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1226 ioc_config |= MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC; 1227 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config); 1228 1229 timeout = sc->ready_timeout * 10; 1230 do { 1231 current_state = mpi3mr_get_iocstate(sc); 1232 if (current_state == MRIOC_STATE_READY) 1233 return 0; 1234 DELAY(100 * 1000); 1235 } while (--timeout); 1236 1237 return -1; 1238 } 1239 1240 static const struct { 1241 enum mpi3mr_iocstate value; 1242 char *name; 1243 } mrioc_states[] = { 1244 { MRIOC_STATE_READY, "ready" }, 1245 { MRIOC_STATE_FAULT, "fault" }, 1246 { MRIOC_STATE_RESET, "reset" }, 1247 { MRIOC_STATE_BECOMING_READY, "becoming ready" }, 1248 { MRIOC_STATE_RESET_REQUESTED, "reset requested" }, 1249 { MRIOC_STATE_COUNT, "Count" }, 1250 }; 1251 1252 static const char *mpi3mr_iocstate_name(enum mpi3mr_iocstate mrioc_state) 1253 { 1254 int i; 1255 char *name = NULL; 1256 1257 for (i = 0; i < MRIOC_STATE_COUNT; i++) { 1258 if (mrioc_states[i].value == mrioc_state){ 1259 name = mrioc_states[i].name; 1260 break; 1261 } 1262 } 1263 return name; 1264 } 1265 1266 /* Reset reason to name mapper structure*/ 1267 static const struct { 1268 enum mpi3mr_reset_reason value; 1269 char *name; 1270 } mpi3mr_reset_reason_codes[] = { 1271 { MPI3MR_RESET_FROM_BRINGUP, "timeout in bringup" }, 1272 { MPI3MR_RESET_FROM_FAULT_WATCH, "fault" }, 1273 { MPI3MR_RESET_FROM_IOCTL, "application" }, 1274 { MPI3MR_RESET_FROM_EH_HOS, "error handling" }, 1275 { MPI3MR_RESET_FROM_TM_TIMEOUT, "TM timeout" }, 1276 { MPI3MR_RESET_FROM_IOCTL_TIMEOUT, "IOCTL timeout" }, 1277 { MPI3MR_RESET_FROM_SCSIIO_TIMEOUT, "SCSIIO timeout" }, 1278 { MPI3MR_RESET_FROM_MUR_FAILURE, "MUR failure" }, 1279 { MPI3MR_RESET_FROM_CTLR_CLEANUP, "timeout in controller cleanup" }, 1280 { MPI3MR_RESET_FROM_CIACTIV_FAULT, "component image activation fault" }, 1281 { MPI3MR_RESET_FROM_PE_TIMEOUT, "port enable timeout" }, 1282 { MPI3MR_RESET_FROM_TSU_TIMEOUT, "time stamp update timeout" }, 1283 { MPI3MR_RESET_FROM_DELREQQ_TIMEOUT, "delete request queue timeout" }, 1284 { MPI3MR_RESET_FROM_DELREPQ_TIMEOUT, "delete reply queue timeout" }, 1285 { 1286 MPI3MR_RESET_FROM_CREATEREPQ_TIMEOUT, 1287 "create request queue timeout" 1288 }, 1289 { 1290 MPI3MR_RESET_FROM_CREATEREQQ_TIMEOUT, 1291 "create reply queue timeout" 1292 }, 1293 { MPI3MR_RESET_FROM_IOCFACTS_TIMEOUT, "IOC facts timeout" }, 1294 { MPI3MR_RESET_FROM_IOCINIT_TIMEOUT, "IOC init timeout" }, 1295 { MPI3MR_RESET_FROM_EVTNOTIFY_TIMEOUT, "event notify timeout" }, 1296 { MPI3MR_RESET_FROM_EVTACK_TIMEOUT, "event acknowledgment timeout" }, 1297 { 1298 MPI3MR_RESET_FROM_CIACTVRST_TIMER, 1299 "component image activation timeout" 1300 }, 1301 { 1302 MPI3MR_RESET_FROM_GETPKGVER_TIMEOUT, 1303 "get package version timeout" 1304 }, 1305 { 1306 MPI3MR_RESET_FROM_PELABORT_TIMEOUT, 1307 "persistent event log abort timeout" 1308 }, 1309 { MPI3MR_RESET_FROM_SYSFS, "sysfs invocation" }, 1310 { MPI3MR_RESET_FROM_SYSFS_TIMEOUT, "sysfs TM timeout" }, 1311 { 1312 MPI3MR_RESET_FROM_DIAG_BUFFER_POST_TIMEOUT, 1313 "diagnostic buffer post timeout" 1314 }, 1315 { MPI3MR_RESET_FROM_FIRMWARE, "firmware asynchronus reset" }, 1316 { MPI3MR_RESET_REASON_COUNT, "Reset reason count" }, 1317 }; 1318 1319 /** 1320 * mpi3mr_reset_rc_name - get reset reason code name 1321 * @reason_code: reset reason code value 1322 * 1323 * Map reset reason to an NULL terminated ASCII string 1324 * 1325 * Return: Name corresponding to reset reason value or NULL. 1326 */ 1327 static const char *mpi3mr_reset_rc_name(enum mpi3mr_reset_reason reason_code) 1328 { 1329 int i; 1330 char *name = NULL; 1331 1332 for (i = 0; i < MPI3MR_RESET_REASON_COUNT; i++) { 1333 if (mpi3mr_reset_reason_codes[i].value == reason_code) { 1334 name = mpi3mr_reset_reason_codes[i].name; 1335 break; 1336 } 1337 } 1338 return name; 1339 } 1340 1341 #define MAX_RESET_TYPE 3 1342 /* Reset type to name mapper structure*/ 1343 static const struct { 1344 U16 reset_type; 1345 char *name; 1346 } mpi3mr_reset_types[] = { 1347 { MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, "soft" }, 1348 { MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, "diag fault" }, 1349 { MAX_RESET_TYPE, "count"} 1350 }; 1351 1352 /** 1353 * mpi3mr_reset_type_name - get reset type name 1354 * @reset_type: reset type value 1355 * 1356 * Map reset type to an NULL terminated ASCII string 1357 * 1358 * Return: Name corresponding to reset type value or NULL. 1359 */ 1360 static const char *mpi3mr_reset_type_name(U16 reset_type) 1361 { 1362 int i; 1363 char *name = NULL; 1364 1365 for (i = 0; i < MAX_RESET_TYPE; i++) { 1366 if (mpi3mr_reset_types[i].reset_type == reset_type) { 1367 name = mpi3mr_reset_types[i].name; 1368 break; 1369 } 1370 } 1371 return name; 1372 } 1373 1374 /** 1375 * mpi3mr_soft_reset_success - Check softreset is success or not 1376 * @ioc_status: IOC status register value 1377 * @ioc_config: IOC config register value 1378 * 1379 * Check whether the soft reset is successful or not based on 1380 * IOC status and IOC config register values. 1381 * 1382 * Return: True when the soft reset is success, false otherwise. 1383 */ 1384 static inline bool 1385 mpi3mr_soft_reset_success(U32 ioc_status, U32 ioc_config) 1386 { 1387 if (!((ioc_status & MPI3_SYSIF_IOC_STATUS_READY) || 1388 (ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT) || 1389 (ioc_config & MPI3_SYSIF_IOC_CONFIG_ENABLE_IOC))) 1390 return true; 1391 return false; 1392 } 1393 1394 /** 1395 * mpi3mr_diagfault_success - Check diag fault is success or not 1396 * @sc: Adapter reference 1397 * @ioc_status: IOC status register value 1398 * 1399 * Check whether the controller hit diag reset fault code. 1400 * 1401 * Return: True when there is diag fault, false otherwise. 1402 */ 1403 static inline bool mpi3mr_diagfault_success(struct mpi3mr_softc *sc, 1404 U32 ioc_status) 1405 { 1406 U32 fault; 1407 1408 if (!(ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) 1409 return false; 1410 fault = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) & MPI3_SYSIF_FAULT_CODE_MASK; 1411 if (fault == MPI3_SYSIF_FAULT_CODE_DIAG_FAULT_RESET) 1412 return true; 1413 return false; 1414 } 1415 1416 /** 1417 * mpi3mr_issue_iocfacts - Send IOC Facts 1418 * @sc: Adapter instance reference 1419 * @facts_data: Cached IOC facts data 1420 * 1421 * Issue IOC Facts MPI request through admin queue and wait for 1422 * the completion of it or time out. 1423 * 1424 * Return: 0 on success, non-zero on failures. 1425 */ 1426 static int mpi3mr_issue_iocfacts(struct mpi3mr_softc *sc, 1427 Mpi3IOCFactsData_t *facts_data) 1428 { 1429 Mpi3IOCFactsRequest_t iocfacts_req; 1430 bus_dma_tag_t data_tag = NULL; 1431 bus_dmamap_t data_map = NULL; 1432 bus_addr_t data_phys = 0; 1433 void *data = NULL; 1434 U32 data_len = sizeof(*facts_data); 1435 int retval = 0; 1436 1437 U8 sgl_flags = (MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE | 1438 MPI3_SGE_FLAGS_DLAS_SYSTEM | 1439 MPI3_SGE_FLAGS_END_OF_LIST); 1440 1441 1442 /* 1443 * We can't use sc->dma_loaddr here. We set those only after we get the 1444 * iocfacts. So allocate in the lower 4GB. The amount of data is tiny 1445 * and we don't do this that often, so any bouncing we might have to do 1446 * isn't a cause for concern. 1447 */ 1448 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1449 4, 0, /* algnmnt, boundary */ 1450 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 1451 BUS_SPACE_MAXADDR, /* highaddr */ 1452 NULL, NULL, /* filter, filterarg */ 1453 data_len, /* maxsize */ 1454 1, /* nsegments */ 1455 data_len, /* maxsegsize */ 1456 0, /* flags */ 1457 NULL, NULL, /* lockfunc, lockarg */ 1458 &data_tag)) { 1459 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 1460 return (ENOMEM); 1461 } 1462 1463 if (bus_dmamem_alloc(data_tag, (void **)&data, 1464 BUS_DMA_NOWAIT, &data_map)) { 1465 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d Data DMA mem alloc failed\n", 1466 __func__, __LINE__); 1467 return (ENOMEM); 1468 } 1469 1470 bzero(data, data_len); 1471 bus_dmamap_load(data_tag, data_map, data, data_len, 1472 mpi3mr_memaddr_cb, &data_phys, BUS_DMA_NOWAIT); 1473 mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d IOCfacts data phys addr= %#016jx size= %d\n", 1474 __func__, __LINE__, (uintmax_t)data_phys, data_len); 1475 1476 if (!data) 1477 { 1478 retval = -1; 1479 printf(IOCNAME "Memory alloc for IOCFactsData: failed\n", 1480 sc->name); 1481 goto out; 1482 } 1483 1484 mtx_lock(&sc->init_cmds.completion.lock); 1485 memset(&iocfacts_req, 0, sizeof(iocfacts_req)); 1486 1487 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 1488 retval = -1; 1489 printf(IOCNAME "Issue IOCFacts: Init command is in use\n", 1490 sc->name); 1491 mtx_unlock(&sc->init_cmds.completion.lock); 1492 goto out; 1493 } 1494 1495 sc->init_cmds.state = MPI3MR_CMD_PENDING; 1496 sc->init_cmds.is_waiting = 1; 1497 sc->init_cmds.callback = NULL; 1498 iocfacts_req.HostTag = (MPI3MR_HOSTTAG_INITCMDS); 1499 iocfacts_req.Function = MPI3_FUNCTION_IOC_FACTS; 1500 1501 mpi3mr_add_sg_single(&iocfacts_req.SGL, sgl_flags, data_len, 1502 data_phys); 1503 1504 init_completion(&sc->init_cmds.completion); 1505 1506 retval = mpi3mr_submit_admin_cmd(sc, &iocfacts_req, 1507 sizeof(iocfacts_req)); 1508 1509 if (retval) { 1510 printf(IOCNAME "Issue IOCFacts: Admin Post failed\n", 1511 sc->name); 1512 goto out_unlock; 1513 } 1514 1515 wait_for_completion_timeout(&sc->init_cmds.completion, 1516 (MPI3MR_INTADMCMD_TIMEOUT)); 1517 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 1518 printf(IOCNAME "Issue IOCFacts: command timed out\n", 1519 sc->name); 1520 mpi3mr_check_rh_fault_ioc(sc, 1521 MPI3MR_RESET_FROM_IOCFACTS_TIMEOUT); 1522 sc->unrecoverable = 1; 1523 retval = -1; 1524 goto out_unlock; 1525 } 1526 1527 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 1528 != MPI3_IOCSTATUS_SUCCESS ) { 1529 printf(IOCNAME "Issue IOCFacts: Failed IOCStatus(0x%04x) " 1530 " Loginfo(0x%08x) \n" , sc->name, 1531 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 1532 sc->init_cmds.ioc_loginfo); 1533 retval = -1; 1534 goto out_unlock; 1535 } 1536 1537 memcpy(facts_data, (U8 *)data, data_len); 1538 out_unlock: 1539 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 1540 mtx_unlock(&sc->init_cmds.completion.lock); 1541 1542 out: 1543 if (data_phys != 0) 1544 bus_dmamap_unload(data_tag, data_map); 1545 if (data != NULL) 1546 bus_dmamem_free(data_tag, data, data_map); 1547 if (data_tag != NULL) 1548 bus_dma_tag_destroy(data_tag); 1549 return retval; 1550 } 1551 1552 /** 1553 * mpi3mr_process_factsdata - Process IOC facts data 1554 * @sc: Adapter instance reference 1555 * @facts_data: Cached IOC facts data 1556 * 1557 * Convert IOC facts data into cpu endianness and cache it in 1558 * the driver . 1559 * 1560 * Return: Nothing. 1561 */ 1562 static int mpi3mr_process_factsdata(struct mpi3mr_softc *sc, 1563 Mpi3IOCFactsData_t *facts_data) 1564 { 1565 int retval = 0; 1566 U32 ioc_config, req_sz, facts_flags; 1567 struct mpi3mr_compimg_ver *fwver; 1568 1569 if (le16toh(facts_data->IOCFactsDataLength) != 1570 (sizeof(*facts_data) / 4)) { 1571 mpi3mr_dprint(sc, MPI3MR_INFO, "IOCFacts data length mismatch " 1572 " driver_sz(%ld) firmware_sz(%d) \n", 1573 sizeof(*facts_data), 1574 facts_data->IOCFactsDataLength); 1575 } 1576 1577 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 1578 req_sz = 1 << ((ioc_config & MPI3_SYSIF_IOC_CONFIG_OPER_REQ_ENT_SZ) >> 1579 MPI3_SYSIF_IOC_CONFIG_OPER_REQ_ENT_SZ_SHIFT); 1580 1581 if (facts_data->IOCRequestFrameSize != (req_sz/4)) { 1582 mpi3mr_dprint(sc, MPI3MR_INFO, "IOCFacts data reqFrameSize mismatch " 1583 " hw_size(%d) firmware_sz(%d) \n" , req_sz/4, 1584 facts_data->IOCRequestFrameSize); 1585 } 1586 1587 memset(&sc->facts, 0, sizeof(sc->facts)); 1588 1589 facts_flags = le32toh(facts_data->Flags); 1590 sc->facts.op_req_sz = req_sz; 1591 sc->op_reply_sz = 1 << ((ioc_config & 1592 MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ) >> 1593 MPI3_SYSIF_IOC_CONFIG_OPER_RPY_ENT_SZ_SHIFT); 1594 1595 sc->facts.ioc_num = facts_data->IOCNumber; 1596 sc->facts.who_init = facts_data->WhoInit; 1597 sc->facts.max_msix_vectors = facts_data->MaxMSIxVectors; 1598 sc->facts.personality = (facts_flags & 1599 MPI3_IOCFACTS_FLAGS_PERSONALITY_MASK); 1600 sc->facts.dma_mask = (facts_flags & 1601 MPI3_IOCFACTS_FLAGS_DMA_ADDRESS_WIDTH_MASK) >> 1602 MPI3_IOCFACTS_FLAGS_DMA_ADDRESS_WIDTH_SHIFT; 1603 sc->facts.protocol_flags = facts_data->ProtocolFlags; 1604 sc->facts.mpi_version = (facts_data->MPIVersion.Word); 1605 sc->facts.max_reqs = (facts_data->MaxOutstandingRequests); 1606 sc->facts.product_id = (facts_data->ProductID); 1607 sc->facts.reply_sz = (facts_data->ReplyFrameSize) * 4; 1608 sc->facts.exceptions = (facts_data->IOCExceptions); 1609 sc->facts.max_perids = (facts_data->MaxPersistentID); 1610 sc->facts.max_vds = (facts_data->MaxVDs); 1611 sc->facts.max_hpds = (facts_data->MaxHostPDs); 1612 sc->facts.max_advhpds = (facts_data->MaxAdvHostPDs); 1613 sc->facts.max_raidpds = (facts_data->MaxRAIDPDs); 1614 sc->facts.max_nvme = (facts_data->MaxNVMe); 1615 sc->facts.max_pcieswitches = 1616 (facts_data->MaxPCIeSwitches); 1617 sc->facts.max_sasexpanders = 1618 (facts_data->MaxSASExpanders); 1619 sc->facts.max_sasinitiators = 1620 (facts_data->MaxSASInitiators); 1621 sc->facts.max_enclosures = (facts_data->MaxEnclosures); 1622 sc->facts.min_devhandle = (facts_data->MinDevHandle); 1623 sc->facts.max_devhandle = (facts_data->MaxDevHandle); 1624 sc->facts.max_op_req_q = 1625 (facts_data->MaxOperationalRequestQueues); 1626 sc->facts.max_op_reply_q = 1627 (facts_data->MaxOperationalReplyQueues); 1628 sc->facts.ioc_capabilities = 1629 (facts_data->IOCCapabilities); 1630 sc->facts.fw_ver.build_num = 1631 (facts_data->FWVersion.BuildNum); 1632 sc->facts.fw_ver.cust_id = 1633 (facts_data->FWVersion.CustomerID); 1634 sc->facts.fw_ver.ph_minor = facts_data->FWVersion.PhaseMinor; 1635 sc->facts.fw_ver.ph_major = facts_data->FWVersion.PhaseMajor; 1636 sc->facts.fw_ver.gen_minor = facts_data->FWVersion.GenMinor; 1637 sc->facts.fw_ver.gen_major = facts_data->FWVersion.GenMajor; 1638 sc->max_msix_vectors = min(sc->max_msix_vectors, 1639 sc->facts.max_msix_vectors); 1640 sc->facts.sge_mod_mask = facts_data->SGEModifierMask; 1641 sc->facts.sge_mod_value = facts_data->SGEModifierValue; 1642 sc->facts.sge_mod_shift = facts_data->SGEModifierShift; 1643 sc->facts.shutdown_timeout = 1644 (facts_data->ShutdownTimeout); 1645 sc->facts.max_dev_per_tg = facts_data->MaxDevicesPerThrottleGroup; 1646 sc->facts.io_throttle_data_length = 1647 facts_data->IOThrottleDataLength; 1648 sc->facts.max_io_throttle_group = 1649 facts_data->MaxIOThrottleGroup; 1650 sc->facts.io_throttle_low = facts_data->IOThrottleLow; 1651 sc->facts.io_throttle_high = facts_data->IOThrottleHigh; 1652 1653 /*Store in 512b block count*/ 1654 if (sc->facts.io_throttle_data_length) 1655 sc->io_throttle_data_length = 1656 (sc->facts.io_throttle_data_length * 2 * 4); 1657 else 1658 /* set the length to 1MB + 1K to disable throttle*/ 1659 sc->io_throttle_data_length = MPI3MR_MAX_SECTORS + 2; 1660 1661 sc->io_throttle_high = (sc->facts.io_throttle_high * 2 * 1024); 1662 sc->io_throttle_low = (sc->facts.io_throttle_low * 2 * 1024); 1663 1664 fwver = &sc->facts.fw_ver; 1665 snprintf(sc->fw_version, sizeof(sc->fw_version), 1666 "%d.%d.%d.%d.%05d-%05d", 1667 fwver->gen_major, fwver->gen_minor, fwver->ph_major, 1668 fwver->ph_minor, fwver->cust_id, fwver->build_num); 1669 1670 mpi3mr_dprint(sc, MPI3MR_INFO, "ioc_num(%d), maxopQ(%d), maxopRepQ(%d), maxdh(%d)," 1671 "maxreqs(%d), mindh(%d) maxPDs(%d) maxvectors(%d) maxperids(%d)\n", 1672 sc->facts.ioc_num, sc->facts.max_op_req_q, 1673 sc->facts.max_op_reply_q, sc->facts.max_devhandle, 1674 sc->facts.max_reqs, sc->facts.min_devhandle, 1675 sc->facts.max_pds, sc->facts.max_msix_vectors, 1676 sc->facts.max_perids); 1677 mpi3mr_dprint(sc, MPI3MR_INFO, "SGEModMask 0x%x SGEModVal 0x%x SGEModShift 0x%x\n", 1678 sc->facts.sge_mod_mask, sc->facts.sge_mod_value, 1679 sc->facts.sge_mod_shift); 1680 mpi3mr_dprint(sc, MPI3MR_INFO, 1681 "max_dev_per_throttle_group(%d), max_throttle_groups(%d), io_throttle_data_len(%dKiB), io_throttle_high(%dMiB), io_throttle_low(%dMiB)\n", 1682 sc->facts.max_dev_per_tg, sc->facts.max_io_throttle_group, 1683 sc->facts.io_throttle_data_length * 4, 1684 sc->facts.io_throttle_high, sc->facts.io_throttle_low); 1685 1686 sc->max_host_ios = sc->facts.max_reqs - 1687 (MPI3MR_INTERNALCMDS_RESVD + 1); 1688 1689 /* 1690 * Set the DMA mask for the card. dma_mask is the number of bits that 1691 * can have bits set in them. Translate this into bus_dma loaddr args. 1692 * Add sanity for more bits than address space or other overflow 1693 * situations. 1694 */ 1695 if (sc->facts.dma_mask == 0 || 1696 (sc->facts.dma_mask >= sizeof(bus_addr_t) * 8)) 1697 sc->dma_loaddr = BUS_SPACE_MAXADDR; 1698 else 1699 sc->dma_loaddr = ~((1ull << sc->facts.dma_mask) - 1); 1700 mpi3mr_dprint(sc, MPI3MR_INFO, 1701 "dma_mask bits: %d loaddr 0x%jx\n", 1702 sc->facts.dma_mask, sc->dma_loaddr); 1703 1704 return retval; 1705 } 1706 1707 static inline void mpi3mr_setup_reply_free_queues(struct mpi3mr_softc *sc) 1708 { 1709 int i; 1710 bus_addr_t phys_addr; 1711 1712 /* initialize Reply buffer Queue */ 1713 for (i = 0, phys_addr = sc->reply_buf_phys; 1714 i < sc->num_reply_bufs; i++, phys_addr += sc->reply_sz) 1715 sc->reply_free_q[i] = phys_addr; 1716 sc->reply_free_q[i] = (0); 1717 1718 /* initialize Sense Buffer Queue */ 1719 for (i = 0, phys_addr = sc->sense_buf_phys; 1720 i < sc->num_sense_bufs; i++, phys_addr += MPI3MR_SENSEBUF_SZ) 1721 sc->sense_buf_q[i] = phys_addr; 1722 sc->sense_buf_q[i] = (0); 1723 1724 } 1725 1726 static int mpi3mr_reply_dma_alloc(struct mpi3mr_softc *sc) 1727 { 1728 U32 sz; 1729 1730 sc->num_reply_bufs = sc->facts.max_reqs + MPI3MR_NUM_EVTREPLIES; 1731 sc->reply_free_q_sz = sc->num_reply_bufs + 1; 1732 sc->num_sense_bufs = sc->facts.max_reqs / MPI3MR_SENSEBUF_FACTOR; 1733 sc->sense_buf_q_sz = sc->num_sense_bufs + 1; 1734 1735 sz = sc->num_reply_bufs * sc->reply_sz; 1736 1737 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1738 16, 0, /* algnmnt, boundary */ 1739 sc->dma_loaddr, /* lowaddr */ 1740 BUS_SPACE_MAXADDR, /* highaddr */ 1741 NULL, NULL, /* filter, filterarg */ 1742 sz, /* maxsize */ 1743 1, /* nsegments */ 1744 sz, /* maxsegsize */ 1745 0, /* flags */ 1746 NULL, NULL, /* lockfunc, lockarg */ 1747 &sc->reply_buf_tag)) { 1748 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 1749 return (ENOMEM); 1750 } 1751 1752 if (bus_dmamem_alloc(sc->reply_buf_tag, (void **)&sc->reply_buf, 1753 BUS_DMA_NOWAIT, &sc->reply_buf_dmamap)) { 1754 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d DMA mem alloc failed\n", 1755 __func__, __LINE__); 1756 return (ENOMEM); 1757 } 1758 1759 bzero(sc->reply_buf, sz); 1760 bus_dmamap_load(sc->reply_buf_tag, sc->reply_buf_dmamap, sc->reply_buf, sz, 1761 mpi3mr_memaddr_cb, &sc->reply_buf_phys, BUS_DMA_NOWAIT); 1762 1763 sc->reply_buf_dma_min_address = sc->reply_buf_phys; 1764 sc->reply_buf_dma_max_address = sc->reply_buf_phys + sz; 1765 mpi3mr_dprint(sc, MPI3MR_XINFO, "reply buf (0x%p): depth(%d), frame_size(%d), " 1766 "pool_size(%d kB), reply_buf_dma(0x%llx)\n", 1767 sc->reply_buf, sc->num_reply_bufs, sc->reply_sz, 1768 (sz / 1024), (unsigned long long)sc->reply_buf_phys); 1769 1770 /* reply free queue, 8 byte align */ 1771 sz = sc->reply_free_q_sz * 8; 1772 1773 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1774 8, 0, /* algnmnt, boundary */ 1775 sc->dma_loaddr, /* lowaddr */ 1776 BUS_SPACE_MAXADDR, /* highaddr */ 1777 NULL, NULL, /* filter, filterarg */ 1778 sz, /* maxsize */ 1779 1, /* nsegments */ 1780 sz, /* maxsegsize */ 1781 0, /* flags */ 1782 NULL, NULL, /* lockfunc, lockarg */ 1783 &sc->reply_free_q_tag)) { 1784 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate reply free queue DMA tag\n"); 1785 return (ENOMEM); 1786 } 1787 1788 if (bus_dmamem_alloc(sc->reply_free_q_tag, (void **)&sc->reply_free_q, 1789 BUS_DMA_NOWAIT, &sc->reply_free_q_dmamap)) { 1790 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d DMA mem alloc failed\n", 1791 __func__, __LINE__); 1792 return (ENOMEM); 1793 } 1794 1795 bzero(sc->reply_free_q, sz); 1796 bus_dmamap_load(sc->reply_free_q_tag, sc->reply_free_q_dmamap, sc->reply_free_q, sz, 1797 mpi3mr_memaddr_cb, &sc->reply_free_q_phys, BUS_DMA_NOWAIT); 1798 1799 mpi3mr_dprint(sc, MPI3MR_XINFO, "reply_free_q (0x%p): depth(%d), frame_size(%d), " 1800 "pool_size(%d kB), reply_free_q_dma(0x%llx)\n", 1801 sc->reply_free_q, sc->reply_free_q_sz, 8, (sz / 1024), 1802 (unsigned long long)sc->reply_free_q_phys); 1803 1804 /* sense buffer pool, 4 byte align */ 1805 sz = sc->num_sense_bufs * MPI3MR_SENSEBUF_SZ; 1806 1807 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1808 4, 0, /* algnmnt, boundary */ 1809 sc->dma_loaddr, /* lowaddr */ 1810 BUS_SPACE_MAXADDR, /* highaddr */ 1811 NULL, NULL, /* filter, filterarg */ 1812 sz, /* maxsize */ 1813 1, /* nsegments */ 1814 sz, /* maxsegsize */ 1815 0, /* flags */ 1816 NULL, NULL, /* lockfunc, lockarg */ 1817 &sc->sense_buf_tag)) { 1818 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Sense buffer DMA tag\n"); 1819 return (ENOMEM); 1820 } 1821 1822 if (bus_dmamem_alloc(sc->sense_buf_tag, (void **)&sc->sense_buf, 1823 BUS_DMA_NOWAIT, &sc->sense_buf_dmamap)) { 1824 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d DMA mem alloc failed\n", 1825 __func__, __LINE__); 1826 return (ENOMEM); 1827 } 1828 1829 bzero(sc->sense_buf, sz); 1830 bus_dmamap_load(sc->sense_buf_tag, sc->sense_buf_dmamap, sc->sense_buf, sz, 1831 mpi3mr_memaddr_cb, &sc->sense_buf_phys, BUS_DMA_NOWAIT); 1832 1833 mpi3mr_dprint(sc, MPI3MR_XINFO, "sense_buf (0x%p): depth(%d), frame_size(%d), " 1834 "pool_size(%d kB), sense_dma(0x%llx)\n", 1835 sc->sense_buf, sc->num_sense_bufs, MPI3MR_SENSEBUF_SZ, 1836 (sz / 1024), (unsigned long long)sc->sense_buf_phys); 1837 1838 /* sense buffer queue, 8 byte align */ 1839 sz = sc->sense_buf_q_sz * 8; 1840 1841 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1842 8, 0, /* algnmnt, boundary */ 1843 sc->dma_loaddr, /* lowaddr */ 1844 BUS_SPACE_MAXADDR, /* highaddr */ 1845 NULL, NULL, /* filter, filterarg */ 1846 sz, /* maxsize */ 1847 1, /* nsegments */ 1848 sz, /* maxsegsize */ 1849 0, /* flags */ 1850 NULL, NULL, /* lockfunc, lockarg */ 1851 &sc->sense_buf_q_tag)) { 1852 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Sense buffer Queue DMA tag\n"); 1853 return (ENOMEM); 1854 } 1855 1856 if (bus_dmamem_alloc(sc->sense_buf_q_tag, (void **)&sc->sense_buf_q, 1857 BUS_DMA_NOWAIT, &sc->sense_buf_q_dmamap)) { 1858 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d DMA mem alloc failed\n", 1859 __func__, __LINE__); 1860 return (ENOMEM); 1861 } 1862 1863 bzero(sc->sense_buf_q, sz); 1864 bus_dmamap_load(sc->sense_buf_q_tag, sc->sense_buf_q_dmamap, sc->sense_buf_q, sz, 1865 mpi3mr_memaddr_cb, &sc->sense_buf_q_phys, BUS_DMA_NOWAIT); 1866 1867 mpi3mr_dprint(sc, MPI3MR_XINFO, "sense_buf_q (0x%p): depth(%d), frame_size(%d), " 1868 "pool_size(%d kB), sense_dma(0x%llx)\n", 1869 sc->sense_buf_q, sc->sense_buf_q_sz, 8, (sz / 1024), 1870 (unsigned long long)sc->sense_buf_q_phys); 1871 1872 return 0; 1873 } 1874 1875 static int mpi3mr_reply_alloc(struct mpi3mr_softc *sc) 1876 { 1877 int retval = 0; 1878 U32 i; 1879 1880 if (sc->init_cmds.reply) 1881 goto post_reply_sbuf; 1882 1883 sc->init_cmds.reply = malloc(sc->reply_sz, 1884 M_MPI3MR, M_NOWAIT | M_ZERO); 1885 1886 if (!sc->init_cmds.reply) { 1887 printf(IOCNAME "Cannot allocate memory for init_cmds.reply\n", 1888 sc->name); 1889 goto out_failed; 1890 } 1891 1892 sc->ioctl_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO); 1893 if (!sc->ioctl_cmds.reply) { 1894 printf(IOCNAME "Cannot allocate memory for ioctl_cmds.reply\n", 1895 sc->name); 1896 goto out_failed; 1897 } 1898 1899 sc->host_tm_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO); 1900 if (!sc->host_tm_cmds.reply) { 1901 printf(IOCNAME "Cannot allocate memory for host_tm.reply\n", 1902 sc->name); 1903 goto out_failed; 1904 } 1905 for (i=0; i<MPI3MR_NUM_DEVRMCMD; i++) { 1906 sc->dev_rmhs_cmds[i].reply = malloc(sc->reply_sz, 1907 M_MPI3MR, M_NOWAIT | M_ZERO); 1908 if (!sc->dev_rmhs_cmds[i].reply) { 1909 printf(IOCNAME "Cannot allocate memory for" 1910 " dev_rmhs_cmd[%d].reply\n", 1911 sc->name, i); 1912 goto out_failed; 1913 } 1914 } 1915 1916 for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) { 1917 sc->evtack_cmds[i].reply = malloc(sc->reply_sz, 1918 M_MPI3MR, M_NOWAIT | M_ZERO); 1919 if (!sc->evtack_cmds[i].reply) 1920 goto out_failed; 1921 } 1922 1923 sc->dev_handle_bitmap_sz = MPI3MR_DIV_ROUND_UP(sc->facts.max_devhandle, 8); 1924 1925 sc->removepend_bitmap = malloc(sc->dev_handle_bitmap_sz, 1926 M_MPI3MR, M_NOWAIT | M_ZERO); 1927 if (!sc->removepend_bitmap) { 1928 printf(IOCNAME "Cannot alloc memory for remove pend bitmap\n", 1929 sc->name); 1930 goto out_failed; 1931 } 1932 1933 sc->devrem_bitmap_sz = MPI3MR_DIV_ROUND_UP(MPI3MR_NUM_DEVRMCMD, 8); 1934 sc->devrem_bitmap = malloc(sc->devrem_bitmap_sz, 1935 M_MPI3MR, M_NOWAIT | M_ZERO); 1936 if (!sc->devrem_bitmap) { 1937 printf(IOCNAME "Cannot alloc memory for dev remove bitmap\n", 1938 sc->name); 1939 goto out_failed; 1940 } 1941 1942 sc->evtack_cmds_bitmap_sz = MPI3MR_DIV_ROUND_UP(MPI3MR_NUM_EVTACKCMD, 8); 1943 1944 sc->evtack_cmds_bitmap = malloc(sc->evtack_cmds_bitmap_sz, 1945 M_MPI3MR, M_NOWAIT | M_ZERO); 1946 if (!sc->evtack_cmds_bitmap) 1947 goto out_failed; 1948 1949 if (mpi3mr_reply_dma_alloc(sc)) { 1950 printf(IOCNAME "func:%s line:%d DMA memory allocation failed\n", 1951 sc->name, __func__, __LINE__); 1952 goto out_failed; 1953 } 1954 1955 post_reply_sbuf: 1956 mpi3mr_setup_reply_free_queues(sc); 1957 return retval; 1958 out_failed: 1959 mpi3mr_cleanup_interrupts(sc); 1960 mpi3mr_free_mem(sc); 1961 retval = -1; 1962 return retval; 1963 } 1964 1965 static void 1966 mpi3mr_print_fw_pkg_ver(struct mpi3mr_softc *sc) 1967 { 1968 int retval = 0; 1969 void *fw_pkg_ver = NULL; 1970 bus_dma_tag_t fw_pkg_ver_tag; 1971 bus_dmamap_t fw_pkg_ver_map; 1972 bus_addr_t fw_pkg_ver_dma; 1973 Mpi3CIUploadRequest_t ci_upload; 1974 Mpi3ComponentImageHeader_t *ci_header; 1975 U32 fw_pkg_ver_len = sizeof(*ci_header); 1976 U8 sgl_flags = MPI3MR_SGEFLAGS_SYSTEM_SIMPLE_END_OF_LIST; 1977 1978 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 1979 4, 0, /* algnmnt, boundary */ 1980 sc->dma_loaddr, /* lowaddr */ 1981 BUS_SPACE_MAXADDR, /* highaddr */ 1982 NULL, NULL, /* filter, filterarg */ 1983 fw_pkg_ver_len, /* maxsize */ 1984 1, /* nsegments */ 1985 fw_pkg_ver_len, /* maxsegsize */ 1986 0, /* flags */ 1987 NULL, NULL, /* lockfunc, lockarg */ 1988 &fw_pkg_ver_tag)) { 1989 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate fw package version request DMA tag\n"); 1990 return; 1991 } 1992 1993 if (bus_dmamem_alloc(fw_pkg_ver_tag, (void **)&fw_pkg_ver, BUS_DMA_NOWAIT, &fw_pkg_ver_map)) { 1994 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d fw package version DMA mem alloc failed\n", 1995 __func__, __LINE__); 1996 return; 1997 } 1998 1999 bzero(fw_pkg_ver, fw_pkg_ver_len); 2000 2001 bus_dmamap_load(fw_pkg_ver_tag, fw_pkg_ver_map, fw_pkg_ver, fw_pkg_ver_len, 2002 mpi3mr_memaddr_cb, &fw_pkg_ver_dma, BUS_DMA_NOWAIT); 2003 2004 mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d fw package version phys addr= %#016jx size= %d\n", 2005 __func__, __LINE__, (uintmax_t)fw_pkg_ver_dma, fw_pkg_ver_len); 2006 2007 if (!fw_pkg_ver) { 2008 mpi3mr_dprint(sc, MPI3MR_ERROR, "Memory alloc for fw package version failed\n"); 2009 goto out; 2010 } 2011 2012 memset(&ci_upload, 0, sizeof(ci_upload)); 2013 mtx_lock(&sc->init_cmds.completion.lock); 2014 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 2015 mpi3mr_dprint(sc, MPI3MR_INFO,"Issue CI Header Upload: command is in use\n"); 2016 mtx_unlock(&sc->init_cmds.completion.lock); 2017 goto out; 2018 } 2019 sc->init_cmds.state = MPI3MR_CMD_PENDING; 2020 sc->init_cmds.is_waiting = 1; 2021 sc->init_cmds.callback = NULL; 2022 ci_upload.HostTag = htole16(MPI3MR_HOSTTAG_INITCMDS); 2023 ci_upload.Function = MPI3_FUNCTION_CI_UPLOAD; 2024 ci_upload.MsgFlags = MPI3_CI_UPLOAD_MSGFLAGS_LOCATION_PRIMARY; 2025 ci_upload.ImageOffset = MPI3_IMAGE_HEADER_SIGNATURE0_OFFSET; 2026 ci_upload.SegmentSize = MPI3_IMAGE_HEADER_SIZE; 2027 2028 mpi3mr_add_sg_single(&ci_upload.SGL, sgl_flags, fw_pkg_ver_len, 2029 fw_pkg_ver_dma); 2030 2031 init_completion(&sc->init_cmds.completion); 2032 if ((retval = mpi3mr_submit_admin_cmd(sc, &ci_upload, sizeof(ci_upload)))) { 2033 mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue CI Header Upload: Admin Post failed\n"); 2034 goto out_unlock; 2035 } 2036 wait_for_completion_timeout(&sc->init_cmds.completion, 2037 (MPI3MR_INTADMCMD_TIMEOUT)); 2038 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 2039 mpi3mr_dprint(sc, MPI3MR_ERROR, "Issue CI Header Upload: command timed out\n"); 2040 sc->init_cmds.is_waiting = 0; 2041 if (!(sc->init_cmds.state & MPI3MR_CMD_RESET)) 2042 mpi3mr_check_rh_fault_ioc(sc, 2043 MPI3MR_RESET_FROM_GETPKGVER_TIMEOUT); 2044 goto out_unlock; 2045 } 2046 if ((GET_IOC_STATUS(sc->init_cmds.ioc_status)) != MPI3_IOCSTATUS_SUCCESS) { 2047 mpi3mr_dprint(sc, MPI3MR_ERROR, 2048 "Issue CI Header Upload: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n", 2049 GET_IOC_STATUS(sc->init_cmds.ioc_status), sc->init_cmds.ioc_loginfo); 2050 goto out_unlock; 2051 } 2052 2053 ci_header = (Mpi3ComponentImageHeader_t *) fw_pkg_ver; 2054 mpi3mr_dprint(sc, MPI3MR_XINFO, 2055 "Issue CI Header Upload:EnvVariableOffset(0x%x) \ 2056 HeaderSize(0x%x) Signature1(0x%x)\n", 2057 ci_header->EnvironmentVariableOffset, 2058 ci_header->HeaderSize, 2059 ci_header->Signature1); 2060 mpi3mr_dprint(sc, MPI3MR_INFO, "FW Package Version: %02d.%02d.%02d.%02d\n", 2061 ci_header->ComponentImageVersion.GenMajor, 2062 ci_header->ComponentImageVersion.GenMinor, 2063 ci_header->ComponentImageVersion.PhaseMajor, 2064 ci_header->ComponentImageVersion.PhaseMinor); 2065 out_unlock: 2066 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 2067 mtx_unlock(&sc->init_cmds.completion.lock); 2068 2069 out: 2070 if (fw_pkg_ver_dma != 0) 2071 bus_dmamap_unload(fw_pkg_ver_tag, fw_pkg_ver_map); 2072 if (fw_pkg_ver) 2073 bus_dmamem_free(fw_pkg_ver_tag, fw_pkg_ver, fw_pkg_ver_map); 2074 if (fw_pkg_ver_tag) 2075 bus_dma_tag_destroy(fw_pkg_ver_tag); 2076 2077 } 2078 2079 /** 2080 * mpi3mr_issue_iocinit - Send IOC Init 2081 * @sc: Adapter instance reference 2082 * 2083 * Issue IOC Init MPI request through admin queue and wait for 2084 * the completion of it or time out. 2085 * 2086 * Return: 0 on success, non-zero on failures. 2087 */ 2088 static int mpi3mr_issue_iocinit(struct mpi3mr_softc *sc) 2089 { 2090 Mpi3IOCInitRequest_t iocinit_req; 2091 Mpi3DriverInfoLayout_t *drvr_info = NULL; 2092 bus_dma_tag_t drvr_info_tag; 2093 bus_dmamap_t drvr_info_map; 2094 bus_addr_t drvr_info_phys; 2095 U32 drvr_info_len = sizeof(*drvr_info); 2096 int retval = 0; 2097 struct timeval now; 2098 uint64_t time_in_msec; 2099 2100 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 2101 4, 0, /* algnmnt, boundary */ 2102 sc->dma_loaddr, /* lowaddr */ 2103 BUS_SPACE_MAXADDR, /* highaddr */ 2104 NULL, NULL, /* filter, filterarg */ 2105 drvr_info_len, /* maxsize */ 2106 1, /* nsegments */ 2107 drvr_info_len, /* maxsegsize */ 2108 0, /* flags */ 2109 NULL, NULL, /* lockfunc, lockarg */ 2110 &drvr_info_tag)) { 2111 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 2112 return (ENOMEM); 2113 } 2114 2115 if (bus_dmamem_alloc(drvr_info_tag, (void **)&drvr_info, 2116 BUS_DMA_NOWAIT, &drvr_info_map)) { 2117 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d Data DMA mem alloc failed\n", 2118 __func__, __LINE__); 2119 return (ENOMEM); 2120 } 2121 2122 bzero(drvr_info, drvr_info_len); 2123 bus_dmamap_load(drvr_info_tag, drvr_info_map, drvr_info, drvr_info_len, 2124 mpi3mr_memaddr_cb, &drvr_info_phys, BUS_DMA_NOWAIT); 2125 mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d IOCfacts drvr_info phys addr= %#016jx size= %d\n", 2126 __func__, __LINE__, (uintmax_t)drvr_info_phys, drvr_info_len); 2127 2128 if (!drvr_info) 2129 { 2130 retval = -1; 2131 printf(IOCNAME "Memory alloc for Driver Info failed\n", 2132 sc->name); 2133 goto out; 2134 } 2135 drvr_info->InformationLength = (drvr_info_len); 2136 strcpy(drvr_info->DriverSignature, "Broadcom"); 2137 strcpy(drvr_info->OsName, "FreeBSD"); 2138 strcpy(drvr_info->OsVersion, fmt_os_ver); 2139 strcpy(drvr_info->DriverName, MPI3MR_DRIVER_NAME); 2140 strcpy(drvr_info->DriverVersion, MPI3MR_DRIVER_VERSION); 2141 strcpy(drvr_info->DriverReleaseDate, MPI3MR_DRIVER_RELDATE); 2142 drvr_info->DriverCapabilities = 0; 2143 memcpy((U8 *)&sc->driver_info, (U8 *)drvr_info, sizeof(sc->driver_info)); 2144 2145 memset(&iocinit_req, 0, sizeof(iocinit_req)); 2146 mtx_lock(&sc->init_cmds.completion.lock); 2147 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 2148 retval = -1; 2149 printf(IOCNAME "Issue IOCInit: Init command is in use\n", 2150 sc->name); 2151 mtx_unlock(&sc->init_cmds.completion.lock); 2152 goto out; 2153 } 2154 sc->init_cmds.state = MPI3MR_CMD_PENDING; 2155 sc->init_cmds.is_waiting = 1; 2156 sc->init_cmds.callback = NULL; 2157 iocinit_req.HostTag = MPI3MR_HOSTTAG_INITCMDS; 2158 iocinit_req.Function = MPI3_FUNCTION_IOC_INIT; 2159 iocinit_req.MPIVersion.Struct.Dev = MPI3_VERSION_DEV; 2160 iocinit_req.MPIVersion.Struct.Unit = MPI3_VERSION_UNIT; 2161 iocinit_req.MPIVersion.Struct.Major = MPI3_VERSION_MAJOR; 2162 iocinit_req.MPIVersion.Struct.Minor = MPI3_VERSION_MINOR; 2163 iocinit_req.WhoInit = MPI3_WHOINIT_HOST_DRIVER; 2164 iocinit_req.ReplyFreeQueueDepth = sc->reply_free_q_sz; 2165 iocinit_req.ReplyFreeQueueAddress = 2166 sc->reply_free_q_phys; 2167 iocinit_req.SenseBufferLength = MPI3MR_SENSEBUF_SZ; 2168 iocinit_req.SenseBufferFreeQueueDepth = 2169 sc->sense_buf_q_sz; 2170 iocinit_req.SenseBufferFreeQueueAddress = 2171 sc->sense_buf_q_phys; 2172 iocinit_req.DriverInformationAddress = drvr_info_phys; 2173 2174 getmicrotime(&now); 2175 time_in_msec = (now.tv_sec * 1000 + now.tv_usec/1000); 2176 iocinit_req.TimeStamp = htole64(time_in_msec); 2177 2178 init_completion(&sc->init_cmds.completion); 2179 retval = mpi3mr_submit_admin_cmd(sc, &iocinit_req, 2180 sizeof(iocinit_req)); 2181 2182 if (retval) { 2183 printf(IOCNAME "Issue IOCInit: Admin Post failed\n", 2184 sc->name); 2185 goto out_unlock; 2186 } 2187 2188 wait_for_completion_timeout(&sc->init_cmds.completion, 2189 (MPI3MR_INTADMCMD_TIMEOUT)); 2190 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 2191 printf(IOCNAME "Issue IOCInit: command timed out\n", 2192 sc->name); 2193 mpi3mr_check_rh_fault_ioc(sc, 2194 MPI3MR_RESET_FROM_IOCINIT_TIMEOUT); 2195 sc->unrecoverable = 1; 2196 retval = -1; 2197 goto out_unlock; 2198 } 2199 2200 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 2201 != MPI3_IOCSTATUS_SUCCESS ) { 2202 printf(IOCNAME "Issue IOCInit: Failed IOCStatus(0x%04x) " 2203 " Loginfo(0x%08x) \n" , sc->name, 2204 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 2205 sc->init_cmds.ioc_loginfo); 2206 retval = -1; 2207 goto out_unlock; 2208 } 2209 2210 out_unlock: 2211 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 2212 mtx_unlock(&sc->init_cmds.completion.lock); 2213 2214 out: 2215 if (drvr_info_phys != 0) 2216 bus_dmamap_unload(drvr_info_tag, drvr_info_map); 2217 if (drvr_info != NULL) 2218 bus_dmamem_free(drvr_info_tag, drvr_info, drvr_info_map); 2219 if (drvr_info_tag != NULL) 2220 bus_dma_tag_destroy(drvr_info_tag); 2221 return retval; 2222 } 2223 2224 static void 2225 mpi3mr_display_ioc_info(struct mpi3mr_softc *sc) 2226 { 2227 int i = 0; 2228 char personality[16]; 2229 2230 switch (sc->facts.personality) { 2231 case MPI3_IOCFACTS_FLAGS_PERSONALITY_EHBA: 2232 strcpy(personality, "Enhanced HBA"); 2233 break; 2234 case MPI3_IOCFACTS_FLAGS_PERSONALITY_RAID_DDR: 2235 strcpy(personality, "RAID"); 2236 break; 2237 default: 2238 strcpy(personality, "Unknown"); 2239 break; 2240 } 2241 2242 mpi3mr_dprint(sc, MPI3MR_INFO, "Current Personality: %s\n", personality); 2243 2244 mpi3mr_dprint(sc, MPI3MR_INFO, "%s\n", sc->fw_version); 2245 2246 mpi3mr_dprint(sc, MPI3MR_INFO, "Protocol=("); 2247 2248 if (sc->facts.protocol_flags & 2249 MPI3_IOCFACTS_PROTOCOL_SCSI_INITIATOR) { 2250 printf("Initiator"); 2251 i++; 2252 } 2253 2254 if (sc->facts.protocol_flags & 2255 MPI3_IOCFACTS_PROTOCOL_SCSI_TARGET) { 2256 printf("%sTarget", i ? "," : ""); 2257 i++; 2258 } 2259 2260 if (sc->facts.protocol_flags & 2261 MPI3_IOCFACTS_PROTOCOL_NVME) { 2262 printf("%sNVMe attachment", i ? "," : ""); 2263 i++; 2264 } 2265 i = 0; 2266 printf("), "); 2267 printf("Capabilities=("); 2268 2269 if (sc->facts.ioc_capabilities & 2270 MPI3_IOCFACTS_CAPABILITY_RAID_CAPABLE) { 2271 printf("RAID"); 2272 i++; 2273 } 2274 2275 printf(")\n"); 2276 } 2277 2278 /** 2279 * mpi3mr_unmask_events - Unmask events in event mask bitmap 2280 * @sc: Adapter instance reference 2281 * @event: MPI event ID 2282 * 2283 * Un mask the specific event by resetting the event_mask 2284 * bitmap. 2285 * 2286 * Return: None. 2287 */ 2288 static void mpi3mr_unmask_events(struct mpi3mr_softc *sc, U16 event) 2289 { 2290 U32 desired_event; 2291 2292 if (event >= 128) 2293 return; 2294 2295 desired_event = (1 << (event % 32)); 2296 2297 if (event < 32) 2298 sc->event_masks[0] &= ~desired_event; 2299 else if (event < 64) 2300 sc->event_masks[1] &= ~desired_event; 2301 else if (event < 96) 2302 sc->event_masks[2] &= ~desired_event; 2303 else if (event < 128) 2304 sc->event_masks[3] &= ~desired_event; 2305 } 2306 2307 static void mpi3mr_set_events_mask(struct mpi3mr_softc *sc) 2308 { 2309 int i; 2310 for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 2311 sc->event_masks[i] = -1; 2312 2313 mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_ADDED); 2314 mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_INFO_CHANGED); 2315 mpi3mr_unmask_events(sc, MPI3_EVENT_DEVICE_STATUS_CHANGE); 2316 2317 mpi3mr_unmask_events(sc, MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE); 2318 2319 mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST); 2320 mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_DISCOVERY); 2321 mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR); 2322 mpi3mr_unmask_events(sc, MPI3_EVENT_SAS_BROADCAST_PRIMITIVE); 2323 2324 mpi3mr_unmask_events(sc, MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST); 2325 mpi3mr_unmask_events(sc, MPI3_EVENT_PCIE_ENUMERATION); 2326 2327 mpi3mr_unmask_events(sc, MPI3_EVENT_PREPARE_FOR_RESET); 2328 mpi3mr_unmask_events(sc, MPI3_EVENT_CABLE_MGMT); 2329 mpi3mr_unmask_events(sc, MPI3_EVENT_ENERGY_PACK_CHANGE); 2330 } 2331 2332 /** 2333 * mpi3mr_issue_event_notification - Send event notification 2334 * @sc: Adapter instance reference 2335 * 2336 * Issue event notification MPI request through admin queue and 2337 * wait for the completion of it or time out. 2338 * 2339 * Return: 0 on success, non-zero on failures. 2340 */ 2341 int mpi3mr_issue_event_notification(struct mpi3mr_softc *sc) 2342 { 2343 Mpi3EventNotificationRequest_t evtnotify_req; 2344 int retval = 0; 2345 U8 i; 2346 2347 memset(&evtnotify_req, 0, sizeof(evtnotify_req)); 2348 mtx_lock(&sc->init_cmds.completion.lock); 2349 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 2350 retval = -1; 2351 printf(IOCNAME "Issue EvtNotify: Init command is in use\n", 2352 sc->name); 2353 mtx_unlock(&sc->init_cmds.completion.lock); 2354 goto out; 2355 } 2356 sc->init_cmds.state = MPI3MR_CMD_PENDING; 2357 sc->init_cmds.is_waiting = 1; 2358 sc->init_cmds.callback = NULL; 2359 evtnotify_req.HostTag = (MPI3MR_HOSTTAG_INITCMDS); 2360 evtnotify_req.Function = MPI3_FUNCTION_EVENT_NOTIFICATION; 2361 for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 2362 evtnotify_req.EventMasks[i] = 2363 (sc->event_masks[i]); 2364 init_completion(&sc->init_cmds.completion); 2365 retval = mpi3mr_submit_admin_cmd(sc, &evtnotify_req, 2366 sizeof(evtnotify_req)); 2367 if (retval) { 2368 printf(IOCNAME "Issue EvtNotify: Admin Post failed\n", 2369 sc->name); 2370 goto out_unlock; 2371 } 2372 2373 poll_for_command_completion(sc, 2374 &sc->init_cmds, 2375 (MPI3MR_INTADMCMD_TIMEOUT)); 2376 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 2377 printf(IOCNAME "Issue EvtNotify: command timed out\n", 2378 sc->name); 2379 mpi3mr_check_rh_fault_ioc(sc, 2380 MPI3MR_RESET_FROM_EVTNOTIFY_TIMEOUT); 2381 retval = -1; 2382 goto out_unlock; 2383 } 2384 2385 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 2386 != MPI3_IOCSTATUS_SUCCESS ) { 2387 printf(IOCNAME "Issue EvtNotify: Failed IOCStatus(0x%04x) " 2388 " Loginfo(0x%08x) \n" , sc->name, 2389 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 2390 sc->init_cmds.ioc_loginfo); 2391 retval = -1; 2392 goto out_unlock; 2393 } 2394 2395 out_unlock: 2396 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 2397 mtx_unlock(&sc->init_cmds.completion.lock); 2398 2399 out: 2400 return retval; 2401 } 2402 2403 int 2404 mpi3mr_register_events(struct mpi3mr_softc *sc) 2405 { 2406 int error; 2407 2408 mpi3mr_set_events_mask(sc); 2409 2410 error = mpi3mr_issue_event_notification(sc); 2411 2412 if (error) { 2413 printf(IOCNAME "Failed to issue event notification %d\n", 2414 sc->name, error); 2415 } 2416 2417 return error; 2418 } 2419 2420 /** 2421 * mpi3mr_process_event_ack - Process event acknowledgment 2422 * @sc: Adapter instance reference 2423 * @event: MPI3 event ID 2424 * @event_ctx: Event context 2425 * 2426 * Send event acknowledgement through admin queue and wait for 2427 * it to complete. 2428 * 2429 * Return: 0 on success, non-zero on failures. 2430 */ 2431 int mpi3mr_process_event_ack(struct mpi3mr_softc *sc, U8 event, 2432 U32 event_ctx) 2433 { 2434 Mpi3EventAckRequest_t evtack_req; 2435 int retval = 0; 2436 2437 memset(&evtack_req, 0, sizeof(evtack_req)); 2438 mtx_lock(&sc->init_cmds.completion.lock); 2439 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 2440 retval = -1; 2441 printf(IOCNAME "Issue EvtAck: Init command is in use\n", 2442 sc->name); 2443 mtx_unlock(&sc->init_cmds.completion.lock); 2444 goto out; 2445 } 2446 sc->init_cmds.state = MPI3MR_CMD_PENDING; 2447 sc->init_cmds.is_waiting = 1; 2448 sc->init_cmds.callback = NULL; 2449 evtack_req.HostTag = htole16(MPI3MR_HOSTTAG_INITCMDS); 2450 evtack_req.Function = MPI3_FUNCTION_EVENT_ACK; 2451 evtack_req.Event = event; 2452 evtack_req.EventContext = htole32(event_ctx); 2453 2454 init_completion(&sc->init_cmds.completion); 2455 retval = mpi3mr_submit_admin_cmd(sc, &evtack_req, 2456 sizeof(evtack_req)); 2457 if (retval) { 2458 printf(IOCNAME "Issue EvtAck: Admin Post failed\n", 2459 sc->name); 2460 goto out_unlock; 2461 } 2462 2463 wait_for_completion_timeout(&sc->init_cmds.completion, 2464 (MPI3MR_INTADMCMD_TIMEOUT)); 2465 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 2466 printf(IOCNAME "Issue EvtAck: command timed out\n", 2467 sc->name); 2468 retval = -1; 2469 goto out_unlock; 2470 } 2471 2472 if ((sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK) 2473 != MPI3_IOCSTATUS_SUCCESS ) { 2474 printf(IOCNAME "Issue EvtAck: Failed IOCStatus(0x%04x) " 2475 " Loginfo(0x%08x) \n" , sc->name, 2476 (sc->init_cmds.ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 2477 sc->init_cmds.ioc_loginfo); 2478 retval = -1; 2479 goto out_unlock; 2480 } 2481 2482 out_unlock: 2483 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 2484 mtx_unlock(&sc->init_cmds.completion.lock); 2485 2486 out: 2487 return retval; 2488 } 2489 2490 2491 static int mpi3mr_alloc_chain_bufs(struct mpi3mr_softc *sc) 2492 { 2493 int retval = 0; 2494 U32 sz, i; 2495 U16 num_chains; 2496 2497 num_chains = sc->max_host_ios; 2498 2499 sc->chain_buf_count = num_chains; 2500 sz = sizeof(struct mpi3mr_chain) * num_chains; 2501 2502 sc->chain_sgl_list = malloc(sz, M_MPI3MR, M_NOWAIT | M_ZERO); 2503 2504 if (!sc->chain_sgl_list) { 2505 printf(IOCNAME "Cannot allocate memory for chain SGL list\n", 2506 sc->name); 2507 retval = -1; 2508 goto out_failed; 2509 } 2510 2511 sz = MPI3MR_CHAINSGE_SIZE; 2512 2513 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 2514 4096, 0, /* algnmnt, boundary */ 2515 sc->dma_loaddr, /* lowaddr */ 2516 BUS_SPACE_MAXADDR, /* highaddr */ 2517 NULL, NULL, /* filter, filterarg */ 2518 sz, /* maxsize */ 2519 1, /* nsegments */ 2520 sz, /* maxsegsize */ 2521 0, /* flags */ 2522 NULL, NULL, /* lockfunc, lockarg */ 2523 &sc->chain_sgl_list_tag)) { 2524 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate Chain buffer DMA tag\n"); 2525 return (ENOMEM); 2526 } 2527 2528 for (i = 0; i < num_chains; i++) { 2529 if (bus_dmamem_alloc(sc->chain_sgl_list_tag, (void **)&sc->chain_sgl_list[i].buf, 2530 BUS_DMA_NOWAIT, &sc->chain_sgl_list[i].buf_dmamap)) { 2531 mpi3mr_dprint(sc, MPI3MR_ERROR, "Func: %s line: %d DMA mem alloc failed\n", 2532 __func__, __LINE__); 2533 return (ENOMEM); 2534 } 2535 2536 bzero(sc->chain_sgl_list[i].buf, sz); 2537 bus_dmamap_load(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap, sc->chain_sgl_list[i].buf, sz, 2538 mpi3mr_memaddr_cb, &sc->chain_sgl_list[i].buf_phys, BUS_DMA_NOWAIT); 2539 mpi3mr_dprint(sc, MPI3MR_XINFO, "Func: %s line: %d phys addr= %#016jx size= %d\n", 2540 __func__, __LINE__, (uintmax_t)sc->chain_sgl_list[i].buf_phys, sz); 2541 } 2542 2543 sc->chain_bitmap_sz = MPI3MR_DIV_ROUND_UP(num_chains, 8); 2544 2545 sc->chain_bitmap = malloc(sc->chain_bitmap_sz, M_MPI3MR, M_NOWAIT | M_ZERO); 2546 if (!sc->chain_bitmap) { 2547 mpi3mr_dprint(sc, MPI3MR_INFO, "Cannot alloc memory for chain bitmap\n"); 2548 retval = -1; 2549 goto out_failed; 2550 } 2551 return retval; 2552 2553 out_failed: 2554 for (i = 0; i < num_chains; i++) { 2555 if (sc->chain_sgl_list[i].buf_phys != 0) 2556 bus_dmamap_unload(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap); 2557 if (sc->chain_sgl_list[i].buf != NULL) 2558 bus_dmamem_free(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf, sc->chain_sgl_list[i].buf_dmamap); 2559 } 2560 if (sc->chain_sgl_list_tag != NULL) 2561 bus_dma_tag_destroy(sc->chain_sgl_list_tag); 2562 return retval; 2563 } 2564 2565 static int mpi3mr_pel_alloc(struct mpi3mr_softc *sc) 2566 { 2567 int retval = 0; 2568 2569 if (!sc->pel_cmds.reply) { 2570 sc->pel_cmds.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO); 2571 if (!sc->pel_cmds.reply) { 2572 printf(IOCNAME "Cannot allocate memory for pel_cmds.reply\n", 2573 sc->name); 2574 goto out_failed; 2575 } 2576 } 2577 2578 if (!sc->pel_abort_cmd.reply) { 2579 sc->pel_abort_cmd.reply = malloc(sc->reply_sz, M_MPI3MR, M_NOWAIT | M_ZERO); 2580 if (!sc->pel_abort_cmd.reply) { 2581 printf(IOCNAME "Cannot allocate memory for pel_abort_cmd.reply\n", 2582 sc->name); 2583 goto out_failed; 2584 } 2585 } 2586 2587 if (!sc->pel_seq_number) { 2588 sc->pel_seq_number_sz = sizeof(Mpi3PELSeq_t); 2589 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 2590 4, 0, /* alignment, boundary */ 2591 sc->dma_loaddr, /* lowaddr */ 2592 BUS_SPACE_MAXADDR, /* highaddr */ 2593 NULL, NULL, /* filter, filterarg */ 2594 sc->pel_seq_number_sz, /* maxsize */ 2595 1, /* nsegments */ 2596 sc->pel_seq_number_sz, /* maxsegsize */ 2597 0, /* flags */ 2598 NULL, NULL, /* lockfunc, lockarg */ 2599 &sc->pel_seq_num_dmatag)) { 2600 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot create PEL seq number dma memory tag\n"); 2601 retval = -ENOMEM; 2602 goto out_failed; 2603 } 2604 2605 if (bus_dmamem_alloc(sc->pel_seq_num_dmatag, (void **)&sc->pel_seq_number, 2606 BUS_DMA_NOWAIT, &sc->pel_seq_num_dmamap)) { 2607 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate PEL seq number kernel buffer dma memory\n"); 2608 retval = -ENOMEM; 2609 goto out_failed; 2610 } 2611 2612 bzero(sc->pel_seq_number, sc->pel_seq_number_sz); 2613 2614 bus_dmamap_load(sc->pel_seq_num_dmatag, sc->pel_seq_num_dmamap, sc->pel_seq_number, 2615 sc->pel_seq_number_sz, mpi3mr_memaddr_cb, &sc->pel_seq_number_dma, BUS_DMA_NOWAIT); 2616 2617 if (!sc->pel_seq_number) { 2618 printf(IOCNAME "%s:%d Cannot load PEL seq number dma memory for size: %d\n", sc->name, 2619 __func__, __LINE__, sc->pel_seq_number_sz); 2620 retval = -ENOMEM; 2621 goto out_failed; 2622 } 2623 } 2624 2625 out_failed: 2626 return retval; 2627 } 2628 2629 /** 2630 * mpi3mr_validate_fw_update - validate IOCFacts post adapter reset 2631 * @sc: Adapter instance reference 2632 * 2633 * Return zero if the new IOCFacts is compatible with previous values 2634 * else return appropriate error 2635 */ 2636 static int 2637 mpi3mr_validate_fw_update(struct mpi3mr_softc *sc) 2638 { 2639 U16 dev_handle_bitmap_sz; 2640 U8 *removepend_bitmap; 2641 2642 if (sc->facts.reply_sz > sc->reply_sz) { 2643 mpi3mr_dprint(sc, MPI3MR_ERROR, 2644 "Cannot increase reply size from %d to %d\n", 2645 sc->reply_sz, sc->reply_sz); 2646 return -EPERM; 2647 } 2648 2649 if (sc->num_io_throttle_group != sc->facts.max_io_throttle_group) { 2650 mpi3mr_dprint(sc, MPI3MR_ERROR, 2651 "max io throttle group doesn't match old(%d), new(%d)\n", 2652 sc->num_io_throttle_group, 2653 sc->facts.max_io_throttle_group); 2654 return -EPERM; 2655 } 2656 2657 if (sc->facts.max_op_reply_q < sc->num_queues) { 2658 mpi3mr_dprint(sc, MPI3MR_ERROR, 2659 "Cannot reduce number of operational reply queues from %d to %d\n", 2660 sc->num_queues, 2661 sc->facts.max_op_reply_q); 2662 return -EPERM; 2663 } 2664 2665 if (sc->facts.max_op_req_q < sc->num_queues) { 2666 mpi3mr_dprint(sc, MPI3MR_ERROR, 2667 "Cannot reduce number of operational request queues from %d to %d\n", 2668 sc->num_queues, sc->facts.max_op_req_q); 2669 return -EPERM; 2670 } 2671 2672 dev_handle_bitmap_sz = MPI3MR_DIV_ROUND_UP(sc->facts.max_devhandle, 8); 2673 2674 if (dev_handle_bitmap_sz > sc->dev_handle_bitmap_sz) { 2675 removepend_bitmap = realloc(sc->removepend_bitmap, 2676 dev_handle_bitmap_sz, M_MPI3MR, M_NOWAIT); 2677 2678 if (!removepend_bitmap) { 2679 mpi3mr_dprint(sc, MPI3MR_ERROR, 2680 "failed to increase removepend_bitmap sz from: %d to %d\n", 2681 sc->dev_handle_bitmap_sz, dev_handle_bitmap_sz); 2682 return -ENOMEM; 2683 } 2684 2685 memset(removepend_bitmap + sc->dev_handle_bitmap_sz, 0, 2686 dev_handle_bitmap_sz - sc->dev_handle_bitmap_sz); 2687 sc->removepend_bitmap = removepend_bitmap; 2688 mpi3mr_dprint(sc, MPI3MR_INFO, 2689 "increased dev_handle_bitmap_sz from %d to %d\n", 2690 sc->dev_handle_bitmap_sz, dev_handle_bitmap_sz); 2691 sc->dev_handle_bitmap_sz = dev_handle_bitmap_sz; 2692 } 2693 2694 return 0; 2695 } 2696 2697 /* 2698 * mpi3mr_initialize_ioc - Controller initialization 2699 * @dev: pointer to device struct 2700 * 2701 * This function allocates the controller wide resources and brings 2702 * the controller to operational state 2703 * 2704 * Return: 0 on success and proper error codes on failure 2705 */ 2706 int mpi3mr_initialize_ioc(struct mpi3mr_softc *sc, U8 init_type) 2707 { 2708 int retval = 0; 2709 enum mpi3mr_iocstate ioc_state; 2710 U64 ioc_info; 2711 U32 ioc_status, ioc_control, i, timeout; 2712 Mpi3IOCFactsData_t facts_data; 2713 char str[32]; 2714 U32 size; 2715 2716 sc->cpu_count = mp_ncpus; 2717 2718 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 2719 ioc_control = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 2720 ioc_info = mpi3mr_regread64(sc, MPI3_SYSIF_IOC_INFO_LOW_OFFSET); 2721 2722 mpi3mr_dprint(sc, MPI3MR_INFO, "SOD ioc_status: 0x%x ioc_control: 0x%x " 2723 "ioc_info: 0x%lx\n", ioc_status, ioc_control, ioc_info); 2724 2725 /*The timeout value is in 2sec unit, changing it to seconds*/ 2726 sc->ready_timeout = 2727 ((ioc_info & MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_MASK) >> 2728 MPI3_SYSIF_IOC_INFO_LOW_TIMEOUT_SHIFT) * 2; 2729 2730 ioc_state = mpi3mr_get_iocstate(sc); 2731 2732 mpi3mr_dprint(sc, MPI3MR_INFO, "IOC state: %s IOC ready timeout: %d\n", 2733 mpi3mr_iocstate_name(ioc_state), sc->ready_timeout); 2734 2735 if (ioc_state == MRIOC_STATE_BECOMING_READY || 2736 ioc_state == MRIOC_STATE_RESET_REQUESTED) { 2737 timeout = sc->ready_timeout * 10; 2738 do { 2739 DELAY(1000 * 100); 2740 } while (--timeout); 2741 2742 ioc_state = mpi3mr_get_iocstate(sc); 2743 mpi3mr_dprint(sc, MPI3MR_INFO, 2744 "IOC in %s state after waiting for reset time\n", 2745 mpi3mr_iocstate_name(ioc_state)); 2746 } 2747 2748 if (ioc_state == MRIOC_STATE_READY) { 2749 retval = mpi3mr_mur_ioc(sc, MPI3MR_RESET_FROM_BRINGUP); 2750 if (retval) { 2751 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to MU reset IOC, error 0x%x\n", 2752 retval); 2753 } 2754 ioc_state = mpi3mr_get_iocstate(sc); 2755 } 2756 2757 if (ioc_state != MRIOC_STATE_RESET) { 2758 mpi3mr_print_fault_info(sc); 2759 mpi3mr_dprint(sc, MPI3MR_ERROR, "issuing soft reset to bring to reset state\n"); 2760 retval = mpi3mr_issue_reset(sc, 2761 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, 2762 MPI3MR_RESET_FROM_BRINGUP); 2763 if (retval) { 2764 mpi3mr_dprint(sc, MPI3MR_ERROR, 2765 "%s :Failed to soft reset IOC, error 0x%d\n", 2766 __func__, retval); 2767 goto out_failed; 2768 } 2769 } 2770 2771 ioc_state = mpi3mr_get_iocstate(sc); 2772 2773 if (ioc_state != MRIOC_STATE_RESET) { 2774 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot bring IOC to reset state\n"); 2775 goto out_failed; 2776 } 2777 2778 retval = mpi3mr_setup_admin_qpair(sc); 2779 if (retval) { 2780 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to setup Admin queues, error 0x%x\n", 2781 retval); 2782 goto out_failed; 2783 } 2784 2785 retval = mpi3mr_bring_ioc_ready(sc); 2786 if (retval) { 2787 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to bring IOC ready, error 0x%x\n", 2788 retval); 2789 goto out_failed; 2790 } 2791 2792 if (init_type == MPI3MR_INIT_TYPE_INIT) { 2793 retval = mpi3mr_alloc_interrupts(sc, 1); 2794 if (retval) { 2795 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate interrupts, error 0x%x\n", 2796 retval); 2797 goto out_failed; 2798 } 2799 2800 retval = mpi3mr_setup_irqs(sc); 2801 if (retval) { 2802 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to setup ISR, error 0x%x\n", 2803 retval); 2804 goto out_failed; 2805 } 2806 } 2807 2808 mpi3mr_enable_interrupts(sc); 2809 2810 if (init_type == MPI3MR_INIT_TYPE_INIT) { 2811 mtx_init(&sc->mpi3mr_mtx, "SIM lock", NULL, MTX_DEF); 2812 mtx_init(&sc->io_lock, "IO lock", NULL, MTX_DEF); 2813 mtx_init(&sc->admin_req_lock, "Admin Request Queue lock", NULL, MTX_SPIN); 2814 mtx_init(&sc->reply_free_q_lock, "Reply free Queue lock", NULL, MTX_SPIN); 2815 mtx_init(&sc->sense_buf_q_lock, "Sense buffer Queue lock", NULL, MTX_SPIN); 2816 mtx_init(&sc->chain_buf_lock, "Chain buffer lock", NULL, MTX_SPIN); 2817 mtx_init(&sc->cmd_pool_lock, "Command pool lock", NULL, MTX_DEF); 2818 mtx_init(&sc->fwevt_lock, "Firmware Event lock", NULL, MTX_DEF); 2819 mtx_init(&sc->target_lock, "Target lock", NULL, MTX_SPIN); 2820 mtx_init(&sc->reset_mutex, "Reset lock", NULL, MTX_DEF); 2821 2822 mtx_init(&sc->init_cmds.completion.lock, "Init commands lock", NULL, MTX_DEF); 2823 sc->init_cmds.reply = NULL; 2824 sc->init_cmds.state = MPI3MR_CMD_NOTUSED; 2825 sc->init_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE; 2826 sc->init_cmds.host_tag = MPI3MR_HOSTTAG_INITCMDS; 2827 2828 mtx_init(&sc->ioctl_cmds.completion.lock, "IOCTL commands lock", NULL, MTX_DEF); 2829 sc->ioctl_cmds.reply = NULL; 2830 sc->ioctl_cmds.state = MPI3MR_CMD_NOTUSED; 2831 sc->ioctl_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE; 2832 sc->ioctl_cmds.host_tag = MPI3MR_HOSTTAG_IOCTLCMDS; 2833 2834 mtx_init(&sc->pel_abort_cmd.completion.lock, "PEL Abort command lock", NULL, MTX_DEF); 2835 sc->pel_abort_cmd.reply = NULL; 2836 sc->pel_abort_cmd.state = MPI3MR_CMD_NOTUSED; 2837 sc->pel_abort_cmd.dev_handle = MPI3MR_INVALID_DEV_HANDLE; 2838 sc->pel_abort_cmd.host_tag = MPI3MR_HOSTTAG_PELABORT; 2839 2840 mtx_init(&sc->host_tm_cmds.completion.lock, "TM commands lock", NULL, MTX_DEF); 2841 sc->host_tm_cmds.reply = NULL; 2842 sc->host_tm_cmds.state = MPI3MR_CMD_NOTUSED; 2843 sc->host_tm_cmds.dev_handle = MPI3MR_INVALID_DEV_HANDLE; 2844 sc->host_tm_cmds.host_tag = MPI3MR_HOSTTAG_TMS; 2845 2846 TAILQ_INIT(&sc->cmd_list_head); 2847 TAILQ_INIT(&sc->event_list); 2848 TAILQ_INIT(&sc->delayed_rmhs_list); 2849 TAILQ_INIT(&sc->delayed_evtack_cmds_list); 2850 2851 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { 2852 snprintf(str, 32, "Dev REMHS commands lock[%d]", i); 2853 mtx_init(&sc->dev_rmhs_cmds[i].completion.lock, str, NULL, MTX_DEF); 2854 sc->dev_rmhs_cmds[i].reply = NULL; 2855 sc->dev_rmhs_cmds[i].state = MPI3MR_CMD_NOTUSED; 2856 sc->dev_rmhs_cmds[i].dev_handle = MPI3MR_INVALID_DEV_HANDLE; 2857 sc->dev_rmhs_cmds[i].host_tag = MPI3MR_HOSTTAG_DEVRMCMD_MIN 2858 + i; 2859 } 2860 } 2861 2862 retval = mpi3mr_issue_iocfacts(sc, &facts_data); 2863 if (retval) { 2864 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to Issue IOC Facts, retval: 0x%x\n", 2865 retval); 2866 goto out_failed; 2867 } 2868 2869 retval = mpi3mr_process_factsdata(sc, &facts_data); 2870 if (retval) { 2871 mpi3mr_dprint(sc, MPI3MR_ERROR, "IOC Facts data processing failedi, retval: 0x%x\n", 2872 retval); 2873 goto out_failed; 2874 } 2875 2876 sc->num_io_throttle_group = sc->facts.max_io_throttle_group; 2877 mpi3mr_atomic_set(&sc->pend_large_data_sz, 0); 2878 2879 if (init_type == MPI3MR_INIT_TYPE_RESET) { 2880 retval = mpi3mr_validate_fw_update(sc); 2881 if (retval) 2882 goto out_failed; 2883 } else { 2884 sc->reply_sz = sc->facts.reply_sz; 2885 } 2886 2887 mpi3mr_display_ioc_info(sc); 2888 2889 retval = mpi3mr_reply_alloc(sc); 2890 if (retval) { 2891 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocated reply and sense buffers, retval: 0x%x\n", 2892 retval); 2893 goto out_failed; 2894 } 2895 2896 if (init_type == MPI3MR_INIT_TYPE_INIT) { 2897 retval = mpi3mr_alloc_chain_bufs(sc); 2898 if (retval) { 2899 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocated chain buffers, retval: 0x%x\n", 2900 retval); 2901 goto out_failed; 2902 } 2903 } 2904 2905 retval = mpi3mr_issue_iocinit(sc); 2906 if (retval) { 2907 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to Issue IOC Init, retval: 0x%x\n", 2908 retval); 2909 goto out_failed; 2910 } 2911 2912 mpi3mr_print_fw_pkg_ver(sc); 2913 2914 sc->reply_free_q_host_index = sc->num_reply_bufs; 2915 mpi3mr_regwrite(sc, MPI3_SYSIF_REPLY_FREE_HOST_INDEX_OFFSET, 2916 sc->reply_free_q_host_index); 2917 2918 sc->sense_buf_q_host_index = sc->num_sense_bufs; 2919 2920 mpi3mr_regwrite(sc, MPI3_SYSIF_SENSE_BUF_FREE_HOST_INDEX_OFFSET, 2921 sc->sense_buf_q_host_index); 2922 2923 if (init_type == MPI3MR_INIT_TYPE_INIT) { 2924 retval = mpi3mr_alloc_interrupts(sc, 0); 2925 if (retval) { 2926 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate interrupts, retval: 0x%x\n", 2927 retval); 2928 goto out_failed; 2929 } 2930 2931 retval = mpi3mr_setup_irqs(sc); 2932 if (retval) { 2933 printf(IOCNAME "Failed to setup ISR, error: 0x%x\n", 2934 sc->name, retval); 2935 goto out_failed; 2936 } 2937 2938 mpi3mr_enable_interrupts(sc); 2939 2940 } else 2941 mpi3mr_enable_interrupts(sc); 2942 2943 retval = mpi3mr_create_op_queues(sc); 2944 2945 if (retval) { 2946 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to create operational queues, error: %d\n", 2947 retval); 2948 goto out_failed; 2949 } 2950 2951 if (!sc->throttle_groups && sc->num_io_throttle_group) { 2952 mpi3mr_dprint(sc, MPI3MR_ERROR, "allocating memory for throttle groups\n"); 2953 size = sizeof(struct mpi3mr_throttle_group_info); 2954 sc->throttle_groups = (struct mpi3mr_throttle_group_info *) 2955 malloc(sc->num_io_throttle_group * 2956 size, M_MPI3MR, M_NOWAIT | M_ZERO); 2957 if (!sc->throttle_groups) 2958 goto out_failed; 2959 } 2960 2961 if (init_type == MPI3MR_INIT_TYPE_RESET) { 2962 mpi3mr_dprint(sc, MPI3MR_INFO, "Re-register events\n"); 2963 retval = mpi3mr_register_events(sc); 2964 if (retval) { 2965 mpi3mr_dprint(sc, MPI3MR_INFO, "Failed to re-register events, retval: 0x%x\n", 2966 retval); 2967 goto out_failed; 2968 } 2969 2970 mpi3mr_dprint(sc, MPI3MR_INFO, "Issuing Port Enable\n"); 2971 retval = mpi3mr_issue_port_enable(sc, 0); 2972 if (retval) { 2973 mpi3mr_dprint(sc, MPI3MR_INFO, "Failed to issue port enable, retval: 0x%x\n", 2974 retval); 2975 goto out_failed; 2976 } 2977 } 2978 retval = mpi3mr_pel_alloc(sc); 2979 if (retval) { 2980 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate memory for PEL, retval: 0x%x\n", 2981 retval); 2982 goto out_failed; 2983 } 2984 2985 return retval; 2986 2987 out_failed: 2988 retval = -1; 2989 return retval; 2990 } 2991 2992 static void mpi3mr_port_enable_complete(struct mpi3mr_softc *sc, 2993 struct mpi3mr_drvr_cmd *drvrcmd) 2994 { 2995 drvrcmd->state = MPI3MR_CMD_NOTUSED; 2996 drvrcmd->callback = NULL; 2997 printf(IOCNAME "Completing Port Enable Request\n", sc->name); 2998 sc->mpi3mr_flags |= MPI3MR_FLAGS_PORT_ENABLE_DONE; 2999 mpi3mr_startup_decrement(sc->cam_sc); 3000 } 3001 3002 int mpi3mr_issue_port_enable(struct mpi3mr_softc *sc, U8 async) 3003 { 3004 Mpi3PortEnableRequest_t pe_req; 3005 int retval = 0; 3006 3007 memset(&pe_req, 0, sizeof(pe_req)); 3008 mtx_lock(&sc->init_cmds.completion.lock); 3009 if (sc->init_cmds.state & MPI3MR_CMD_PENDING) { 3010 retval = -1; 3011 printf(IOCNAME "Issue PortEnable: Init command is in use\n", sc->name); 3012 mtx_unlock(&sc->init_cmds.completion.lock); 3013 goto out; 3014 } 3015 3016 sc->init_cmds.state = MPI3MR_CMD_PENDING; 3017 3018 if (async) { 3019 sc->init_cmds.is_waiting = 0; 3020 sc->init_cmds.callback = mpi3mr_port_enable_complete; 3021 } else { 3022 sc->init_cmds.is_waiting = 1; 3023 sc->init_cmds.callback = NULL; 3024 init_completion(&sc->init_cmds.completion); 3025 } 3026 pe_req.HostTag = MPI3MR_HOSTTAG_INITCMDS; 3027 pe_req.Function = MPI3_FUNCTION_PORT_ENABLE; 3028 3029 printf(IOCNAME "Sending Port Enable Request\n", sc->name); 3030 retval = mpi3mr_submit_admin_cmd(sc, &pe_req, sizeof(pe_req)); 3031 if (retval) { 3032 printf(IOCNAME "Issue PortEnable: Admin Post failed\n", 3033 sc->name); 3034 goto out_unlock; 3035 } 3036 3037 if (!async) { 3038 wait_for_completion_timeout(&sc->init_cmds.completion, 3039 MPI3MR_PORTENABLE_TIMEOUT); 3040 if (!(sc->init_cmds.state & MPI3MR_CMD_COMPLETE)) { 3041 printf(IOCNAME "Issue PortEnable: command timed out\n", 3042 sc->name); 3043 retval = -1; 3044 mpi3mr_check_rh_fault_ioc(sc, MPI3MR_RESET_FROM_PE_TIMEOUT); 3045 goto out_unlock; 3046 } 3047 mpi3mr_port_enable_complete(sc, &sc->init_cmds); 3048 } 3049 out_unlock: 3050 mtx_unlock(&sc->init_cmds.completion.lock); 3051 3052 out: 3053 return retval; 3054 } 3055 3056 void 3057 mpi3mr_watchdog_thread(void *arg) 3058 { 3059 struct mpi3mr_softc *sc; 3060 enum mpi3mr_iocstate ioc_state; 3061 U32 fault, host_diagnostic, ioc_status; 3062 3063 sc = (struct mpi3mr_softc *)arg; 3064 3065 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s\n", __func__); 3066 3067 sc->watchdog_thread_active = 1; 3068 mtx_lock(&sc->reset_mutex); 3069 for (;;) { 3070 if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN || 3071 (sc->unrecoverable == 1)) { 3072 mpi3mr_dprint(sc, MPI3MR_INFO, 3073 "Exit due to %s from %s\n", 3074 sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN ? "Shutdown" : 3075 "Hardware critical error", __func__); 3076 break; 3077 } 3078 mtx_unlock(&sc->reset_mutex); 3079 3080 if ((sc->prepare_for_reset) && 3081 ((sc->prepare_for_reset_timeout_counter++) >= 3082 MPI3MR_PREPARE_FOR_RESET_TIMEOUT)) { 3083 mpi3mr_soft_reset_handler(sc, 3084 MPI3MR_RESET_FROM_CIACTVRST_TIMER, 1); 3085 goto sleep; 3086 } 3087 3088 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 3089 3090 if (ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) { 3091 mpi3mr_soft_reset_handler(sc, MPI3MR_RESET_FROM_FIRMWARE, 0); 3092 goto sleep; 3093 } 3094 3095 ioc_state = mpi3mr_get_iocstate(sc); 3096 if (ioc_state == MRIOC_STATE_FAULT) { 3097 fault = mpi3mr_regread(sc, MPI3_SYSIF_FAULT_OFFSET) & 3098 MPI3_SYSIF_FAULT_CODE_MASK; 3099 3100 host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET); 3101 if (host_diagnostic & MPI3_SYSIF_HOST_DIAG_SAVE_IN_PROGRESS) { 3102 if (!sc->diagsave_timeout) { 3103 mpi3mr_print_fault_info(sc); 3104 mpi3mr_dprint(sc, MPI3MR_INFO, 3105 "diag save in progress\n"); 3106 } 3107 if ((sc->diagsave_timeout++) <= MPI3_SYSIF_DIAG_SAVE_TIMEOUT) 3108 goto sleep; 3109 } 3110 mpi3mr_print_fault_info(sc); 3111 sc->diagsave_timeout = 0; 3112 3113 if ((fault == MPI3_SYSIF_FAULT_CODE_POWER_CYCLE_REQUIRED) || 3114 (fault == MPI3_SYSIF_FAULT_CODE_COMPLETE_RESET_NEEDED)) { 3115 mpi3mr_dprint(sc, MPI3MR_INFO, 3116 "Controller requires system power cycle or complete reset is needed," 3117 "fault code: 0x%x. marking controller as unrecoverable\n", fault); 3118 sc->unrecoverable = 1; 3119 break; 3120 } 3121 if ((fault == MPI3_SYSIF_FAULT_CODE_DIAG_FAULT_RESET) 3122 || (fault == MPI3_SYSIF_FAULT_CODE_SOFT_RESET_IN_PROGRESS) 3123 || (sc->reset_in_progress)) 3124 break; 3125 if (fault == MPI3_SYSIF_FAULT_CODE_CI_ACTIVATION_RESET) 3126 mpi3mr_soft_reset_handler(sc, 3127 MPI3MR_RESET_FROM_CIACTIV_FAULT, 0); 3128 else 3129 mpi3mr_soft_reset_handler(sc, 3130 MPI3MR_RESET_FROM_FAULT_WATCH, 0); 3131 3132 } 3133 3134 if (sc->reset.type == MPI3MR_TRIGGER_SOFT_RESET) { 3135 mpi3mr_print_fault_info(sc); 3136 mpi3mr_soft_reset_handler(sc, sc->reset.reason, 1); 3137 } 3138 sleep: 3139 mtx_lock(&sc->reset_mutex); 3140 /* 3141 * Sleep for 1 second if we're not exiting, then loop to top 3142 * to poll exit status and hardware health. 3143 */ 3144 if ((sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) == 0 && 3145 !sc->unrecoverable) { 3146 msleep(&sc->watchdog_chan, &sc->reset_mutex, PRIBIO, 3147 "mpi3mr_watchdog", 1 * hz); 3148 } 3149 } 3150 mtx_unlock(&sc->reset_mutex); 3151 sc->watchdog_thread_active = 0; 3152 mpi3mr_kproc_exit(0); 3153 } 3154 3155 static void mpi3mr_display_event_data(struct mpi3mr_softc *sc, 3156 Mpi3EventNotificationReply_t *event_rep) 3157 { 3158 char *desc = NULL; 3159 U16 event; 3160 3161 event = event_rep->Event; 3162 3163 switch (event) { 3164 case MPI3_EVENT_LOG_DATA: 3165 desc = "Log Data"; 3166 break; 3167 case MPI3_EVENT_CHANGE: 3168 desc = "Event Change"; 3169 break; 3170 case MPI3_EVENT_GPIO_INTERRUPT: 3171 desc = "GPIO Interrupt"; 3172 break; 3173 case MPI3_EVENT_CABLE_MGMT: 3174 desc = "Cable Management"; 3175 break; 3176 case MPI3_EVENT_ENERGY_PACK_CHANGE: 3177 desc = "Energy Pack Change"; 3178 break; 3179 case MPI3_EVENT_DEVICE_ADDED: 3180 { 3181 Mpi3DevicePage0_t *event_data = 3182 (Mpi3DevicePage0_t *)event_rep->EventData; 3183 mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Added: Dev=0x%04x Form=0x%x Perst id: 0x%x\n", 3184 event_data->DevHandle, event_data->DeviceForm, event_data->PersistentID); 3185 return; 3186 } 3187 case MPI3_EVENT_DEVICE_INFO_CHANGED: 3188 { 3189 Mpi3DevicePage0_t *event_data = 3190 (Mpi3DevicePage0_t *)event_rep->EventData; 3191 mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Info Changed: Dev=0x%04x Form=0x%x\n", 3192 event_data->DevHandle, event_data->DeviceForm); 3193 return; 3194 } 3195 case MPI3_EVENT_DEVICE_STATUS_CHANGE: 3196 { 3197 Mpi3EventDataDeviceStatusChange_t *event_data = 3198 (Mpi3EventDataDeviceStatusChange_t *)event_rep->EventData; 3199 mpi3mr_dprint(sc, MPI3MR_EVENT, "Device Status Change: Dev=0x%04x RC=0x%x\n", 3200 event_data->DevHandle, event_data->ReasonCode); 3201 return; 3202 } 3203 case MPI3_EVENT_SAS_DISCOVERY: 3204 { 3205 Mpi3EventDataSasDiscovery_t *event_data = 3206 (Mpi3EventDataSasDiscovery_t *)event_rep->EventData; 3207 mpi3mr_dprint(sc, MPI3MR_EVENT, "SAS Discovery: (%s)", 3208 (event_data->ReasonCode == MPI3_EVENT_SAS_DISC_RC_STARTED) ? 3209 "start" : "stop"); 3210 if (event_data->DiscoveryStatus && 3211 (sc->mpi3mr_debug & MPI3MR_EVENT)) { 3212 printf("discovery_status(0x%08x)", 3213 event_data->DiscoveryStatus); 3214 3215 } 3216 3217 if (sc->mpi3mr_debug & MPI3MR_EVENT) 3218 printf("\n"); 3219 return; 3220 } 3221 case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE: 3222 desc = "SAS Broadcast Primitive"; 3223 break; 3224 case MPI3_EVENT_SAS_NOTIFY_PRIMITIVE: 3225 desc = "SAS Notify Primitive"; 3226 break; 3227 case MPI3_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 3228 desc = "SAS Init Device Status Change"; 3229 break; 3230 case MPI3_EVENT_SAS_INIT_TABLE_OVERFLOW: 3231 desc = "SAS Init Table Overflow"; 3232 break; 3233 case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 3234 desc = "SAS Topology Change List"; 3235 break; 3236 case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 3237 desc = "Enclosure Device Status Change"; 3238 break; 3239 case MPI3_EVENT_HARD_RESET_RECEIVED: 3240 desc = "Hard Reset Received"; 3241 break; 3242 case MPI3_EVENT_SAS_PHY_COUNTER: 3243 desc = "SAS PHY Counter"; 3244 break; 3245 case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR: 3246 desc = "SAS Device Discovery Error"; 3247 break; 3248 case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: 3249 desc = "PCIE Topology Change List"; 3250 break; 3251 case MPI3_EVENT_PCIE_ENUMERATION: 3252 { 3253 Mpi3EventDataPcieEnumeration_t *event_data = 3254 (Mpi3EventDataPcieEnumeration_t *)event_rep->EventData; 3255 mpi3mr_dprint(sc, MPI3MR_EVENT, "PCIE Enumeration: (%s)", 3256 (event_data->ReasonCode == 3257 MPI3_EVENT_PCIE_ENUM_RC_STARTED) ? "start" : 3258 "stop"); 3259 if (event_data->EnumerationStatus) 3260 mpi3mr_dprint(sc, MPI3MR_EVENT, "enumeration_status(0x%08x)", 3261 event_data->EnumerationStatus); 3262 if (sc->mpi3mr_debug & MPI3MR_EVENT) 3263 printf("\n"); 3264 return; 3265 } 3266 case MPI3_EVENT_PREPARE_FOR_RESET: 3267 desc = "Prepare For Reset"; 3268 break; 3269 } 3270 3271 if (!desc) 3272 return; 3273 3274 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s\n", desc); 3275 } 3276 3277 struct mpi3mr_target * 3278 mpi3mr_find_target_by_per_id(struct mpi3mr_cam_softc *cam_sc, 3279 uint16_t per_id) 3280 { 3281 struct mpi3mr_target *target = NULL; 3282 3283 mtx_lock_spin(&cam_sc->sc->target_lock); 3284 TAILQ_FOREACH(target, &cam_sc->tgt_list, tgt_next) { 3285 if (target->per_id == per_id) 3286 break; 3287 } 3288 3289 mtx_unlock_spin(&cam_sc->sc->target_lock); 3290 return target; 3291 } 3292 3293 struct mpi3mr_target * 3294 mpi3mr_find_target_by_dev_handle(struct mpi3mr_cam_softc *cam_sc, 3295 uint16_t handle) 3296 { 3297 struct mpi3mr_target *target = NULL; 3298 3299 mtx_lock_spin(&cam_sc->sc->target_lock); 3300 TAILQ_FOREACH(target, &cam_sc->tgt_list, tgt_next) { 3301 if (target->dev_handle == handle) 3302 break; 3303 3304 } 3305 mtx_unlock_spin(&cam_sc->sc->target_lock); 3306 return target; 3307 } 3308 3309 void mpi3mr_update_device(struct mpi3mr_softc *sc, 3310 struct mpi3mr_target *tgtdev, Mpi3DevicePage0_t *dev_pg0, 3311 bool is_added) 3312 { 3313 U16 flags = 0; 3314 3315 tgtdev->per_id = (dev_pg0->PersistentID); 3316 tgtdev->dev_handle = (dev_pg0->DevHandle); 3317 tgtdev->dev_type = dev_pg0->DeviceForm; 3318 tgtdev->encl_handle = (dev_pg0->EnclosureHandle); 3319 tgtdev->parent_handle = (dev_pg0->ParentDevHandle); 3320 tgtdev->slot = (dev_pg0->Slot); 3321 tgtdev->qdepth = (dev_pg0->QueueDepth); 3322 tgtdev->wwid = (dev_pg0->WWID); 3323 3324 flags = (dev_pg0->Flags); 3325 tgtdev->is_hidden = (flags & MPI3_DEVICE0_FLAGS_HIDDEN); 3326 if (is_added == true) 3327 tgtdev->io_throttle_enabled = 3328 (flags & MPI3_DEVICE0_FLAGS_IO_THROTTLING_REQUIRED) ? 1 : 0; 3329 3330 switch (dev_pg0->AccessStatus) { 3331 case MPI3_DEVICE0_ASTATUS_NO_ERRORS: 3332 case MPI3_DEVICE0_ASTATUS_PREPARE: 3333 case MPI3_DEVICE0_ASTATUS_NEEDS_INITIALIZATION: 3334 case MPI3_DEVICE0_ASTATUS_DEVICE_MISSING_DELAY: 3335 break; 3336 default: 3337 tgtdev->is_hidden = 1; 3338 break; 3339 } 3340 3341 switch (tgtdev->dev_type) { 3342 case MPI3_DEVICE_DEVFORM_SAS_SATA: 3343 { 3344 Mpi3Device0SasSataFormat_t *sasinf = 3345 &dev_pg0->DeviceSpecific.SasSataFormat; 3346 U16 dev_info = (sasinf->DeviceInfo); 3347 tgtdev->dev_spec.sassata_inf.dev_info = dev_info; 3348 tgtdev->dev_spec.sassata_inf.sas_address = 3349 (sasinf->SASAddress); 3350 if ((dev_info & MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_MASK) != 3351 MPI3_SAS_DEVICE_INFO_DEVICE_TYPE_END_DEVICE) 3352 tgtdev->is_hidden = 1; 3353 else if (!(dev_info & (MPI3_SAS_DEVICE_INFO_STP_SATA_TARGET | 3354 MPI3_SAS_DEVICE_INFO_SSP_TARGET))) 3355 tgtdev->is_hidden = 1; 3356 break; 3357 } 3358 case MPI3_DEVICE_DEVFORM_PCIE: 3359 { 3360 Mpi3Device0PcieFormat_t *pcieinf = 3361 &dev_pg0->DeviceSpecific.PcieFormat; 3362 U16 dev_info = (pcieinf->DeviceInfo); 3363 3364 tgtdev->q_depth = dev_pg0->QueueDepth; 3365 tgtdev->dev_spec.pcie_inf.dev_info = dev_info; 3366 tgtdev->dev_spec.pcie_inf.capb = 3367 (pcieinf->Capabilities); 3368 tgtdev->dev_spec.pcie_inf.mdts = MPI3MR_DEFAULT_MDTS; 3369 if (dev_pg0->AccessStatus == MPI3_DEVICE0_ASTATUS_NO_ERRORS) { 3370 tgtdev->dev_spec.pcie_inf.mdts = 3371 (pcieinf->MaximumDataTransferSize); 3372 tgtdev->dev_spec.pcie_inf.pgsz = pcieinf->PageSize; 3373 tgtdev->dev_spec.pcie_inf.reset_to = 3374 pcieinf->ControllerResetTO; 3375 tgtdev->dev_spec.pcie_inf.abort_to = 3376 pcieinf->NVMeAbortTO; 3377 } 3378 if (tgtdev->dev_spec.pcie_inf.mdts > (1024 * 1024)) 3379 tgtdev->dev_spec.pcie_inf.mdts = (1024 * 1024); 3380 3381 if (((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) != 3382 MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) && 3383 ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) != 3384 MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE)) 3385 tgtdev->is_hidden = 1; 3386 3387 break; 3388 } 3389 case MPI3_DEVICE_DEVFORM_VD: 3390 { 3391 Mpi3Device0VdFormat_t *vdinf = 3392 &dev_pg0->DeviceSpecific.VdFormat; 3393 struct mpi3mr_throttle_group_info *tg = NULL; 3394 3395 tgtdev->dev_spec.vol_inf.state = vdinf->VdState; 3396 if (vdinf->VdState == MPI3_DEVICE0_VD_STATE_OFFLINE) 3397 tgtdev->is_hidden = 1; 3398 tgtdev->dev_spec.vol_inf.tg_id = vdinf->IOThrottleGroup; 3399 tgtdev->dev_spec.vol_inf.tg_high = 3400 vdinf->IOThrottleGroupHigh * 2048; 3401 tgtdev->dev_spec.vol_inf.tg_low = 3402 vdinf->IOThrottleGroupLow * 2048; 3403 if (vdinf->IOThrottleGroup < sc->num_io_throttle_group) { 3404 tg = sc->throttle_groups + vdinf->IOThrottleGroup; 3405 tg->id = vdinf->IOThrottleGroup; 3406 tg->high = tgtdev->dev_spec.vol_inf.tg_high; 3407 tg->low = tgtdev->dev_spec.vol_inf.tg_low; 3408 if (is_added == true) 3409 tg->fw_qd = tgtdev->q_depth; 3410 tg->modified_qd = tgtdev->q_depth; 3411 } 3412 tgtdev->dev_spec.vol_inf.tg = tg; 3413 tgtdev->throttle_group = tg; 3414 break; 3415 } 3416 default: 3417 goto out; 3418 } 3419 3420 out: 3421 return; 3422 } 3423 3424 int mpi3mr_create_device(struct mpi3mr_softc *sc, 3425 Mpi3DevicePage0_t *dev_pg0) 3426 { 3427 int retval = 0; 3428 struct mpi3mr_target *target = NULL; 3429 U16 per_id = 0; 3430 3431 per_id = dev_pg0->PersistentID; 3432 3433 mtx_lock_spin(&sc->target_lock); 3434 TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) { 3435 if (target->per_id == per_id) { 3436 target->state = MPI3MR_DEV_CREATED; 3437 break; 3438 } 3439 } 3440 mtx_unlock_spin(&sc->target_lock); 3441 3442 if (target) { 3443 mpi3mr_update_device(sc, target, dev_pg0, true); 3444 } else { 3445 target = malloc(sizeof(*target), M_MPI3MR, 3446 M_NOWAIT | M_ZERO); 3447 3448 if (target == NULL) { 3449 retval = -1; 3450 goto out; 3451 } 3452 3453 target->exposed_to_os = 0; 3454 mpi3mr_update_device(sc, target, dev_pg0, true); 3455 mtx_lock_spin(&sc->target_lock); 3456 TAILQ_INSERT_TAIL(&sc->cam_sc->tgt_list, target, tgt_next); 3457 target->state = MPI3MR_DEV_CREATED; 3458 mtx_unlock_spin(&sc->target_lock); 3459 } 3460 out: 3461 return retval; 3462 } 3463 3464 /** 3465 * mpi3mr_dev_rmhs_complete_iou - Device removal IOUC completion 3466 * @sc: Adapter instance reference 3467 * @drv_cmd: Internal command tracker 3468 * 3469 * Issues a target reset TM to the firmware from the device 3470 * removal TM pend list or retry the removal handshake sequence 3471 * based on the IOU control request IOC status. 3472 * 3473 * Return: Nothing 3474 */ 3475 static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_softc *sc, 3476 struct mpi3mr_drvr_cmd *drv_cmd) 3477 { 3478 U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN; 3479 struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL; 3480 struct mpi3mr_target *tgtdev = NULL; 3481 3482 mpi3mr_dprint(sc, MPI3MR_EVENT, 3483 "%s :dev_rmhs_iouctrl_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x)\n", 3484 __func__, drv_cmd->dev_handle, drv_cmd->ioc_status, 3485 drv_cmd->ioc_loginfo); 3486 if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) { 3487 if (drv_cmd->retry_count < MPI3MR_DEVRMHS_RETRYCOUNT) { 3488 drv_cmd->retry_count++; 3489 mpi3mr_dprint(sc, MPI3MR_EVENT, 3490 "%s :dev_rmhs_iouctrl_complete: handle(0x%04x)retrying handshake retry=%d\n", 3491 __func__, drv_cmd->dev_handle, 3492 drv_cmd->retry_count); 3493 mpi3mr_dev_rmhs_send_tm(sc, drv_cmd->dev_handle, 3494 drv_cmd, drv_cmd->iou_rc); 3495 return; 3496 } 3497 mpi3mr_dprint(sc, MPI3MR_ERROR, 3498 "%s :dev removal handshake failed after all retries: handle(0x%04x)\n", 3499 __func__, drv_cmd->dev_handle); 3500 } else { 3501 mtx_lock_spin(&sc->target_lock); 3502 TAILQ_FOREACH(tgtdev, &sc->cam_sc->tgt_list, tgt_next) { 3503 if (tgtdev->dev_handle == drv_cmd->dev_handle) 3504 tgtdev->state = MPI3MR_DEV_REMOVE_HS_COMPLETED; 3505 } 3506 mtx_unlock_spin(&sc->target_lock); 3507 3508 mpi3mr_dprint(sc, MPI3MR_INFO, 3509 "%s :dev removal handshake completed successfully: handle(0x%04x)\n", 3510 __func__, drv_cmd->dev_handle); 3511 mpi3mr_clear_bit(drv_cmd->dev_handle, sc->removepend_bitmap); 3512 } 3513 3514 if (!TAILQ_EMPTY(&sc->delayed_rmhs_list)) { 3515 delayed_dev_rmhs = TAILQ_FIRST(&sc->delayed_rmhs_list); 3516 drv_cmd->dev_handle = delayed_dev_rmhs->handle; 3517 drv_cmd->retry_count = 0; 3518 drv_cmd->iou_rc = delayed_dev_rmhs->iou_rc; 3519 mpi3mr_dprint(sc, MPI3MR_EVENT, 3520 "%s :dev_rmhs_iouctrl_complete: processing delayed TM: handle(0x%04x)\n", 3521 __func__, drv_cmd->dev_handle); 3522 mpi3mr_dev_rmhs_send_tm(sc, drv_cmd->dev_handle, drv_cmd, 3523 drv_cmd->iou_rc); 3524 TAILQ_REMOVE(&sc->delayed_rmhs_list, delayed_dev_rmhs, list); 3525 free(delayed_dev_rmhs, M_MPI3MR); 3526 return; 3527 } 3528 drv_cmd->state = MPI3MR_CMD_NOTUSED; 3529 drv_cmd->callback = NULL; 3530 drv_cmd->retry_count = 0; 3531 drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE; 3532 mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap); 3533 } 3534 3535 /** 3536 * mpi3mr_dev_rmhs_complete_tm - Device removal TM completion 3537 * @sc: Adapter instance reference 3538 * @drv_cmd: Internal command tracker 3539 * 3540 * Issues a target reset TM to the firmware from the device 3541 * removal TM pend list or issue IO Unit control request as 3542 * part of device removal or hidden acknowledgment handshake. 3543 * 3544 * Return: Nothing 3545 */ 3546 static void mpi3mr_dev_rmhs_complete_tm(struct mpi3mr_softc *sc, 3547 struct mpi3mr_drvr_cmd *drv_cmd) 3548 { 3549 Mpi3IoUnitControlRequest_t iou_ctrl; 3550 U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN; 3551 Mpi3SCSITaskMgmtReply_t *tm_reply = NULL; 3552 int retval; 3553 3554 if (drv_cmd->state & MPI3MR_CMD_REPLYVALID) 3555 tm_reply = (Mpi3SCSITaskMgmtReply_t *)drv_cmd->reply; 3556 3557 if (tm_reply) 3558 printf(IOCNAME 3559 "dev_rmhs_tr_complete:handle(0x%04x), ioc_status(0x%04x), loginfo(0x%08x), term_count(%d)\n", 3560 sc->name, drv_cmd->dev_handle, drv_cmd->ioc_status, 3561 drv_cmd->ioc_loginfo, 3562 le32toh(tm_reply->TerminationCount)); 3563 3564 printf(IOCNAME "Issuing IOU CTL: handle(0x%04x) dev_rmhs idx(%d)\n", 3565 sc->name, drv_cmd->dev_handle, cmd_idx); 3566 3567 memset(&iou_ctrl, 0, sizeof(iou_ctrl)); 3568 3569 drv_cmd->state = MPI3MR_CMD_PENDING; 3570 drv_cmd->is_waiting = 0; 3571 drv_cmd->callback = mpi3mr_dev_rmhs_complete_iou; 3572 iou_ctrl.Operation = drv_cmd->iou_rc; 3573 iou_ctrl.Param16[0] = htole16(drv_cmd->dev_handle); 3574 iou_ctrl.HostTag = htole16(drv_cmd->host_tag); 3575 iou_ctrl.Function = MPI3_FUNCTION_IO_UNIT_CONTROL; 3576 3577 retval = mpi3mr_submit_admin_cmd(sc, &iou_ctrl, sizeof(iou_ctrl)); 3578 if (retval) { 3579 printf(IOCNAME "Issue DevRmHsTMIOUCTL: Admin post failed\n", 3580 sc->name); 3581 goto out_failed; 3582 } 3583 3584 return; 3585 out_failed: 3586 drv_cmd->state = MPI3MR_CMD_NOTUSED; 3587 drv_cmd->callback = NULL; 3588 drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE; 3589 drv_cmd->retry_count = 0; 3590 mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap); 3591 } 3592 3593 /** 3594 * mpi3mr_dev_rmhs_send_tm - Issue TM for device removal 3595 * @sc: Adapter instance reference 3596 * @handle: Device handle 3597 * @cmdparam: Internal command tracker 3598 * @iou_rc: IO Unit reason code 3599 * 3600 * Issues a target reset TM to the firmware or add it to a pend 3601 * list as part of device removal or hidden acknowledgment 3602 * handshake. 3603 * 3604 * Return: Nothing 3605 */ 3606 static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_softc *sc, U16 handle, 3607 struct mpi3mr_drvr_cmd *cmdparam, U8 iou_rc) 3608 { 3609 Mpi3SCSITaskMgmtRequest_t tm_req; 3610 int retval = 0; 3611 U16 cmd_idx = MPI3MR_NUM_DEVRMCMD; 3612 U8 retrycount = 5; 3613 struct mpi3mr_drvr_cmd *drv_cmd = cmdparam; 3614 struct delayed_dev_rmhs_node *delayed_dev_rmhs = NULL; 3615 3616 if (drv_cmd) 3617 goto issue_cmd; 3618 do { 3619 cmd_idx = mpi3mr_find_first_zero_bit(sc->devrem_bitmap, 3620 MPI3MR_NUM_DEVRMCMD); 3621 if (cmd_idx < MPI3MR_NUM_DEVRMCMD) { 3622 if (!mpi3mr_test_and_set_bit(cmd_idx, sc->devrem_bitmap)) 3623 break; 3624 cmd_idx = MPI3MR_NUM_DEVRMCMD; 3625 } 3626 } while (retrycount--); 3627 3628 if (cmd_idx >= MPI3MR_NUM_DEVRMCMD) { 3629 delayed_dev_rmhs = malloc(sizeof(*delayed_dev_rmhs),M_MPI3MR, 3630 M_ZERO|M_NOWAIT); 3631 3632 if (!delayed_dev_rmhs) 3633 return; 3634 delayed_dev_rmhs->handle = handle; 3635 delayed_dev_rmhs->iou_rc = iou_rc; 3636 TAILQ_INSERT_TAIL(&(sc->delayed_rmhs_list), delayed_dev_rmhs, list); 3637 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :DevRmHs: tr:handle(0x%04x) is postponed\n", 3638 __func__, handle); 3639 3640 3641 return; 3642 } 3643 drv_cmd = &sc->dev_rmhs_cmds[cmd_idx]; 3644 3645 issue_cmd: 3646 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN; 3647 mpi3mr_dprint(sc, MPI3MR_EVENT, 3648 "%s :Issuing TR TM: for devhandle 0x%04x with dev_rmhs %d\n", 3649 __func__, handle, cmd_idx); 3650 3651 memset(&tm_req, 0, sizeof(tm_req)); 3652 if (drv_cmd->state & MPI3MR_CMD_PENDING) { 3653 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Issue TM: Command is in use\n", __func__); 3654 goto out; 3655 } 3656 drv_cmd->state = MPI3MR_CMD_PENDING; 3657 drv_cmd->is_waiting = 0; 3658 drv_cmd->callback = mpi3mr_dev_rmhs_complete_tm; 3659 drv_cmd->dev_handle = handle; 3660 drv_cmd->iou_rc = iou_rc; 3661 tm_req.DevHandle = htole16(handle); 3662 tm_req.TaskType = MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET; 3663 tm_req.HostTag = htole16(drv_cmd->host_tag); 3664 tm_req.TaskHostTag = htole16(MPI3MR_HOSTTAG_INVALID); 3665 tm_req.Function = MPI3_FUNCTION_SCSI_TASK_MGMT; 3666 3667 mpi3mr_set_bit(handle, sc->removepend_bitmap); 3668 retval = mpi3mr_submit_admin_cmd(sc, &tm_req, sizeof(tm_req)); 3669 if (retval) { 3670 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s :Issue DevRmHsTM: Admin Post failed\n", 3671 __func__); 3672 goto out_failed; 3673 } 3674 out: 3675 return; 3676 out_failed: 3677 drv_cmd->state = MPI3MR_CMD_NOTUSED; 3678 drv_cmd->callback = NULL; 3679 drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE; 3680 drv_cmd->retry_count = 0; 3681 mpi3mr_clear_bit(cmd_idx, sc->devrem_bitmap); 3682 } 3683 3684 /** 3685 * mpi3mr_complete_evt_ack - Event ack request completion 3686 * @sc: Adapter instance reference 3687 * @drv_cmd: Internal command tracker 3688 * 3689 * This is the completion handler for non blocking event 3690 * acknowledgment sent to the firmware and this will issue any 3691 * pending event acknowledgment request. 3692 * 3693 * Return: Nothing 3694 */ 3695 static void mpi3mr_complete_evt_ack(struct mpi3mr_softc *sc, 3696 struct mpi3mr_drvr_cmd *drv_cmd) 3697 { 3698 U16 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN; 3699 struct delayed_evtack_node *delayed_evtack = NULL; 3700 3701 if (drv_cmd->ioc_status != MPI3_IOCSTATUS_SUCCESS) { 3702 mpi3mr_dprint(sc, MPI3MR_EVENT, 3703 "%s: Failed IOCStatus(0x%04x) Loginfo(0x%08x)\n", __func__, 3704 (drv_cmd->ioc_status & MPI3_IOCSTATUS_STATUS_MASK), 3705 drv_cmd->ioc_loginfo); 3706 } 3707 3708 if (!TAILQ_EMPTY(&sc->delayed_evtack_cmds_list)) { 3709 delayed_evtack = TAILQ_FIRST(&sc->delayed_evtack_cmds_list); 3710 mpi3mr_dprint(sc, MPI3MR_EVENT, 3711 "%s: processing delayed event ack for event %d\n", 3712 __func__, delayed_evtack->event); 3713 mpi3mr_send_evt_ack(sc, delayed_evtack->event, drv_cmd, 3714 delayed_evtack->event_ctx); 3715 TAILQ_REMOVE(&sc->delayed_evtack_cmds_list, delayed_evtack, list); 3716 free(delayed_evtack, M_MPI3MR); 3717 return; 3718 } 3719 drv_cmd->state = MPI3MR_CMD_NOTUSED; 3720 drv_cmd->callback = NULL; 3721 mpi3mr_clear_bit(cmd_idx, sc->evtack_cmds_bitmap); 3722 } 3723 3724 /** 3725 * mpi3mr_send_evt_ack - Issue event acknwoledgment request 3726 * @sc: Adapter instance reference 3727 * @event: MPI3 event id 3728 * @cmdparam: Internal command tracker 3729 * @event_ctx: Event context 3730 * 3731 * Issues event acknowledgment request to the firmware if there 3732 * is a free command to send the event ack else it to a pend 3733 * list so that it will be processed on a completion of a prior 3734 * event acknowledgment . 3735 * 3736 * Return: Nothing 3737 */ 3738 static void mpi3mr_send_evt_ack(struct mpi3mr_softc *sc, U8 event, 3739 struct mpi3mr_drvr_cmd *cmdparam, U32 event_ctx) 3740 { 3741 Mpi3EventAckRequest_t evtack_req; 3742 int retval = 0; 3743 U8 retrycount = 5; 3744 U16 cmd_idx = MPI3MR_NUM_EVTACKCMD; 3745 struct mpi3mr_drvr_cmd *drv_cmd = cmdparam; 3746 struct delayed_evtack_node *delayed_evtack = NULL; 3747 3748 if (drv_cmd) 3749 goto issue_cmd; 3750 do { 3751 cmd_idx = mpi3mr_find_first_zero_bit(sc->evtack_cmds_bitmap, 3752 MPI3MR_NUM_EVTACKCMD); 3753 if (cmd_idx < MPI3MR_NUM_EVTACKCMD) { 3754 if (!mpi3mr_test_and_set_bit(cmd_idx, 3755 sc->evtack_cmds_bitmap)) 3756 break; 3757 cmd_idx = MPI3MR_NUM_EVTACKCMD; 3758 } 3759 } while (retrycount--); 3760 3761 if (cmd_idx >= MPI3MR_NUM_EVTACKCMD) { 3762 delayed_evtack = malloc(sizeof(*delayed_evtack),M_MPI3MR, 3763 M_ZERO | M_NOWAIT); 3764 if (!delayed_evtack) 3765 return; 3766 delayed_evtack->event = event; 3767 delayed_evtack->event_ctx = event_ctx; 3768 TAILQ_INSERT_TAIL(&(sc->delayed_evtack_cmds_list), delayed_evtack, list); 3769 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s : Event ack for event:%d is postponed\n", 3770 __func__, event); 3771 return; 3772 } 3773 drv_cmd = &sc->evtack_cmds[cmd_idx]; 3774 3775 issue_cmd: 3776 cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN; 3777 3778 memset(&evtack_req, 0, sizeof(evtack_req)); 3779 if (drv_cmd->state & MPI3MR_CMD_PENDING) { 3780 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s: Command is in use\n", __func__); 3781 goto out; 3782 } 3783 drv_cmd->state = MPI3MR_CMD_PENDING; 3784 drv_cmd->is_waiting = 0; 3785 drv_cmd->callback = mpi3mr_complete_evt_ack; 3786 evtack_req.HostTag = htole16(drv_cmd->host_tag); 3787 evtack_req.Function = MPI3_FUNCTION_EVENT_ACK; 3788 evtack_req.Event = event; 3789 evtack_req.EventContext = htole32(event_ctx); 3790 retval = mpi3mr_submit_admin_cmd(sc, &evtack_req, 3791 sizeof(evtack_req)); 3792 3793 if (retval) { 3794 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Admin Post failed\n", __func__); 3795 goto out_failed; 3796 } 3797 out: 3798 return; 3799 out_failed: 3800 drv_cmd->state = MPI3MR_CMD_NOTUSED; 3801 drv_cmd->callback = NULL; 3802 mpi3mr_clear_bit(cmd_idx, sc->evtack_cmds_bitmap); 3803 } 3804 3805 /* 3806 * mpi3mr_pcietopochg_evt_th - PCIETopologyChange evt tophalf 3807 * @sc: Adapter instance reference 3808 * @event_reply: Event data 3809 * 3810 * Checks for the reason code and based on that either block I/O 3811 * to device, or unblock I/O to the device, or start the device 3812 * removal handshake with reason as remove with the firmware for 3813 * PCIe devices. 3814 * 3815 * Return: Nothing 3816 */ 3817 static void mpi3mr_pcietopochg_evt_th(struct mpi3mr_softc *sc, 3818 Mpi3EventNotificationReply_t *event_reply) 3819 { 3820 Mpi3EventDataPcieTopologyChangeList_t *topo_evt = 3821 (Mpi3EventDataPcieTopologyChangeList_t *) event_reply->EventData; 3822 int i; 3823 U16 handle; 3824 U8 reason_code; 3825 struct mpi3mr_target *tgtdev = NULL; 3826 3827 for (i = 0; i < topo_evt->NumEntries; i++) { 3828 handle = le16toh(topo_evt->PortEntry[i].AttachedDevHandle); 3829 if (!handle) 3830 continue; 3831 reason_code = topo_evt->PortEntry[i].PortStatus; 3832 tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle); 3833 switch (reason_code) { 3834 case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING: 3835 if (tgtdev) { 3836 tgtdev->dev_removed = 1; 3837 tgtdev->dev_removedelay = 0; 3838 mpi3mr_atomic_set(&tgtdev->block_io, 0); 3839 } 3840 mpi3mr_dev_rmhs_send_tm(sc, handle, NULL, 3841 MPI3_CTRL_OP_REMOVE_DEVICE); 3842 break; 3843 case MPI3_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING: 3844 if (tgtdev) { 3845 tgtdev->dev_removedelay = 1; 3846 mpi3mr_atomic_inc(&tgtdev->block_io); 3847 } 3848 break; 3849 case MPI3_EVENT_PCIE_TOPO_PS_RESPONDING: 3850 if (tgtdev && 3851 tgtdev->dev_removedelay) { 3852 tgtdev->dev_removedelay = 0; 3853 if (mpi3mr_atomic_read(&tgtdev->block_io) > 0) 3854 mpi3mr_atomic_dec(&tgtdev->block_io); 3855 } 3856 break; 3857 case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED: 3858 default: 3859 break; 3860 } 3861 } 3862 } 3863 3864 /** 3865 * mpi3mr_sastopochg_evt_th - SASTopologyChange evt tophalf 3866 * @sc: Adapter instance reference 3867 * @event_reply: Event data 3868 * 3869 * Checks for the reason code and based on that either block I/O 3870 * to device, or unblock I/O to the device, or start the device 3871 * removal handshake with reason as remove with the firmware for 3872 * SAS/SATA devices. 3873 * 3874 * Return: Nothing 3875 */ 3876 static void mpi3mr_sastopochg_evt_th(struct mpi3mr_softc *sc, 3877 Mpi3EventNotificationReply_t *event_reply) 3878 { 3879 Mpi3EventDataSasTopologyChangeList_t *topo_evt = 3880 (Mpi3EventDataSasTopologyChangeList_t *)event_reply->EventData; 3881 int i; 3882 U16 handle; 3883 U8 reason_code; 3884 struct mpi3mr_target *tgtdev = NULL; 3885 3886 for (i = 0; i < topo_evt->NumEntries; i++) { 3887 handle = le16toh(topo_evt->PhyEntry[i].AttachedDevHandle); 3888 if (!handle) 3889 continue; 3890 reason_code = topo_evt->PhyEntry[i].Status & 3891 MPI3_EVENT_SAS_TOPO_PHY_RC_MASK; 3892 tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle); 3893 switch (reason_code) { 3894 case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING: 3895 if (tgtdev) { 3896 tgtdev->dev_removed = 1; 3897 tgtdev->dev_removedelay = 0; 3898 mpi3mr_atomic_set(&tgtdev->block_io, 0); 3899 } 3900 mpi3mr_dev_rmhs_send_tm(sc, handle, NULL, 3901 MPI3_CTRL_OP_REMOVE_DEVICE); 3902 break; 3903 case MPI3_EVENT_SAS_TOPO_PHY_RC_DELAY_NOT_RESPONDING: 3904 if (tgtdev) { 3905 tgtdev->dev_removedelay = 1; 3906 mpi3mr_atomic_inc(&tgtdev->block_io); 3907 } 3908 break; 3909 case MPI3_EVENT_SAS_TOPO_PHY_RC_RESPONDING: 3910 if (tgtdev && 3911 tgtdev->dev_removedelay) { 3912 tgtdev->dev_removedelay = 0; 3913 if (mpi3mr_atomic_read(&tgtdev->block_io) > 0) 3914 mpi3mr_atomic_dec(&tgtdev->block_io); 3915 } 3916 case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED: 3917 default: 3918 break; 3919 } 3920 } 3921 3922 } 3923 /** 3924 * mpi3mr_devstatuschg_evt_th - DeviceStatusChange evt tophalf 3925 * @sc: Adapter instance reference 3926 * @event_reply: Event data 3927 * 3928 * Checks for the reason code and based on that either block I/O 3929 * to device, or unblock I/O to the device, or start the device 3930 * removal handshake with reason as remove/hide acknowledgment 3931 * with the firmware. 3932 * 3933 * Return: Nothing 3934 */ 3935 static void mpi3mr_devstatuschg_evt_th(struct mpi3mr_softc *sc, 3936 Mpi3EventNotificationReply_t *event_reply) 3937 { 3938 U16 dev_handle = 0; 3939 U8 ublock = 0, block = 0, hide = 0, uhide = 0, delete = 0, remove = 0; 3940 struct mpi3mr_target *tgtdev = NULL; 3941 Mpi3EventDataDeviceStatusChange_t *evtdata = 3942 (Mpi3EventDataDeviceStatusChange_t *) event_reply->EventData; 3943 3944 dev_handle = le16toh(evtdata->DevHandle); 3945 3946 switch (evtdata->ReasonCode) { 3947 case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_STRT: 3948 case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_STRT: 3949 block = 1; 3950 break; 3951 case MPI3_EVENT_DEV_STAT_RC_HIDDEN: 3952 delete = 1; 3953 hide = 1; 3954 break; 3955 case MPI3_EVENT_DEV_STAT_RC_NOT_HIDDEN: 3956 uhide = 1; 3957 break; 3958 case MPI3_EVENT_DEV_STAT_RC_VD_NOT_RESPONDING: 3959 delete = 1; 3960 remove = 1; 3961 break; 3962 case MPI3_EVENT_DEV_STAT_RC_INT_DEVICE_RESET_CMP: 3963 case MPI3_EVENT_DEV_STAT_RC_INT_IT_NEXUS_RESET_CMP: 3964 ublock = 1; 3965 break; 3966 default: 3967 break; 3968 } 3969 3970 tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, dev_handle); 3971 3972 if (!tgtdev) { 3973 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s :target with dev_handle:0x%x not found\n", 3974 __func__, dev_handle); 3975 return; 3976 } 3977 3978 if (block) 3979 mpi3mr_atomic_inc(&tgtdev->block_io); 3980 3981 if (hide) 3982 tgtdev->is_hidden = hide; 3983 3984 if (uhide) { 3985 tgtdev->is_hidden = 0; 3986 tgtdev->dev_removed = 0; 3987 } 3988 3989 if (delete) 3990 tgtdev->dev_removed = 1; 3991 3992 if (ublock) { 3993 if (mpi3mr_atomic_read(&tgtdev->block_io) > 0) 3994 mpi3mr_atomic_dec(&tgtdev->block_io); 3995 } 3996 3997 if (remove) { 3998 mpi3mr_dev_rmhs_send_tm(sc, dev_handle, NULL, 3999 MPI3_CTRL_OP_REMOVE_DEVICE); 4000 } 4001 if (hide) 4002 mpi3mr_dev_rmhs_send_tm(sc, dev_handle, NULL, 4003 MPI3_CTRL_OP_HIDDEN_ACK); 4004 } 4005 4006 /** 4007 * mpi3mr_preparereset_evt_th - Prepareforreset evt tophalf 4008 * @sc: Adapter instance reference 4009 * @event_reply: Event data 4010 * 4011 * Blocks and unblocks host level I/O based on the reason code 4012 * 4013 * Return: Nothing 4014 */ 4015 static void mpi3mr_preparereset_evt_th(struct mpi3mr_softc *sc, 4016 Mpi3EventNotificationReply_t *event_reply) 4017 { 4018 Mpi3EventDataPrepareForReset_t *evtdata = 4019 (Mpi3EventDataPrepareForReset_t *)event_reply->EventData; 4020 4021 if (evtdata->ReasonCode == MPI3_EVENT_PREPARE_RESET_RC_START) { 4022 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Recieved PrepForReset Event with RC=START\n", 4023 __func__); 4024 if (sc->prepare_for_reset) 4025 return; 4026 sc->prepare_for_reset = 1; 4027 sc->prepare_for_reset_timeout_counter = 0; 4028 } else if (evtdata->ReasonCode == MPI3_EVENT_PREPARE_RESET_RC_ABORT) { 4029 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s :Recieved PrepForReset Event with RC=ABORT\n", 4030 __func__); 4031 sc->prepare_for_reset = 0; 4032 sc->prepare_for_reset_timeout_counter = 0; 4033 } 4034 if ((event_reply->MsgFlags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK) 4035 == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED) 4036 mpi3mr_send_evt_ack(sc, event_reply->Event, NULL, 4037 le32toh(event_reply->EventContext)); 4038 } 4039 4040 /** 4041 * mpi3mr_energypackchg_evt_th - Energypackchange evt tophalf 4042 * @sc: Adapter instance reference 4043 * @event_reply: Event data 4044 * 4045 * Identifies the new shutdown timeout value and update. 4046 * 4047 * Return: Nothing 4048 */ 4049 static void mpi3mr_energypackchg_evt_th(struct mpi3mr_softc *sc, 4050 Mpi3EventNotificationReply_t *event_reply) 4051 { 4052 Mpi3EventDataEnergyPackChange_t *evtdata = 4053 (Mpi3EventDataEnergyPackChange_t *)event_reply->EventData; 4054 U16 shutdown_timeout = le16toh(evtdata->ShutdownTimeout); 4055 4056 if (shutdown_timeout <= 0) { 4057 mpi3mr_dprint(sc, MPI3MR_ERROR, 4058 "%s :Invalid Shutdown Timeout received = %d\n", 4059 __func__, shutdown_timeout); 4060 return; 4061 } 4062 4063 mpi3mr_dprint(sc, MPI3MR_EVENT, 4064 "%s :Previous Shutdown Timeout Value = %d New Shutdown Timeout Value = %d\n", 4065 __func__, sc->facts.shutdown_timeout, shutdown_timeout); 4066 sc->facts.shutdown_timeout = shutdown_timeout; 4067 } 4068 4069 /** 4070 * mpi3mr_cablemgmt_evt_th - Cable mgmt evt tophalf 4071 * @sc: Adapter instance reference 4072 * @event_reply: Event data 4073 * 4074 * Displays Cable manegemt event details. 4075 * 4076 * Return: Nothing 4077 */ 4078 static void mpi3mr_cablemgmt_evt_th(struct mpi3mr_softc *sc, 4079 Mpi3EventNotificationReply_t *event_reply) 4080 { 4081 Mpi3EventDataCableManagement_t *evtdata = 4082 (Mpi3EventDataCableManagement_t *)event_reply->EventData; 4083 4084 switch (evtdata->Status) { 4085 case MPI3_EVENT_CABLE_MGMT_STATUS_INSUFFICIENT_POWER: 4086 { 4087 mpi3mr_dprint(sc, MPI3MR_INFO, "An active cable with ReceptacleID %d cannot be powered.\n" 4088 "Devices connected to this cable are not detected.\n" 4089 "This cable requires %d mW of power.\n", 4090 evtdata->ReceptacleID, 4091 le32toh(evtdata->ActiveCablePowerRequirement)); 4092 break; 4093 } 4094 case MPI3_EVENT_CABLE_MGMT_STATUS_DEGRADED: 4095 { 4096 mpi3mr_dprint(sc, MPI3MR_INFO, "A cable with ReceptacleID %d is not running at optimal speed\n", 4097 evtdata->ReceptacleID); 4098 break; 4099 } 4100 default: 4101 break; 4102 } 4103 } 4104 4105 /** 4106 * mpi3mr_process_events - Event's toph-half handler 4107 * @sc: Adapter instance reference 4108 * @event_reply: Event data 4109 * 4110 * Top half of event processing. 4111 * 4112 * Return: Nothing 4113 */ 4114 static void mpi3mr_process_events(struct mpi3mr_softc *sc, 4115 uintptr_t data, Mpi3EventNotificationReply_t *event_reply) 4116 { 4117 U16 evt_type; 4118 bool ack_req = 0, process_evt_bh = 0; 4119 struct mpi3mr_fw_event_work *fw_event; 4120 U16 sz; 4121 4122 if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) 4123 goto out; 4124 4125 if ((event_reply->MsgFlags & MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_MASK) 4126 == MPI3_EVENT_NOTIFY_MSGFLAGS_ACK_REQUIRED) 4127 ack_req = 1; 4128 4129 evt_type = event_reply->Event; 4130 4131 switch (evt_type) { 4132 case MPI3_EVENT_DEVICE_ADDED: 4133 { 4134 Mpi3DevicePage0_t *dev_pg0 = 4135 (Mpi3DevicePage0_t *) event_reply->EventData; 4136 if (mpi3mr_create_device(sc, dev_pg0)) 4137 mpi3mr_dprint(sc, MPI3MR_ERROR, 4138 "%s :Failed to add device in the device add event\n", 4139 __func__); 4140 else 4141 process_evt_bh = 1; 4142 break; 4143 } 4144 4145 case MPI3_EVENT_DEVICE_STATUS_CHANGE: 4146 { 4147 process_evt_bh = 1; 4148 mpi3mr_devstatuschg_evt_th(sc, event_reply); 4149 break; 4150 } 4151 case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 4152 { 4153 process_evt_bh = 1; 4154 mpi3mr_sastopochg_evt_th(sc, event_reply); 4155 break; 4156 } 4157 case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: 4158 { 4159 process_evt_bh = 1; 4160 mpi3mr_pcietopochg_evt_th(sc, event_reply); 4161 break; 4162 } 4163 case MPI3_EVENT_PREPARE_FOR_RESET: 4164 { 4165 mpi3mr_preparereset_evt_th(sc, event_reply); 4166 ack_req = 0; 4167 break; 4168 } 4169 case MPI3_EVENT_DEVICE_INFO_CHANGED: 4170 case MPI3_EVENT_LOG_DATA: 4171 { 4172 process_evt_bh = 1; 4173 break; 4174 } 4175 case MPI3_EVENT_ENERGY_PACK_CHANGE: 4176 { 4177 mpi3mr_energypackchg_evt_th(sc, event_reply); 4178 break; 4179 } 4180 case MPI3_EVENT_CABLE_MGMT: 4181 { 4182 mpi3mr_cablemgmt_evt_th(sc, event_reply); 4183 break; 4184 } 4185 4186 case MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE: 4187 case MPI3_EVENT_SAS_DISCOVERY: 4188 case MPI3_EVENT_SAS_DEVICE_DISCOVERY_ERROR: 4189 case MPI3_EVENT_SAS_BROADCAST_PRIMITIVE: 4190 case MPI3_EVENT_PCIE_ENUMERATION: 4191 break; 4192 default: 4193 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :Event 0x%02x is not handled by driver\n", 4194 __func__, evt_type); 4195 break; 4196 } 4197 4198 if (process_evt_bh || ack_req) { 4199 fw_event = malloc(sizeof(struct mpi3mr_fw_event_work), M_MPI3MR, 4200 M_ZERO|M_NOWAIT); 4201 4202 if (!fw_event) { 4203 printf("%s: allocate failed for fw_event\n", __func__); 4204 return; 4205 } 4206 4207 sz = le16toh(event_reply->EventDataLength) * 4; 4208 fw_event->event_data = malloc(sz, M_MPI3MR, M_ZERO|M_NOWAIT); 4209 4210 if (!fw_event->event_data) { 4211 printf("%s: allocate failed for event_data\n", __func__); 4212 free(fw_event, M_MPI3MR); 4213 return; 4214 } 4215 4216 bcopy(event_reply->EventData, fw_event->event_data, sz); 4217 fw_event->event = event_reply->Event; 4218 if ((event_reply->Event == MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST || 4219 event_reply->Event == MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST || 4220 event_reply->Event == MPI3_EVENT_ENCL_DEVICE_STATUS_CHANGE ) && 4221 sc->track_mapping_events) 4222 sc->pending_map_events++; 4223 4224 /* 4225 * Events should be processed after Port enable is completed. 4226 */ 4227 if ((event_reply->Event == MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST || 4228 event_reply->Event == MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST ) && 4229 !(sc->mpi3mr_flags & MPI3MR_FLAGS_PORT_ENABLE_DONE)) 4230 mpi3mr_startup_increment(sc->cam_sc); 4231 4232 fw_event->send_ack = ack_req; 4233 fw_event->event_context = le32toh(event_reply->EventContext); 4234 fw_event->event_data_size = sz; 4235 fw_event->process_event = process_evt_bh; 4236 4237 mtx_lock(&sc->fwevt_lock); 4238 TAILQ_INSERT_TAIL(&sc->cam_sc->ev_queue, fw_event, ev_link); 4239 taskqueue_enqueue(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task); 4240 mtx_unlock(&sc->fwevt_lock); 4241 4242 } 4243 out: 4244 return; 4245 } 4246 4247 static void mpi3mr_handle_events(struct mpi3mr_softc *sc, uintptr_t data, 4248 Mpi3DefaultReply_t *def_reply) 4249 { 4250 Mpi3EventNotificationReply_t *event_reply = 4251 (Mpi3EventNotificationReply_t *)def_reply; 4252 4253 sc->change_count = event_reply->IOCChangeCount; 4254 mpi3mr_display_event_data(sc, event_reply); 4255 4256 mpi3mr_process_events(sc, data, event_reply); 4257 } 4258 4259 static void mpi3mr_process_admin_reply_desc(struct mpi3mr_softc *sc, 4260 Mpi3DefaultReplyDescriptor_t *reply_desc, U64 *reply_dma) 4261 { 4262 U16 reply_desc_type, host_tag = 0, idx; 4263 U16 ioc_status = MPI3_IOCSTATUS_SUCCESS; 4264 U32 ioc_loginfo = 0; 4265 Mpi3StatusReplyDescriptor_t *status_desc; 4266 Mpi3AddressReplyDescriptor_t *addr_desc; 4267 Mpi3SuccessReplyDescriptor_t *success_desc; 4268 Mpi3DefaultReply_t *def_reply = NULL; 4269 struct mpi3mr_drvr_cmd *cmdptr = NULL; 4270 Mpi3SCSIIOReply_t *scsi_reply; 4271 U8 *sense_buf = NULL; 4272 4273 *reply_dma = 0; 4274 reply_desc_type = reply_desc->ReplyFlags & 4275 MPI3_REPLY_DESCRIPT_FLAGS_TYPE_MASK; 4276 switch (reply_desc_type) { 4277 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS: 4278 status_desc = (Mpi3StatusReplyDescriptor_t *)reply_desc; 4279 host_tag = status_desc->HostTag; 4280 ioc_status = status_desc->IOCStatus; 4281 if (ioc_status & 4282 MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL) 4283 ioc_loginfo = status_desc->IOCLogInfo; 4284 ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; 4285 break; 4286 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY: 4287 addr_desc = (Mpi3AddressReplyDescriptor_t *)reply_desc; 4288 *reply_dma = addr_desc->ReplyFrameAddress; 4289 def_reply = mpi3mr_get_reply_virt_addr(sc, *reply_dma); 4290 if (def_reply == NULL) 4291 goto out; 4292 host_tag = def_reply->HostTag; 4293 ioc_status = def_reply->IOCStatus; 4294 if (ioc_status & 4295 MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL) 4296 ioc_loginfo = def_reply->IOCLogInfo; 4297 ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; 4298 if (def_reply->Function == MPI3_FUNCTION_SCSI_IO) { 4299 scsi_reply = (Mpi3SCSIIOReply_t *)def_reply; 4300 sense_buf = mpi3mr_get_sensebuf_virt_addr(sc, 4301 scsi_reply->SenseDataBufferAddress); 4302 } 4303 break; 4304 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS: 4305 success_desc = (Mpi3SuccessReplyDescriptor_t *)reply_desc; 4306 host_tag = success_desc->HostTag; 4307 break; 4308 default: 4309 break; 4310 } 4311 switch (host_tag) { 4312 case MPI3MR_HOSTTAG_INITCMDS: 4313 cmdptr = &sc->init_cmds; 4314 break; 4315 case MPI3MR_HOSTTAG_IOCTLCMDS: 4316 cmdptr = &sc->ioctl_cmds; 4317 break; 4318 case MPI3MR_HOSTTAG_TMS: 4319 cmdptr = &sc->host_tm_cmds; 4320 wakeup((void *)&sc->tm_chan); 4321 break; 4322 case MPI3MR_HOSTTAG_PELABORT: 4323 cmdptr = &sc->pel_abort_cmd; 4324 break; 4325 case MPI3MR_HOSTTAG_PELWAIT: 4326 cmdptr = &sc->pel_cmds; 4327 break; 4328 case MPI3MR_HOSTTAG_INVALID: 4329 if (def_reply && def_reply->Function == 4330 MPI3_FUNCTION_EVENT_NOTIFICATION) 4331 mpi3mr_handle_events(sc, *reply_dma ,def_reply); 4332 default: 4333 break; 4334 } 4335 4336 if (host_tag >= MPI3MR_HOSTTAG_DEVRMCMD_MIN && 4337 host_tag <= MPI3MR_HOSTTAG_DEVRMCMD_MAX ) { 4338 idx = host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN; 4339 cmdptr = &sc->dev_rmhs_cmds[idx]; 4340 } 4341 4342 if (host_tag >= MPI3MR_HOSTTAG_EVTACKCMD_MIN && 4343 host_tag <= MPI3MR_HOSTTAG_EVTACKCMD_MAX) { 4344 idx = host_tag - MPI3MR_HOSTTAG_EVTACKCMD_MIN; 4345 cmdptr = &sc->evtack_cmds[idx]; 4346 } 4347 4348 if (cmdptr) { 4349 if (cmdptr->state & MPI3MR_CMD_PENDING) { 4350 cmdptr->state |= MPI3MR_CMD_COMPLETE; 4351 cmdptr->ioc_loginfo = ioc_loginfo; 4352 cmdptr->ioc_status = ioc_status; 4353 cmdptr->state &= ~MPI3MR_CMD_PENDING; 4354 if (def_reply) { 4355 cmdptr->state |= MPI3MR_CMD_REPLYVALID; 4356 memcpy((U8 *)cmdptr->reply, (U8 *)def_reply, 4357 sc->reply_sz); 4358 } 4359 if (sense_buf && cmdptr->sensebuf) { 4360 cmdptr->is_senseprst = 1; 4361 memcpy(cmdptr->sensebuf, sense_buf, 4362 MPI3MR_SENSEBUF_SZ); 4363 } 4364 if (cmdptr->is_waiting) { 4365 complete(&cmdptr->completion); 4366 cmdptr->is_waiting = 0; 4367 } else if (cmdptr->callback) 4368 cmdptr->callback(sc, cmdptr); 4369 } 4370 } 4371 out: 4372 if (sense_buf != NULL) 4373 mpi3mr_repost_sense_buf(sc, 4374 scsi_reply->SenseDataBufferAddress); 4375 return; 4376 } 4377 4378 /* 4379 * mpi3mr_complete_admin_cmd: ISR routine for admin commands 4380 * @sc: Adapter's soft instance 4381 * 4382 * This function processes admin command completions. 4383 */ 4384 static int mpi3mr_complete_admin_cmd(struct mpi3mr_softc *sc) 4385 { 4386 U32 exp_phase = sc->admin_reply_ephase; 4387 U32 adm_reply_ci = sc->admin_reply_ci; 4388 U32 num_adm_reply = 0; 4389 U64 reply_dma = 0; 4390 Mpi3DefaultReplyDescriptor_t *reply_desc; 4391 U16 threshold_comps = 0; 4392 4393 mtx_lock_spin(&sc->admin_reply_lock); 4394 if (sc->admin_in_use == false) { 4395 sc->admin_in_use = true; 4396 mtx_unlock_spin(&sc->admin_reply_lock); 4397 } else { 4398 mtx_unlock_spin(&sc->admin_reply_lock); 4399 return 0; 4400 } 4401 4402 reply_desc = (Mpi3DefaultReplyDescriptor_t *)sc->admin_reply + 4403 adm_reply_ci; 4404 4405 if ((reply_desc->ReplyFlags & 4406 MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) { 4407 mtx_lock_spin(&sc->admin_reply_lock); 4408 sc->admin_in_use = false; 4409 mtx_unlock_spin(&sc->admin_reply_lock); 4410 return 0; 4411 } 4412 4413 do { 4414 sc->admin_req_ci = reply_desc->RequestQueueCI; 4415 mpi3mr_process_admin_reply_desc(sc, reply_desc, &reply_dma); 4416 if (reply_dma) 4417 mpi3mr_repost_reply_buf(sc, reply_dma); 4418 num_adm_reply++; 4419 if (++adm_reply_ci == sc->num_admin_replies) { 4420 adm_reply_ci = 0; 4421 exp_phase ^= 1; 4422 } 4423 reply_desc = 4424 (Mpi3DefaultReplyDescriptor_t *)sc->admin_reply + 4425 adm_reply_ci; 4426 if ((reply_desc->ReplyFlags & 4427 MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) 4428 break; 4429 4430 if (++threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) { 4431 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, adm_reply_ci); 4432 threshold_comps = 0; 4433 } 4434 } while (1); 4435 4436 mpi3mr_regwrite(sc, MPI3_SYSIF_ADMIN_REPLY_Q_CI_OFFSET, adm_reply_ci); 4437 sc->admin_reply_ci = adm_reply_ci; 4438 sc->admin_reply_ephase = exp_phase; 4439 mtx_lock_spin(&sc->admin_reply_lock); 4440 sc->admin_in_use = false; 4441 mtx_unlock_spin(&sc->admin_reply_lock); 4442 return num_adm_reply; 4443 } 4444 4445 static void 4446 mpi3mr_cmd_done(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cmd) 4447 { 4448 mpi3mr_unmap_request(sc, cmd); 4449 4450 mtx_lock(&sc->mpi3mr_mtx); 4451 if (cmd->callout_owner) { 4452 callout_stop(&cmd->callout); 4453 cmd->callout_owner = false; 4454 } 4455 4456 if (sc->unrecoverable) 4457 mpi3mr_set_ccbstatus(cmd->ccb, CAM_DEV_NOT_THERE); 4458 4459 xpt_done(cmd->ccb); 4460 cmd->ccb = NULL; 4461 mtx_unlock(&sc->mpi3mr_mtx); 4462 mpi3mr_release_command(cmd); 4463 } 4464 4465 void mpi3mr_process_op_reply_desc(struct mpi3mr_softc *sc, 4466 Mpi3DefaultReplyDescriptor_t *reply_desc, U64 *reply_dma) 4467 { 4468 U16 reply_desc_type, host_tag = 0; 4469 U16 ioc_status = MPI3_IOCSTATUS_SUCCESS; 4470 U32 ioc_loginfo = 0; 4471 Mpi3StatusReplyDescriptor_t *status_desc = NULL; 4472 Mpi3AddressReplyDescriptor_t *addr_desc = NULL; 4473 Mpi3SuccessReplyDescriptor_t *success_desc = NULL; 4474 Mpi3SCSIIOReply_t *scsi_reply = NULL; 4475 U8 *sense_buf = NULL; 4476 U8 scsi_state = 0, scsi_status = 0, sense_state = 0; 4477 U32 xfer_count = 0, sense_count =0, resp_data = 0; 4478 struct mpi3mr_cmd *cm = NULL; 4479 union ccb *ccb; 4480 struct ccb_scsiio *csio; 4481 struct mpi3mr_cam_softc *cam_sc; 4482 U32 target_id; 4483 U8 *scsi_cdb; 4484 struct mpi3mr_target *target = NULL; 4485 U32 ioc_pend_data_len = 0, tg_pend_data_len = 0, data_len_blks = 0; 4486 struct mpi3mr_throttle_group_info *tg = NULL; 4487 U8 throttle_enabled_dev = 0; 4488 static int ratelimit; 4489 4490 *reply_dma = 0; 4491 reply_desc_type = reply_desc->ReplyFlags & 4492 MPI3_REPLY_DESCRIPT_FLAGS_TYPE_MASK; 4493 switch (reply_desc_type) { 4494 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_STATUS: 4495 status_desc = (Mpi3StatusReplyDescriptor_t *)reply_desc; 4496 host_tag = status_desc->HostTag; 4497 ioc_status = status_desc->IOCStatus; 4498 if (ioc_status & 4499 MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL) 4500 ioc_loginfo = status_desc->IOCLogInfo; 4501 ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; 4502 break; 4503 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_ADDRESS_REPLY: 4504 addr_desc = (Mpi3AddressReplyDescriptor_t *)reply_desc; 4505 *reply_dma = addr_desc->ReplyFrameAddress; 4506 scsi_reply = mpi3mr_get_reply_virt_addr(sc, 4507 *reply_dma); 4508 if (scsi_reply == NULL) { 4509 mpi3mr_dprint(sc, MPI3MR_ERROR, "scsi_reply is NULL, " 4510 "this shouldn't happen, reply_desc: %p\n", 4511 reply_desc); 4512 goto out; 4513 } 4514 4515 host_tag = scsi_reply->HostTag; 4516 ioc_status = scsi_reply->IOCStatus; 4517 scsi_status = scsi_reply->SCSIStatus; 4518 scsi_state = scsi_reply->SCSIState; 4519 sense_state = (scsi_state & MPI3_SCSI_STATE_SENSE_MASK); 4520 xfer_count = scsi_reply->TransferCount; 4521 sense_count = scsi_reply->SenseCount; 4522 resp_data = scsi_reply->ResponseData; 4523 sense_buf = mpi3mr_get_sensebuf_virt_addr(sc, 4524 scsi_reply->SenseDataBufferAddress); 4525 if (ioc_status & 4526 MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_LOGINFOAVAIL) 4527 ioc_loginfo = scsi_reply->IOCLogInfo; 4528 ioc_status &= MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK; 4529 if (sense_state == MPI3_SCSI_STATE_SENSE_BUFF_Q_EMPTY) 4530 mpi3mr_dprint(sc, MPI3MR_ERROR, "Ran out of sense buffers\n"); 4531 4532 break; 4533 case MPI3_REPLY_DESCRIPT_FLAGS_TYPE_SUCCESS: 4534 success_desc = (Mpi3SuccessReplyDescriptor_t *)reply_desc; 4535 host_tag = success_desc->HostTag; 4536 4537 default: 4538 break; 4539 } 4540 4541 cm = sc->cmd_list[host_tag]; 4542 4543 if (cm->state == MPI3MR_CMD_STATE_FREE) 4544 goto out; 4545 4546 cam_sc = sc->cam_sc; 4547 ccb = cm->ccb; 4548 csio = &ccb->csio; 4549 target_id = csio->ccb_h.target_id; 4550 4551 scsi_cdb = scsiio_cdb_ptr(csio); 4552 4553 target = mpi3mr_find_target_by_per_id(cam_sc, target_id); 4554 if (sc->iot_enable) { 4555 data_len_blks = csio->dxfer_len >> 9; 4556 4557 if (target) { 4558 tg = target->throttle_group; 4559 throttle_enabled_dev = 4560 target->io_throttle_enabled; 4561 } 4562 4563 if ((data_len_blks >= sc->io_throttle_data_length) && 4564 throttle_enabled_dev) { 4565 mpi3mr_atomic_sub(&sc->pend_large_data_sz, data_len_blks); 4566 ioc_pend_data_len = mpi3mr_atomic_read( 4567 &sc->pend_large_data_sz); 4568 if (tg) { 4569 mpi3mr_atomic_sub(&tg->pend_large_data_sz, 4570 data_len_blks); 4571 tg_pend_data_len = mpi3mr_atomic_read(&tg->pend_large_data_sz); 4572 if (ratelimit % 1000) { 4573 mpi3mr_dprint(sc, MPI3MR_IOT, 4574 "large vd_io completion persist_id(%d), handle(0x%04x), data_len(%d)," 4575 "ioc_pending(%d), tg_pending(%d), ioc_low(%d), tg_low(%d)\n", 4576 target->per_id, 4577 target->dev_handle, 4578 data_len_blks, ioc_pend_data_len, 4579 tg_pend_data_len, 4580 sc->io_throttle_low, 4581 tg->low); 4582 ratelimit++; 4583 } 4584 if (tg->io_divert && ((ioc_pend_data_len <= 4585 sc->io_throttle_low) && 4586 (tg_pend_data_len <= tg->low))) { 4587 tg->io_divert = 0; 4588 mpi3mr_dprint(sc, MPI3MR_IOT, 4589 "VD: Coming out of divert perst_id(%d) tg_id(%d)\n", 4590 target->per_id, tg->id); 4591 mpi3mr_set_io_divert_for_all_vd_in_tg( 4592 sc, tg, 0); 4593 } 4594 } else { 4595 if (ratelimit % 1000) { 4596 mpi3mr_dprint(sc, MPI3MR_IOT, 4597 "large pd_io completion persist_id(%d), handle(0x%04x), data_len(%d), ioc_pending(%d), ioc_low(%d)\n", 4598 target->per_id, 4599 target->dev_handle, 4600 data_len_blks, ioc_pend_data_len, 4601 sc->io_throttle_low); 4602 ratelimit++; 4603 } 4604 4605 if (ioc_pend_data_len <= sc->io_throttle_low) { 4606 target->io_divert = 0; 4607 mpi3mr_dprint(sc, MPI3MR_IOT, 4608 "PD: Coming out of divert perst_id(%d)\n", 4609 target->per_id); 4610 } 4611 } 4612 4613 } else if (target->io_divert) { 4614 ioc_pend_data_len = mpi3mr_atomic_read(&sc->pend_large_data_sz); 4615 if (!tg) { 4616 if (ratelimit % 1000) { 4617 mpi3mr_dprint(sc, MPI3MR_IOT, 4618 "pd_io completion persist_id(%d), handle(0x%04x), data_len(%d), ioc_pending(%d), ioc_low(%d)\n", 4619 target->per_id, 4620 target->dev_handle, 4621 data_len_blks, ioc_pend_data_len, 4622 sc->io_throttle_low); 4623 ratelimit++; 4624 } 4625 4626 if ( ioc_pend_data_len <= sc->io_throttle_low) { 4627 mpi3mr_dprint(sc, MPI3MR_IOT, 4628 "PD: Coming out of divert perst_id(%d)\n", 4629 target->per_id); 4630 target->io_divert = 0; 4631 } 4632 4633 } else if (ioc_pend_data_len <= sc->io_throttle_low) { 4634 tg_pend_data_len = mpi3mr_atomic_read(&tg->pend_large_data_sz); 4635 if (ratelimit % 1000) { 4636 mpi3mr_dprint(sc, MPI3MR_IOT, 4637 "vd_io completion persist_id(%d), handle(0x%04x), data_len(%d)," 4638 "ioc_pending(%d), tg_pending(%d), ioc_low(%d), tg_low(%d)\n", 4639 target->per_id, 4640 target->dev_handle, 4641 data_len_blks, ioc_pend_data_len, 4642 tg_pend_data_len, 4643 sc->io_throttle_low, 4644 tg->low); 4645 ratelimit++; 4646 } 4647 if (tg->io_divert && (tg_pend_data_len <= tg->low)) { 4648 tg->io_divert = 0; 4649 mpi3mr_dprint(sc, MPI3MR_IOT, 4650 "VD: Coming out of divert perst_id(%d) tg_id(%d)\n", 4651 target->per_id, tg->id); 4652 mpi3mr_set_io_divert_for_all_vd_in_tg( 4653 sc, tg, 0); 4654 } 4655 4656 } 4657 } 4658 } 4659 4660 if (success_desc) { 4661 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 4662 goto out_success; 4663 } 4664 4665 if (ioc_status == MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN 4666 && xfer_count == 0 && (scsi_status == MPI3_SCSI_STATUS_BUSY || 4667 scsi_status == MPI3_SCSI_STATUS_RESERVATION_CONFLICT || 4668 scsi_status == MPI3_SCSI_STATUS_TASK_SET_FULL)) 4669 ioc_status = MPI3_IOCSTATUS_SUCCESS; 4670 4671 if ((sense_state == MPI3_SCSI_STATE_SENSE_VALID) && sense_count 4672 && sense_buf) { 4673 int sense_len, returned_sense_len; 4674 4675 returned_sense_len = min(le32toh(sense_count), 4676 sizeof(struct scsi_sense_data)); 4677 if (returned_sense_len < csio->sense_len) 4678 csio->sense_resid = csio->sense_len - 4679 returned_sense_len; 4680 else 4681 csio->sense_resid = 0; 4682 4683 sense_len = min(returned_sense_len, 4684 csio->sense_len - csio->sense_resid); 4685 bzero(&csio->sense_data, sizeof(csio->sense_data)); 4686 bcopy(sense_buf, &csio->sense_data, sense_len); 4687 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 4688 } 4689 4690 switch (ioc_status) { 4691 case MPI3_IOCSTATUS_BUSY: 4692 case MPI3_IOCSTATUS_INSUFFICIENT_RESOURCES: 4693 mpi3mr_set_ccbstatus(ccb, CAM_REQUEUE_REQ); 4694 break; 4695 case MPI3_IOCSTATUS_SCSI_DEVICE_NOT_THERE: 4696 /* 4697 * If devinfo is 0 this will be a volume. In that case don't 4698 * tell CAM that the volume is not there. We want volumes to 4699 * be enumerated until they are deleted/removed, not just 4700 * failed. 4701 */ 4702 if (cm->targ->devinfo == 0) 4703 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 4704 else 4705 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 4706 break; 4707 case MPI3_IOCSTATUS_SCSI_TASK_TERMINATED: 4708 case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED: 4709 case MPI3_IOCSTATUS_SCSI_EXT_TERMINATED: 4710 mpi3mr_set_ccbstatus(ccb, CAM_SCSI_BUSY); 4711 mpi3mr_dprint(sc, MPI3MR_TRACE, 4712 "func: %s line:%d tgt %u Hosttag %u loginfo %x\n", 4713 __func__, __LINE__, 4714 target_id, cm->hosttag, 4715 le32toh(scsi_reply->IOCLogInfo)); 4716 mpi3mr_dprint(sc, MPI3MR_TRACE, 4717 "SCSIStatus %x SCSIState %x xfercount %u\n", 4718 scsi_reply->SCSIStatus, scsi_reply->SCSIState, 4719 le32toh(xfer_count)); 4720 break; 4721 case MPI3_IOCSTATUS_SCSI_DATA_OVERRUN: 4722 /* resid is ignored for this condition */ 4723 csio->resid = 0; 4724 mpi3mr_set_ccbstatus(ccb, CAM_DATA_RUN_ERR); 4725 break; 4726 case MPI3_IOCSTATUS_SCSI_DATA_UNDERRUN: 4727 csio->resid = cm->length - le32toh(xfer_count); 4728 case MPI3_IOCSTATUS_SCSI_RECOVERED_ERROR: 4729 case MPI3_IOCSTATUS_SUCCESS: 4730 if ((scsi_reply->IOCStatus & MPI3_REPLY_DESCRIPT_STATUS_IOCSTATUS_STATUS_MASK) == 4731 MPI3_IOCSTATUS_SCSI_RECOVERED_ERROR) 4732 mpi3mr_dprint(sc, MPI3MR_XINFO, "func: %s line: %d recovered error\n", __func__, __LINE__); 4733 4734 /* Completion failed at the transport level. */ 4735 if (scsi_reply->SCSIState & (MPI3_SCSI_STATE_NO_SCSI_STATUS | 4736 MPI3_SCSI_STATE_TERMINATED)) { 4737 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); 4738 break; 4739 } 4740 4741 /* In a modern packetized environment, an autosense failure 4742 * implies that there's not much else that can be done to 4743 * recover the command. 4744 */ 4745 if (scsi_reply->SCSIState & MPI3_SCSI_STATE_SENSE_VALID) { 4746 mpi3mr_set_ccbstatus(ccb, CAM_AUTOSENSE_FAIL); 4747 break; 4748 } 4749 4750 /* 4751 * Intentionally override the normal SCSI status reporting 4752 * for these two cases. These are likely to happen in a 4753 * multi-initiator environment, and we want to make sure that 4754 * CAM retries these commands rather than fail them. 4755 */ 4756 if ((scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_COMMAND_TERMINATED) || 4757 (scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_TASK_ABORTED)) { 4758 mpi3mr_set_ccbstatus(ccb, CAM_REQ_ABORTED); 4759 break; 4760 } 4761 4762 /* Handle normal status and sense */ 4763 csio->scsi_status = scsi_reply->SCSIStatus; 4764 if (scsi_reply->SCSIStatus == MPI3_SCSI_STATUS_GOOD) 4765 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 4766 else 4767 mpi3mr_set_ccbstatus(ccb, CAM_SCSI_STATUS_ERROR); 4768 4769 if (scsi_reply->SCSIState & MPI3_SCSI_STATE_SENSE_VALID) { 4770 int sense_len, returned_sense_len; 4771 4772 returned_sense_len = min(le32toh(scsi_reply->SenseCount), 4773 sizeof(struct scsi_sense_data)); 4774 if (returned_sense_len < csio->sense_len) 4775 csio->sense_resid = csio->sense_len - 4776 returned_sense_len; 4777 else 4778 csio->sense_resid = 0; 4779 4780 sense_len = min(returned_sense_len, 4781 csio->sense_len - csio->sense_resid); 4782 bzero(&csio->sense_data, sizeof(csio->sense_data)); 4783 bcopy(cm->sense, &csio->sense_data, sense_len); 4784 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 4785 } 4786 4787 break; 4788 case MPI3_IOCSTATUS_INVALID_SGL: 4789 mpi3mr_set_ccbstatus(ccb, CAM_UNREC_HBA_ERROR); 4790 break; 4791 case MPI3_IOCSTATUS_EEDP_GUARD_ERROR: 4792 case MPI3_IOCSTATUS_EEDP_REF_TAG_ERROR: 4793 case MPI3_IOCSTATUS_EEDP_APP_TAG_ERROR: 4794 case MPI3_IOCSTATUS_SCSI_PROTOCOL_ERROR: 4795 case MPI3_IOCSTATUS_INVALID_FUNCTION: 4796 case MPI3_IOCSTATUS_INTERNAL_ERROR: 4797 case MPI3_IOCSTATUS_INVALID_FIELD: 4798 case MPI3_IOCSTATUS_INVALID_STATE: 4799 case MPI3_IOCSTATUS_SCSI_IO_DATA_ERROR: 4800 case MPI3_IOCSTATUS_SCSI_TASK_MGMT_FAILED: 4801 case MPI3_IOCSTATUS_INSUFFICIENT_POWER: 4802 case MPI3_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: 4803 default: 4804 csio->resid = cm->length; 4805 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); 4806 break; 4807 } 4808 4809 out_success: 4810 if (mpi3mr_get_ccbstatus(ccb) != CAM_REQ_CMP) { 4811 ccb->ccb_h.status |= CAM_DEV_QFRZN; 4812 xpt_freeze_devq(ccb->ccb_h.path, /*count*/ 1); 4813 } 4814 4815 mpi3mr_atomic_dec(&cm->targ->outstanding); 4816 mpi3mr_cmd_done(sc, cm); 4817 mpi3mr_dprint(sc, MPI3MR_TRACE, "Completion IO path :" 4818 " cdb[0]: %x targetid: 0x%x SMID: %x ioc_status: 0x%x ioc_loginfo: 0x%x scsi_status: 0x%x " 4819 "scsi_state: 0x%x response_data: 0x%x\n", scsi_cdb[0], target_id, host_tag, 4820 ioc_status, ioc_loginfo, scsi_status, scsi_state, resp_data); 4821 mpi3mr_atomic_dec(&sc->fw_outstanding); 4822 out: 4823 4824 if (sense_buf) 4825 mpi3mr_repost_sense_buf(sc, 4826 scsi_reply->SenseDataBufferAddress); 4827 return; 4828 } 4829 4830 /* 4831 * mpi3mr_complete_io_cmd: ISR routine for IO commands 4832 * @sc: Adapter's soft instance 4833 * @irq_ctx: Driver's internal per IRQ structure 4834 * 4835 * This function processes IO command completions. 4836 */ 4837 int mpi3mr_complete_io_cmd(struct mpi3mr_softc *sc, 4838 struct mpi3mr_irq_context *irq_ctx) 4839 { 4840 struct mpi3mr_op_reply_queue *op_reply_q = irq_ctx->op_reply_q; 4841 U32 exp_phase = op_reply_q->ephase; 4842 U32 reply_ci = op_reply_q->ci; 4843 U32 num_op_replies = 0; 4844 U64 reply_dma = 0; 4845 Mpi3DefaultReplyDescriptor_t *reply_desc; 4846 U16 req_qid = 0, threshold_comps = 0; 4847 4848 mtx_lock_spin(&op_reply_q->q_lock); 4849 if (op_reply_q->in_use == false) { 4850 op_reply_q->in_use = true; 4851 mtx_unlock_spin(&op_reply_q->q_lock); 4852 } else { 4853 mtx_unlock_spin(&op_reply_q->q_lock); 4854 return 0; 4855 } 4856 4857 reply_desc = (Mpi3DefaultReplyDescriptor_t *)op_reply_q->q_base + reply_ci; 4858 mpi3mr_dprint(sc, MPI3MR_TRACE, "[QID:%d]:reply_desc: (%pa) reply_ci: %x" 4859 " reply_desc->ReplyFlags: 0x%x\n" 4860 "reply_q_base_phys: %#016jx reply_q_base: (%pa) exp_phase: %x\n", 4861 op_reply_q->qid, reply_desc, reply_ci, reply_desc->ReplyFlags, op_reply_q->q_base_phys, 4862 op_reply_q->q_base, exp_phase); 4863 4864 if (((reply_desc->ReplyFlags & 4865 MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) || !op_reply_q->qid) { 4866 mtx_lock_spin(&op_reply_q->q_lock); 4867 op_reply_q->in_use = false; 4868 mtx_unlock_spin(&op_reply_q->q_lock); 4869 return 0; 4870 } 4871 4872 do { 4873 req_qid = reply_desc->RequestQueueID; 4874 sc->op_req_q[req_qid - 1].ci = 4875 reply_desc->RequestQueueCI; 4876 4877 mpi3mr_process_op_reply_desc(sc, reply_desc, &reply_dma); 4878 mpi3mr_atomic_dec(&op_reply_q->pend_ios); 4879 if (reply_dma) 4880 mpi3mr_repost_reply_buf(sc, reply_dma); 4881 num_op_replies++; 4882 if (++reply_ci == op_reply_q->num_replies) { 4883 reply_ci = 0; 4884 exp_phase ^= 1; 4885 } 4886 reply_desc = 4887 (Mpi3DefaultReplyDescriptor_t *)op_reply_q->q_base + reply_ci; 4888 if ((reply_desc->ReplyFlags & 4889 MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) 4890 break; 4891 4892 if (++threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) { 4893 mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REPLY_Q_N_CI_OFFSET(op_reply_q->qid), reply_ci); 4894 threshold_comps = 0; 4895 } 4896 4897 } while (1); 4898 4899 4900 mpi3mr_regwrite(sc, MPI3_SYSIF_OPER_REPLY_Q_N_CI_OFFSET(op_reply_q->qid), reply_ci); 4901 op_reply_q->ci = reply_ci; 4902 op_reply_q->ephase = exp_phase; 4903 mtx_lock_spin(&op_reply_q->q_lock); 4904 op_reply_q->in_use = false; 4905 mtx_unlock_spin(&op_reply_q->q_lock); 4906 return num_op_replies; 4907 } 4908 4909 /* 4910 * mpi3mr_isr: Primary ISR function 4911 * privdata: Driver's internal per IRQ structure 4912 * 4913 * This is driver's primary ISR function which is being called whenever any admin/IO 4914 * command completion. 4915 */ 4916 void mpi3mr_isr(void *privdata) 4917 { 4918 struct mpi3mr_irq_context *irq_ctx = (struct mpi3mr_irq_context *)privdata; 4919 struct mpi3mr_softc *sc = irq_ctx->sc; 4920 U16 msi_idx; 4921 4922 if (!irq_ctx) 4923 return; 4924 4925 msi_idx = irq_ctx->msix_index; 4926 4927 if (!sc->intr_enabled) 4928 return; 4929 4930 if (!msi_idx) 4931 mpi3mr_complete_admin_cmd(sc); 4932 4933 if (irq_ctx->op_reply_q && irq_ctx->op_reply_q->qid) { 4934 mpi3mr_complete_io_cmd(sc, irq_ctx); 4935 } 4936 } 4937 4938 /* 4939 * mpi3mr_alloc_requests - Allocates host commands 4940 * @sc: Adapter reference 4941 * 4942 * This function allocates controller supported host commands 4943 * 4944 * Return: 0 on success and proper error codes on failure 4945 */ 4946 int 4947 mpi3mr_alloc_requests(struct mpi3mr_softc *sc) 4948 { 4949 struct mpi3mr_cmd *cmd; 4950 int i, j, nsegs, ret; 4951 4952 nsegs = MPI3MR_SG_DEPTH; 4953 ret = bus_dma_tag_create( sc->mpi3mr_parent_dmat, /* parent */ 4954 1, 0, /* algnmnt, boundary */ 4955 sc->dma_loaddr, /* lowaddr */ 4956 BUS_SPACE_MAXADDR, /* highaddr */ 4957 NULL, NULL, /* filter, filterarg */ 4958 BUS_SPACE_MAXSIZE, /* maxsize */ 4959 nsegs, /* nsegments */ 4960 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 4961 BUS_DMA_ALLOCNOW, /* flags */ 4962 busdma_lock_mutex, /* lockfunc */ 4963 &sc->io_lock, /* lockarg */ 4964 &sc->buffer_dmat); 4965 if (ret) { 4966 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate buffer DMA tag ret: %d\n", ret); 4967 return (ENOMEM); 4968 } 4969 4970 /* 4971 * sc->cmd_list is an array of struct mpi3mr_cmd pointers. 4972 * Allocate the dynamic array first and then allocate individual 4973 * commands. 4974 */ 4975 sc->cmd_list = malloc(sizeof(struct mpi3mr_cmd *) * sc->max_host_ios, 4976 M_MPI3MR, M_NOWAIT | M_ZERO); 4977 4978 if (!sc->cmd_list) { 4979 device_printf(sc->mpi3mr_dev, "Cannot alloc memory for mpt_cmd_list.\n"); 4980 return (ENOMEM); 4981 } 4982 4983 for (i = 0; i < sc->max_host_ios; i++) { 4984 sc->cmd_list[i] = malloc(sizeof(struct mpi3mr_cmd), 4985 M_MPI3MR, M_NOWAIT | M_ZERO); 4986 if (!sc->cmd_list[i]) { 4987 for (j = 0; j < i; j++) 4988 free(sc->cmd_list[j], M_MPI3MR); 4989 free(sc->cmd_list, M_MPI3MR); 4990 sc->cmd_list = NULL; 4991 return (ENOMEM); 4992 } 4993 } 4994 4995 for (i = 1; i < sc->max_host_ios; i++) { 4996 cmd = sc->cmd_list[i]; 4997 cmd->hosttag = i; 4998 cmd->sc = sc; 4999 cmd->state = MPI3MR_CMD_STATE_BUSY; 5000 callout_init_mtx(&cmd->callout, &sc->mpi3mr_mtx, 0); 5001 cmd->ccb = NULL; 5002 TAILQ_INSERT_TAIL(&(sc->cmd_list_head), cmd, next); 5003 if (bus_dmamap_create(sc->buffer_dmat, 0, &cmd->dmamap)) 5004 return ENOMEM; 5005 } 5006 return (0); 5007 } 5008 5009 /* 5010 * mpi3mr_get_command: Get a coomand structure from free command pool 5011 * @sc: Adapter soft instance 5012 * Return: MPT command reference 5013 * 5014 * This function returns an MPT command to the caller. 5015 */ 5016 struct mpi3mr_cmd * 5017 mpi3mr_get_command(struct mpi3mr_softc *sc) 5018 { 5019 struct mpi3mr_cmd *cmd = NULL; 5020 5021 mtx_lock(&sc->cmd_pool_lock); 5022 if (!TAILQ_EMPTY(&sc->cmd_list_head)) { 5023 cmd = TAILQ_FIRST(&sc->cmd_list_head); 5024 TAILQ_REMOVE(&sc->cmd_list_head, cmd, next); 5025 } else { 5026 goto out; 5027 } 5028 5029 mpi3mr_dprint(sc, MPI3MR_TRACE, "Get command SMID: 0x%x\n", cmd->hosttag); 5030 5031 memset((uint8_t *)&cmd->io_request, 0, MPI3MR_AREQ_FRAME_SZ); 5032 cmd->data_dir = 0; 5033 cmd->ccb = NULL; 5034 cmd->targ = NULL; 5035 cmd->state = MPI3MR_CMD_STATE_BUSY; 5036 cmd->data = NULL; 5037 cmd->length = 0; 5038 out: 5039 mtx_unlock(&sc->cmd_pool_lock); 5040 return cmd; 5041 } 5042 5043 /* 5044 * mpi3mr_release_command: Return a cmd to free command pool 5045 * input: Command packet for return to free command pool 5046 * 5047 * This function returns an MPT command to the free command list. 5048 */ 5049 void 5050 mpi3mr_release_command(struct mpi3mr_cmd *cmd) 5051 { 5052 struct mpi3mr_softc *sc = cmd->sc; 5053 5054 mtx_lock(&sc->cmd_pool_lock); 5055 TAILQ_INSERT_HEAD(&(sc->cmd_list_head), cmd, next); 5056 cmd->state = MPI3MR_CMD_STATE_FREE; 5057 cmd->req_qidx = 0; 5058 mpi3mr_dprint(sc, MPI3MR_TRACE, "Release command SMID: 0x%x\n", cmd->hosttag); 5059 mtx_unlock(&sc->cmd_pool_lock); 5060 5061 return; 5062 } 5063 5064 /** 5065 * mpi3mr_free_ioctl_dma_memory - free memory for ioctl dma 5066 * @sc: Adapter instance reference 5067 * 5068 * Free the DMA memory allocated for IOCTL handling purpose. 5069 * 5070 * Return: None 5071 */ 5072 static void mpi3mr_free_ioctl_dma_memory(struct mpi3mr_softc *sc) 5073 { 5074 U16 i; 5075 struct dma_memory_desc *mem_desc; 5076 5077 for (i=0; i<MPI3MR_NUM_IOCTL_SGE; i++) { 5078 mem_desc = &sc->ioctl_sge[i]; 5079 if (mem_desc->addr && mem_desc->dma_addr) { 5080 bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap); 5081 bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap); 5082 mem_desc->addr = NULL; 5083 if (mem_desc->tag != NULL) 5084 bus_dma_tag_destroy(mem_desc->tag); 5085 } 5086 } 5087 5088 mem_desc = &sc->ioctl_chain_sge; 5089 if (mem_desc->addr && mem_desc->dma_addr) { 5090 bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap); 5091 bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap); 5092 mem_desc->addr = NULL; 5093 if (mem_desc->tag != NULL) 5094 bus_dma_tag_destroy(mem_desc->tag); 5095 } 5096 5097 mem_desc = &sc->ioctl_resp_sge; 5098 if (mem_desc->addr && mem_desc->dma_addr) { 5099 bus_dmamap_unload(mem_desc->tag, mem_desc->dmamap); 5100 bus_dmamem_free(mem_desc->tag, mem_desc->addr, mem_desc->dmamap); 5101 mem_desc->addr = NULL; 5102 if (mem_desc->tag != NULL) 5103 bus_dma_tag_destroy(mem_desc->tag); 5104 } 5105 5106 sc->ioctl_sges_allocated = false; 5107 } 5108 5109 /** 5110 * mpi3mr_alloc_ioctl_dma_memory - Alloc memory for ioctl dma 5111 * @sc: Adapter instance reference 5112 * 5113 * This function allocates dmaable memory required to handle the 5114 * application issued MPI3 IOCTL requests. 5115 * 5116 * Return: None 5117 */ 5118 void mpi3mr_alloc_ioctl_dma_memory(struct mpi3mr_softc *sc) 5119 { 5120 struct dma_memory_desc *mem_desc; 5121 U16 i; 5122 5123 for (i=0; i<MPI3MR_NUM_IOCTL_SGE; i++) { 5124 mem_desc = &sc->ioctl_sge[i]; 5125 mem_desc->size = MPI3MR_IOCTL_SGE_SIZE; 5126 5127 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 5128 4, 0, /* algnmnt, boundary */ 5129 sc->dma_loaddr, /* lowaddr */ 5130 BUS_SPACE_MAXADDR, /* highaddr */ 5131 NULL, NULL, /* filter, filterarg */ 5132 mem_desc->size, /* maxsize */ 5133 1, /* nsegments */ 5134 mem_desc->size, /* maxsegsize */ 5135 0, /* flags */ 5136 NULL, NULL, /* lockfunc, lockarg */ 5137 &mem_desc->tag)) { 5138 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 5139 goto out_failed; 5140 } 5141 5142 if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr, 5143 BUS_DMA_NOWAIT, &mem_desc->dmamap)) { 5144 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 5145 goto out_failed; 5146 } 5147 bzero(mem_desc->addr, mem_desc->size); 5148 bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size, 5149 mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT); 5150 5151 if (!mem_desc->addr) 5152 goto out_failed; 5153 } 5154 5155 mem_desc = &sc->ioctl_chain_sge; 5156 mem_desc->size = MPI3MR_4K_PGSZ; 5157 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 5158 4, 0, /* algnmnt, boundary */ 5159 sc->dma_loaddr, /* lowaddr */ 5160 BUS_SPACE_MAXADDR, /* highaddr */ 5161 NULL, NULL, /* filter, filterarg */ 5162 mem_desc->size, /* maxsize */ 5163 1, /* nsegments */ 5164 mem_desc->size, /* maxsegsize */ 5165 0, /* flags */ 5166 NULL, NULL, /* lockfunc, lockarg */ 5167 &mem_desc->tag)) { 5168 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 5169 goto out_failed; 5170 } 5171 5172 if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr, 5173 BUS_DMA_NOWAIT, &mem_desc->dmamap)) { 5174 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s: Cannot allocate replies memory\n", __func__); 5175 goto out_failed; 5176 } 5177 bzero(mem_desc->addr, mem_desc->size); 5178 bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size, 5179 mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT); 5180 5181 if (!mem_desc->addr) 5182 goto out_failed; 5183 5184 mem_desc = &sc->ioctl_resp_sge; 5185 mem_desc->size = MPI3MR_4K_PGSZ; 5186 if (bus_dma_tag_create(sc->mpi3mr_parent_dmat, /* parent */ 5187 4, 0, /* algnmnt, boundary */ 5188 sc->dma_loaddr, /* lowaddr */ 5189 BUS_SPACE_MAXADDR, /* highaddr */ 5190 NULL, NULL, /* filter, filterarg */ 5191 mem_desc->size, /* maxsize */ 5192 1, /* nsegments */ 5193 mem_desc->size, /* maxsegsize */ 5194 0, /* flags */ 5195 NULL, NULL, /* lockfunc, lockarg */ 5196 &mem_desc->tag)) { 5197 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate request DMA tag\n"); 5198 goto out_failed; 5199 } 5200 5201 if (bus_dmamem_alloc(mem_desc->tag, (void **)&mem_desc->addr, 5202 BUS_DMA_NOWAIT, &mem_desc->dmamap)) { 5203 mpi3mr_dprint(sc, MPI3MR_ERROR, "Cannot allocate replies memory\n"); 5204 goto out_failed; 5205 } 5206 bzero(mem_desc->addr, mem_desc->size); 5207 bus_dmamap_load(mem_desc->tag, mem_desc->dmamap, mem_desc->addr, mem_desc->size, 5208 mpi3mr_memaddr_cb, &mem_desc->dma_addr, BUS_DMA_NOWAIT); 5209 5210 if (!mem_desc->addr) 5211 goto out_failed; 5212 5213 sc->ioctl_sges_allocated = true; 5214 5215 return; 5216 out_failed: 5217 printf("cannot allocate DMA memory for the mpt commands" 5218 " from the applications, application interface for MPT command is disabled\n"); 5219 mpi3mr_free_ioctl_dma_memory(sc); 5220 } 5221 5222 void 5223 mpi3mr_destory_mtx(struct mpi3mr_softc *sc) 5224 { 5225 int i; 5226 struct mpi3mr_op_req_queue *op_req_q; 5227 struct mpi3mr_op_reply_queue *op_reply_q; 5228 5229 if (sc->admin_reply) { 5230 if (mtx_initialized(&sc->admin_reply_lock)) 5231 mtx_destroy(&sc->admin_reply_lock); 5232 } 5233 5234 if (sc->op_reply_q) { 5235 for(i = 0; i < sc->num_queues; i++) { 5236 op_reply_q = sc->op_reply_q + i; 5237 if (mtx_initialized(&op_reply_q->q_lock)) 5238 mtx_destroy(&op_reply_q->q_lock); 5239 } 5240 } 5241 5242 if (sc->op_req_q) { 5243 for(i = 0; i < sc->num_queues; i++) { 5244 op_req_q = sc->op_req_q + i; 5245 if (mtx_initialized(&op_req_q->q_lock)) 5246 mtx_destroy(&op_req_q->q_lock); 5247 } 5248 } 5249 5250 if (mtx_initialized(&sc->init_cmds.completion.lock)) 5251 mtx_destroy(&sc->init_cmds.completion.lock); 5252 5253 if (mtx_initialized(&sc->ioctl_cmds.completion.lock)) 5254 mtx_destroy(&sc->ioctl_cmds.completion.lock); 5255 5256 if (mtx_initialized(&sc->host_tm_cmds.completion.lock)) 5257 mtx_destroy(&sc->host_tm_cmds.completion.lock); 5258 5259 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { 5260 if (mtx_initialized(&sc->dev_rmhs_cmds[i].completion.lock)) 5261 mtx_destroy(&sc->dev_rmhs_cmds[i].completion.lock); 5262 } 5263 5264 if (mtx_initialized(&sc->reset_mutex)) 5265 mtx_destroy(&sc->reset_mutex); 5266 5267 if (mtx_initialized(&sc->target_lock)) 5268 mtx_destroy(&sc->target_lock); 5269 5270 if (mtx_initialized(&sc->fwevt_lock)) 5271 mtx_destroy(&sc->fwevt_lock); 5272 5273 if (mtx_initialized(&sc->cmd_pool_lock)) 5274 mtx_destroy(&sc->cmd_pool_lock); 5275 5276 if (mtx_initialized(&sc->reply_free_q_lock)) 5277 mtx_destroy(&sc->reply_free_q_lock); 5278 5279 if (mtx_initialized(&sc->sense_buf_q_lock)) 5280 mtx_destroy(&sc->sense_buf_q_lock); 5281 5282 if (mtx_initialized(&sc->chain_buf_lock)) 5283 mtx_destroy(&sc->chain_buf_lock); 5284 5285 if (mtx_initialized(&sc->admin_req_lock)) 5286 mtx_destroy(&sc->admin_req_lock); 5287 5288 if (mtx_initialized(&sc->mpi3mr_mtx)) 5289 mtx_destroy(&sc->mpi3mr_mtx); 5290 } 5291 5292 /** 5293 * mpi3mr_free_mem - Freeup adapter level data structures 5294 * @sc: Adapter reference 5295 * 5296 * Return: Nothing. 5297 */ 5298 void 5299 mpi3mr_free_mem(struct mpi3mr_softc *sc) 5300 { 5301 int i; 5302 struct mpi3mr_op_req_queue *op_req_q; 5303 struct mpi3mr_op_reply_queue *op_reply_q; 5304 struct mpi3mr_irq_context *irq_ctx; 5305 5306 if (sc->cmd_list) { 5307 for (i = 0; i < sc->max_host_ios; i++) { 5308 free(sc->cmd_list[i], M_MPI3MR); 5309 } 5310 free(sc->cmd_list, M_MPI3MR); 5311 sc->cmd_list = NULL; 5312 } 5313 5314 if (sc->pel_seq_number && sc->pel_seq_number_dma) { 5315 bus_dmamap_unload(sc->pel_seq_num_dmatag, sc->pel_seq_num_dmamap); 5316 bus_dmamem_free(sc->pel_seq_num_dmatag, sc->pel_seq_number, sc->pel_seq_num_dmamap); 5317 sc->pel_seq_number = NULL; 5318 if (sc->pel_seq_num_dmatag != NULL) 5319 bus_dma_tag_destroy(sc->pel_seq_num_dmatag); 5320 } 5321 5322 if (sc->throttle_groups) { 5323 free(sc->throttle_groups, M_MPI3MR); 5324 sc->throttle_groups = NULL; 5325 } 5326 5327 /* Free up operational queues*/ 5328 if (sc->op_req_q) { 5329 for (i = 0; i < sc->num_queues; i++) { 5330 op_req_q = sc->op_req_q + i; 5331 if (op_req_q->q_base && op_req_q->q_base_phys) { 5332 bus_dmamap_unload(op_req_q->q_base_tag, op_req_q->q_base_dmamap); 5333 bus_dmamem_free(op_req_q->q_base_tag, op_req_q->q_base, op_req_q->q_base_dmamap); 5334 op_req_q->q_base = NULL; 5335 if (op_req_q->q_base_tag != NULL) 5336 bus_dma_tag_destroy(op_req_q->q_base_tag); 5337 } 5338 } 5339 free(sc->op_req_q, M_MPI3MR); 5340 sc->op_req_q = NULL; 5341 } 5342 5343 if (sc->op_reply_q) { 5344 for (i = 0; i < sc->num_queues; i++) { 5345 op_reply_q = sc->op_reply_q + i; 5346 if (op_reply_q->q_base && op_reply_q->q_base_phys) { 5347 bus_dmamap_unload(op_reply_q->q_base_tag, op_reply_q->q_base_dmamap); 5348 bus_dmamem_free(op_reply_q->q_base_tag, op_reply_q->q_base, op_reply_q->q_base_dmamap); 5349 op_reply_q->q_base = NULL; 5350 if (op_reply_q->q_base_tag != NULL) 5351 bus_dma_tag_destroy(op_reply_q->q_base_tag); 5352 } 5353 } 5354 free(sc->op_reply_q, M_MPI3MR); 5355 sc->op_reply_q = NULL; 5356 } 5357 5358 /* Free up chain buffers*/ 5359 if (sc->chain_sgl_list) { 5360 for (i = 0; i < sc->chain_buf_count; i++) { 5361 if (sc->chain_sgl_list[i].buf && sc->chain_sgl_list[i].buf_phys) { 5362 bus_dmamap_unload(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf_dmamap); 5363 bus_dmamem_free(sc->chain_sgl_list_tag, sc->chain_sgl_list[i].buf, 5364 sc->chain_sgl_list[i].buf_dmamap); 5365 sc->chain_sgl_list[i].buf = NULL; 5366 } 5367 } 5368 if (sc->chain_sgl_list_tag != NULL) 5369 bus_dma_tag_destroy(sc->chain_sgl_list_tag); 5370 free(sc->chain_sgl_list, M_MPI3MR); 5371 sc->chain_sgl_list = NULL; 5372 } 5373 5374 if (sc->chain_bitmap) { 5375 free(sc->chain_bitmap, M_MPI3MR); 5376 sc->chain_bitmap = NULL; 5377 } 5378 5379 for (i = 0; i < sc->msix_count; i++) { 5380 irq_ctx = sc->irq_ctx + i; 5381 if (irq_ctx) 5382 irq_ctx->op_reply_q = NULL; 5383 } 5384 5385 /* Free reply_buf_tag */ 5386 if (sc->reply_buf && sc->reply_buf_phys) { 5387 bus_dmamap_unload(sc->reply_buf_tag, sc->reply_buf_dmamap); 5388 bus_dmamem_free(sc->reply_buf_tag, sc->reply_buf, 5389 sc->reply_buf_dmamap); 5390 sc->reply_buf = NULL; 5391 if (sc->reply_buf_tag != NULL) 5392 bus_dma_tag_destroy(sc->reply_buf_tag); 5393 } 5394 5395 /* Free reply_free_q_tag */ 5396 if (sc->reply_free_q && sc->reply_free_q_phys) { 5397 bus_dmamap_unload(sc->reply_free_q_tag, sc->reply_free_q_dmamap); 5398 bus_dmamem_free(sc->reply_free_q_tag, sc->reply_free_q, 5399 sc->reply_free_q_dmamap); 5400 sc->reply_free_q = NULL; 5401 if (sc->reply_free_q_tag != NULL) 5402 bus_dma_tag_destroy(sc->reply_free_q_tag); 5403 } 5404 5405 /* Free sense_buf_tag */ 5406 if (sc->sense_buf && sc->sense_buf_phys) { 5407 bus_dmamap_unload(sc->sense_buf_tag, sc->sense_buf_dmamap); 5408 bus_dmamem_free(sc->sense_buf_tag, sc->sense_buf, 5409 sc->sense_buf_dmamap); 5410 sc->sense_buf = NULL; 5411 if (sc->sense_buf_tag != NULL) 5412 bus_dma_tag_destroy(sc->sense_buf_tag); 5413 } 5414 5415 /* Free sense_buf_q_tag */ 5416 if (sc->sense_buf_q && sc->sense_buf_q_phys) { 5417 bus_dmamap_unload(sc->sense_buf_q_tag, sc->sense_buf_q_dmamap); 5418 bus_dmamem_free(sc->sense_buf_q_tag, sc->sense_buf_q, 5419 sc->sense_buf_q_dmamap); 5420 sc->sense_buf_q = NULL; 5421 if (sc->sense_buf_q_tag != NULL) 5422 bus_dma_tag_destroy(sc->sense_buf_q_tag); 5423 } 5424 5425 /* Free up internal(non-IO) commands*/ 5426 if (sc->init_cmds.reply) { 5427 free(sc->init_cmds.reply, M_MPI3MR); 5428 sc->init_cmds.reply = NULL; 5429 } 5430 5431 if (sc->ioctl_cmds.reply) { 5432 free(sc->ioctl_cmds.reply, M_MPI3MR); 5433 sc->ioctl_cmds.reply = NULL; 5434 } 5435 5436 if (sc->pel_cmds.reply) { 5437 free(sc->pel_cmds.reply, M_MPI3MR); 5438 sc->pel_cmds.reply = NULL; 5439 } 5440 5441 if (sc->pel_abort_cmd.reply) { 5442 free(sc->pel_abort_cmd.reply, M_MPI3MR); 5443 sc->pel_abort_cmd.reply = NULL; 5444 } 5445 5446 if (sc->host_tm_cmds.reply) { 5447 free(sc->host_tm_cmds.reply, M_MPI3MR); 5448 sc->host_tm_cmds.reply = NULL; 5449 } 5450 5451 if (sc->log_data_buffer) { 5452 free(sc->log_data_buffer, M_MPI3MR); 5453 sc->log_data_buffer = NULL; 5454 } 5455 5456 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { 5457 if (sc->dev_rmhs_cmds[i].reply) { 5458 free(sc->dev_rmhs_cmds[i].reply, M_MPI3MR); 5459 sc->dev_rmhs_cmds[i].reply = NULL; 5460 } 5461 } 5462 5463 for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) { 5464 if (sc->evtack_cmds[i].reply) { 5465 free(sc->evtack_cmds[i].reply, M_MPI3MR); 5466 sc->evtack_cmds[i].reply = NULL; 5467 } 5468 } 5469 5470 if (sc->removepend_bitmap) { 5471 free(sc->removepend_bitmap, M_MPI3MR); 5472 sc->removepend_bitmap = NULL; 5473 } 5474 5475 if (sc->devrem_bitmap) { 5476 free(sc->devrem_bitmap, M_MPI3MR); 5477 sc->devrem_bitmap = NULL; 5478 } 5479 5480 if (sc->evtack_cmds_bitmap) { 5481 free(sc->evtack_cmds_bitmap, M_MPI3MR); 5482 sc->evtack_cmds_bitmap = NULL; 5483 } 5484 5485 /* Free Admin reply*/ 5486 if (sc->admin_reply && sc->admin_reply_phys) { 5487 bus_dmamap_unload(sc->admin_reply_tag, sc->admin_reply_dmamap); 5488 bus_dmamem_free(sc->admin_reply_tag, sc->admin_reply, 5489 sc->admin_reply_dmamap); 5490 sc->admin_reply = NULL; 5491 if (sc->admin_reply_tag != NULL) 5492 bus_dma_tag_destroy(sc->admin_reply_tag); 5493 } 5494 5495 /* Free Admin request*/ 5496 if (sc->admin_req && sc->admin_req_phys) { 5497 bus_dmamap_unload(sc->admin_req_tag, sc->admin_req_dmamap); 5498 bus_dmamem_free(sc->admin_req_tag, sc->admin_req, 5499 sc->admin_req_dmamap); 5500 sc->admin_req = NULL; 5501 if (sc->admin_req_tag != NULL) 5502 bus_dma_tag_destroy(sc->admin_req_tag); 5503 } 5504 mpi3mr_free_ioctl_dma_memory(sc); 5505 5506 } 5507 5508 /** 5509 * mpi3mr_drv_cmd_comp_reset - Flush a internal driver command 5510 * @sc: Adapter instance reference 5511 * @cmdptr: Internal command tracker 5512 * 5513 * Complete an internal driver commands with state indicating it 5514 * is completed due to reset. 5515 * 5516 * Return: Nothing. 5517 */ 5518 static inline void mpi3mr_drv_cmd_comp_reset(struct mpi3mr_softc *sc, 5519 struct mpi3mr_drvr_cmd *cmdptr) 5520 { 5521 if (cmdptr->state & MPI3MR_CMD_PENDING) { 5522 cmdptr->state |= MPI3MR_CMD_RESET; 5523 cmdptr->state &= ~MPI3MR_CMD_PENDING; 5524 if (cmdptr->is_waiting) { 5525 complete(&cmdptr->completion); 5526 cmdptr->is_waiting = 0; 5527 } else if (cmdptr->callback) 5528 cmdptr->callback(sc, cmdptr); 5529 } 5530 } 5531 5532 /** 5533 * mpi3mr_flush_drv_cmds - Flush internal driver commands 5534 * @sc: Adapter instance reference 5535 * 5536 * Flush all internal driver commands post reset 5537 * 5538 * Return: Nothing. 5539 */ 5540 static void mpi3mr_flush_drv_cmds(struct mpi3mr_softc *sc) 5541 { 5542 int i = 0; 5543 struct mpi3mr_drvr_cmd *cmdptr; 5544 5545 cmdptr = &sc->init_cmds; 5546 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5547 5548 cmdptr = &sc->ioctl_cmds; 5549 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5550 5551 cmdptr = &sc->host_tm_cmds; 5552 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5553 5554 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) { 5555 cmdptr = &sc->dev_rmhs_cmds[i]; 5556 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5557 } 5558 5559 for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) { 5560 cmdptr = &sc->evtack_cmds[i]; 5561 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5562 } 5563 5564 cmdptr = &sc->pel_cmds; 5565 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5566 5567 cmdptr = &sc->pel_abort_cmd; 5568 mpi3mr_drv_cmd_comp_reset(sc, cmdptr); 5569 } 5570 5571 5572 /** 5573 * mpi3mr_memset_buffers - memset memory for a controller 5574 * @sc: Adapter instance reference 5575 * 5576 * clear all the memory allocated for a controller, typically 5577 * called post reset to reuse the memory allocated during the 5578 * controller init. 5579 * 5580 * Return: Nothing. 5581 */ 5582 static void mpi3mr_memset_buffers(struct mpi3mr_softc *sc) 5583 { 5584 U16 i; 5585 struct mpi3mr_throttle_group_info *tg; 5586 5587 memset(sc->admin_req, 0, sc->admin_req_q_sz); 5588 memset(sc->admin_reply, 0, sc->admin_reply_q_sz); 5589 5590 memset(sc->init_cmds.reply, 0, sc->reply_sz); 5591 memset(sc->ioctl_cmds.reply, 0, sc->reply_sz); 5592 memset(sc->host_tm_cmds.reply, 0, sc->reply_sz); 5593 memset(sc->pel_cmds.reply, 0, sc->reply_sz); 5594 memset(sc->pel_abort_cmd.reply, 0, sc->reply_sz); 5595 for (i = 0; i < MPI3MR_NUM_DEVRMCMD; i++) 5596 memset(sc->dev_rmhs_cmds[i].reply, 0, sc->reply_sz); 5597 for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++) 5598 memset(sc->evtack_cmds[i].reply, 0, sc->reply_sz); 5599 memset(sc->removepend_bitmap, 0, sc->dev_handle_bitmap_sz); 5600 memset(sc->devrem_bitmap, 0, sc->devrem_bitmap_sz); 5601 memset(sc->evtack_cmds_bitmap, 0, sc->evtack_cmds_bitmap_sz); 5602 5603 for (i = 0; i < sc->num_queues; i++) { 5604 sc->op_reply_q[i].qid = 0; 5605 sc->op_reply_q[i].ci = 0; 5606 sc->op_reply_q[i].num_replies = 0; 5607 sc->op_reply_q[i].ephase = 0; 5608 mpi3mr_atomic_set(&sc->op_reply_q[i].pend_ios, 0); 5609 memset(sc->op_reply_q[i].q_base, 0, sc->op_reply_q[i].qsz); 5610 5611 sc->op_req_q[i].ci = 0; 5612 sc->op_req_q[i].pi = 0; 5613 sc->op_req_q[i].num_reqs = 0; 5614 sc->op_req_q[i].qid = 0; 5615 sc->op_req_q[i].reply_qid = 0; 5616 memset(sc->op_req_q[i].q_base, 0, sc->op_req_q[i].qsz); 5617 } 5618 5619 mpi3mr_atomic_set(&sc->pend_large_data_sz, 0); 5620 if (sc->throttle_groups) { 5621 tg = sc->throttle_groups; 5622 for (i = 0; i < sc->num_io_throttle_group; i++, tg++) { 5623 tg->id = 0; 5624 tg->fw_qd = 0; 5625 tg->modified_qd = 0; 5626 tg->io_divert= 0; 5627 tg->high = 0; 5628 tg->low = 0; 5629 mpi3mr_atomic_set(&tg->pend_large_data_sz, 0); 5630 } 5631 } 5632 } 5633 5634 /** 5635 * mpi3mr_invalidate_devhandles -Invalidate device handles 5636 * @sc: Adapter instance reference 5637 * 5638 * Invalidate the device handles in the target device structures 5639 * . Called post reset prior to reinitializing the controller. 5640 * 5641 * Return: Nothing. 5642 */ 5643 static void mpi3mr_invalidate_devhandles(struct mpi3mr_softc *sc) 5644 { 5645 struct mpi3mr_target *target = NULL; 5646 5647 mtx_lock_spin(&sc->target_lock); 5648 TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) { 5649 if (target) { 5650 target->dev_handle = MPI3MR_INVALID_DEV_HANDLE; 5651 target->io_throttle_enabled = 0; 5652 target->io_divert = 0; 5653 target->throttle_group = NULL; 5654 } 5655 } 5656 mtx_unlock_spin(&sc->target_lock); 5657 } 5658 5659 /** 5660 * mpi3mr_rfresh_tgtdevs - Refresh target device exposure 5661 * @sc: Adapter instance reference 5662 * 5663 * This is executed post controller reset to identify any 5664 * missing devices during reset and remove from the upper layers 5665 * or expose any newly detected device to the upper layers. 5666 * 5667 * Return: Nothing. 5668 */ 5669 5670 static void mpi3mr_rfresh_tgtdevs(struct mpi3mr_softc *sc) 5671 { 5672 struct mpi3mr_target *target = NULL; 5673 struct mpi3mr_target *target_temp = NULL; 5674 5675 TAILQ_FOREACH_SAFE(target, &sc->cam_sc->tgt_list, tgt_next, target_temp) { 5676 if (target->dev_handle == MPI3MR_INVALID_DEV_HANDLE) { 5677 if (target->exposed_to_os) 5678 mpi3mr_remove_device_from_os(sc, target->dev_handle); 5679 mpi3mr_remove_device_from_list(sc, target, true); 5680 } else if (target->is_hidden && target->exposed_to_os) { 5681 mpi3mr_remove_device_from_os(sc, target->dev_handle); 5682 } 5683 } 5684 5685 TAILQ_FOREACH(target, &sc->cam_sc->tgt_list, tgt_next) { 5686 if ((target->dev_handle != MPI3MR_INVALID_DEV_HANDLE) && 5687 !target->is_hidden && !target->exposed_to_os) { 5688 mpi3mr_add_device(sc, target->per_id); 5689 } 5690 } 5691 5692 } 5693 5694 static void mpi3mr_flush_io(struct mpi3mr_softc *sc) 5695 { 5696 int i; 5697 struct mpi3mr_cmd *cmd = NULL; 5698 union ccb *ccb = NULL; 5699 5700 for (i = 0; i < sc->max_host_ios; i++) { 5701 cmd = sc->cmd_list[i]; 5702 5703 if (cmd && cmd->ccb) { 5704 if (cmd->callout_owner) { 5705 ccb = (union ccb *)(cmd->ccb); 5706 ccb->ccb_h.status = CAM_SCSI_BUS_RESET; 5707 mpi3mr_atomic_dec(&sc->fw_outstanding); 5708 mpi3mr_atomic_dec(&cmd->targ->outstanding); 5709 mpi3mr_cmd_done(sc, cmd); 5710 } else { 5711 cmd->ccb = NULL; 5712 mpi3mr_release_command(cmd); 5713 } 5714 } 5715 } 5716 } 5717 /** 5718 * mpi3mr_clear_reset_history - Clear reset history 5719 * @sc: Adapter instance reference 5720 * 5721 * Write the reset history bit in IOC Status to clear the bit, 5722 * if it is already set. 5723 * 5724 * Return: Nothing. 5725 */ 5726 static inline void mpi3mr_clear_reset_history(struct mpi3mr_softc *sc) 5727 { 5728 U32 ioc_status; 5729 5730 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 5731 if (ioc_status & MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) 5732 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_STATUS_OFFSET, ioc_status); 5733 } 5734 5735 /** 5736 * mpi3mr_set_diagsave - Set diag save bit for snapdump 5737 * @sc: Adapter reference 5738 * 5739 * Set diag save bit in IOC configuration register to enable 5740 * snapdump. 5741 * 5742 * Return: Nothing. 5743 */ 5744 static inline void mpi3mr_set_diagsave(struct mpi3mr_softc *sc) 5745 { 5746 U32 ioc_config; 5747 5748 ioc_config = 5749 mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 5750 ioc_config |= MPI3_SYSIF_IOC_CONFIG_DIAG_SAVE; 5751 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config); 5752 } 5753 5754 /** 5755 * mpi3mr_issue_reset - Issue reset to the controller 5756 * @sc: Adapter reference 5757 * @reset_type: Reset type 5758 * @reset_reason: Reset reason code 5759 * 5760 * Unlock the host diagnostic registers and write the specific 5761 * reset type to that, wait for reset acknowledgement from the 5762 * controller, if the reset is not successful retry for the 5763 * predefined number of times. 5764 * 5765 * Return: 0 on success, non-zero on failure. 5766 */ 5767 static int mpi3mr_issue_reset(struct mpi3mr_softc *sc, U16 reset_type, 5768 U32 reset_reason) 5769 { 5770 int retval = -1; 5771 U8 unlock_retry_count = 0; 5772 U32 host_diagnostic, ioc_status, ioc_config; 5773 U32 timeout = MPI3MR_RESET_ACK_TIMEOUT * 10; 5774 5775 if ((reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) && 5776 (reset_type != MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT)) 5777 return retval; 5778 if (sc->unrecoverable) 5779 return retval; 5780 5781 if (reset_reason == MPI3MR_RESET_FROM_FIRMWARE) { 5782 retval = 0; 5783 return retval; 5784 } 5785 5786 mpi3mr_dprint(sc, MPI3MR_INFO, "%s reset due to %s(0x%x)\n", 5787 mpi3mr_reset_type_name(reset_type), 5788 mpi3mr_reset_rc_name(reset_reason), reset_reason); 5789 5790 mpi3mr_clear_reset_history(sc); 5791 do { 5792 mpi3mr_dprint(sc, MPI3MR_INFO, 5793 "Write magic sequence to unlock host diag register (retry=%d)\n", 5794 ++unlock_retry_count); 5795 if (unlock_retry_count >= MPI3MR_HOSTDIAG_UNLOCK_RETRY_COUNT) { 5796 mpi3mr_dprint(sc, MPI3MR_ERROR, 5797 "%s reset failed! due to host diag register unlock failure" 5798 "host_diagnostic(0x%08x)\n", mpi3mr_reset_type_name(reset_type), 5799 host_diagnostic); 5800 sc->unrecoverable = 1; 5801 return retval; 5802 } 5803 5804 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5805 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_FLUSH); 5806 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5807 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_1ST); 5808 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5809 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_2ND); 5810 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5811 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_3RD); 5812 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5813 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_4TH); 5814 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5815 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_5TH); 5816 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5817 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_6TH); 5818 5819 DELAY(1000); /* delay in usec */ 5820 host_diagnostic = mpi3mr_regread(sc, MPI3_SYSIF_HOST_DIAG_OFFSET); 5821 mpi3mr_dprint(sc, MPI3MR_INFO, 5822 "wrote magic sequence: retry_count(%d), host_diagnostic(0x%08x)\n", 5823 unlock_retry_count, host_diagnostic); 5824 } while (!(host_diagnostic & MPI3_SYSIF_HOST_DIAG_DIAG_WRITE_ENABLE)); 5825 5826 mpi3mr_regwrite(sc, MPI3_SYSIF_SCRATCHPAD0_OFFSET, reset_reason); 5827 mpi3mr_regwrite(sc, MPI3_SYSIF_HOST_DIAG_OFFSET, host_diagnostic | reset_type); 5828 5829 if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET) { 5830 do { 5831 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 5832 if (ioc_status & 5833 MPI3_SYSIF_IOC_STATUS_RESET_HISTORY) { 5834 ioc_config = 5835 mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 5836 if (mpi3mr_soft_reset_success(ioc_status, 5837 ioc_config)) { 5838 mpi3mr_clear_reset_history(sc); 5839 retval = 0; 5840 break; 5841 } 5842 } 5843 DELAY(100 * 1000); 5844 } while (--timeout); 5845 } else if (reset_type == MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT) { 5846 do { 5847 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 5848 if (mpi3mr_diagfault_success(sc, ioc_status)) { 5849 retval = 0; 5850 break; 5851 } 5852 DELAY(100 * 1000); 5853 } while (--timeout); 5854 } 5855 5856 mpi3mr_regwrite(sc, MPI3_SYSIF_WRITE_SEQUENCE_OFFSET, 5857 MPI3_SYSIF_WRITE_SEQUENCE_KEY_VALUE_2ND); 5858 5859 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 5860 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 5861 5862 mpi3mr_dprint(sc, MPI3MR_INFO, 5863 "IOC Status/Config after %s reset is (0x%x)/(0x%x)\n", 5864 !retval ? "successful":"failed", ioc_status, 5865 ioc_config); 5866 5867 if (retval) 5868 sc->unrecoverable = 1; 5869 5870 return retval; 5871 } 5872 5873 inline void mpi3mr_cleanup_event_taskq(struct mpi3mr_softc *sc) 5874 { 5875 /* 5876 * Block the taskqueue before draining. This means any new tasks won't 5877 * be queued to the taskqueue worker thread. But it doesn't stop the 5878 * current workers that are running. taskqueue_drain waits for those 5879 * correctly in the case of thread backed taskqueues. The while loop 5880 * ensures that all taskqueue threads have finished their current tasks. 5881 */ 5882 taskqueue_block(sc->cam_sc->ev_tq); 5883 while (taskqueue_cancel(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task, NULL) != 0) { 5884 taskqueue_drain(sc->cam_sc->ev_tq, &sc->cam_sc->ev_task); 5885 } 5886 } 5887 5888 /** 5889 * mpi3mr_soft_reset_handler - Reset the controller 5890 * @sc: Adapter instance reference 5891 * @reset_reason: Reset reason code 5892 * @snapdump: snapdump enable/disbale bit 5893 * 5894 * This is an handler for recovering controller by issuing soft 5895 * reset or diag fault reset. This is a blocking function and 5896 * when one reset is executed if any other resets they will be 5897 * blocked. All IOCTLs/IO will be blocked during the reset. If 5898 * controller reset is successful then the controller will be 5899 * reinitalized, otherwise the controller will be marked as not 5900 * recoverable 5901 * 5902 * Return: 0 on success, non-zero on failure. 5903 */ 5904 int mpi3mr_soft_reset_handler(struct mpi3mr_softc *sc, 5905 U32 reset_reason, bool snapdump) 5906 { 5907 int retval = 0, i = 0; 5908 enum mpi3mr_iocstate ioc_state; 5909 5910 mpi3mr_dprint(sc, MPI3MR_INFO, "soft reset invoked: reason code: %s\n", 5911 mpi3mr_reset_rc_name(reset_reason)); 5912 5913 if ((reset_reason == MPI3MR_RESET_FROM_IOCTL) && 5914 (sc->reset.ioctl_reset_snapdump != true)) 5915 snapdump = false; 5916 5917 mpi3mr_dprint(sc, MPI3MR_INFO, 5918 "soft_reset_handler: wait if diag save is in progress\n"); 5919 while (sc->diagsave_timeout) 5920 DELAY(1000 * 1000); 5921 5922 ioc_state = mpi3mr_get_iocstate(sc); 5923 if (ioc_state == MRIOC_STATE_UNRECOVERABLE) { 5924 mpi3mr_dprint(sc, MPI3MR_ERROR, "controller is in unrecoverable state, exit\n"); 5925 sc->reset.type = MPI3MR_NO_RESET; 5926 sc->reset.reason = MPI3MR_DEFAULT_RESET_REASON; 5927 sc->reset.status = -1; 5928 sc->reset.ioctl_reset_snapdump = false; 5929 return -1; 5930 } 5931 5932 if (sc->reset_in_progress) { 5933 mpi3mr_dprint(sc, MPI3MR_INFO, "reset is already in progress, exit\n"); 5934 return -1; 5935 } 5936 5937 /* Pause IOs, drain and block the event taskqueue */ 5938 xpt_freeze_simq(sc->cam_sc->sim, 1); 5939 5940 mpi3mr_cleanup_event_taskq(sc); 5941 5942 sc->reset_in_progress = 1; 5943 sc->block_ioctls = 1; 5944 5945 while (mpi3mr_atomic_read(&sc->pend_ioctls) && (i < PEND_IOCTLS_COMP_WAIT_TIME)) { 5946 ioc_state = mpi3mr_get_iocstate(sc); 5947 if (ioc_state == MRIOC_STATE_FAULT) 5948 break; 5949 i++; 5950 if (!(i % 5)) { 5951 mpi3mr_dprint(sc, MPI3MR_INFO, 5952 "[%2ds]waiting for IOCTL to be finished from %s\n", i, __func__); 5953 } 5954 DELAY(1000 * 1000); 5955 } 5956 5957 if ((!snapdump) && (reset_reason != MPI3MR_RESET_FROM_FAULT_WATCH) && 5958 (reset_reason != MPI3MR_RESET_FROM_FIRMWARE) && 5959 (reset_reason != MPI3MR_RESET_FROM_CIACTIV_FAULT)) { 5960 5961 mpi3mr_dprint(sc, MPI3MR_INFO, "Turn off events prior to reset\n"); 5962 5963 for (i = 0; i < MPI3_EVENT_NOTIFY_EVENTMASK_WORDS; i++) 5964 sc->event_masks[i] = -1; 5965 mpi3mr_issue_event_notification(sc); 5966 } 5967 5968 mpi3mr_disable_interrupts(sc); 5969 5970 if (snapdump) 5971 mpi3mr_trigger_snapdump(sc, reset_reason); 5972 5973 retval = mpi3mr_issue_reset(sc, 5974 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, reset_reason); 5975 if (retval) { 5976 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to issue soft reset to the ioc\n"); 5977 goto out; 5978 } 5979 5980 mpi3mr_flush_drv_cmds(sc); 5981 mpi3mr_flush_io(sc); 5982 mpi3mr_invalidate_devhandles(sc); 5983 mpi3mr_memset_buffers(sc); 5984 5985 if (sc->prepare_for_reset) { 5986 sc->prepare_for_reset = 0; 5987 sc->prepare_for_reset_timeout_counter = 0; 5988 } 5989 5990 retval = mpi3mr_initialize_ioc(sc, MPI3MR_INIT_TYPE_RESET); 5991 if (retval) { 5992 mpi3mr_dprint(sc, MPI3MR_ERROR, "reinit after soft reset failed: reason %d\n", 5993 reset_reason); 5994 goto out; 5995 } 5996 5997 DELAY((1000 * 1000) * 10); 5998 out: 5999 if (!retval) { 6000 sc->diagsave_timeout = 0; 6001 sc->reset_in_progress = 0; 6002 mpi3mr_rfresh_tgtdevs(sc); 6003 sc->ts_update_counter = 0; 6004 sc->block_ioctls = 0; 6005 sc->pel_abort_requested = 0; 6006 if (sc->pel_wait_pend) { 6007 sc->pel_cmds.retry_count = 0; 6008 mpi3mr_issue_pel_wait(sc, &sc->pel_cmds); 6009 mpi3mr_app_send_aen(sc); 6010 } 6011 } else { 6012 mpi3mr_issue_reset(sc, 6013 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_DIAG_FAULT, reset_reason); 6014 sc->unrecoverable = 1; 6015 sc->reset_in_progress = 0; 6016 } 6017 6018 mpi3mr_dprint(sc, MPI3MR_INFO, "Soft Reset: %s\n", ((retval == 0) ? "SUCCESS" : "FAILED")); 6019 6020 taskqueue_unblock(sc->cam_sc->ev_tq); 6021 xpt_release_simq(sc->cam_sc->sim, 1); 6022 6023 sc->reset.type = MPI3MR_NO_RESET; 6024 sc->reset.reason = MPI3MR_DEFAULT_RESET_REASON; 6025 sc->reset.status = retval; 6026 sc->reset.ioctl_reset_snapdump = false; 6027 6028 return retval; 6029 } 6030 6031 /** 6032 * mpi3mr_issue_ioc_shutdown - shutdown controller 6033 * @sc: Adapter instance reference 6034 * 6035 * Send shutodwn notification to the controller and wait for the 6036 * shutdown_timeout for it to be completed. 6037 * 6038 * Return: Nothing. 6039 */ 6040 static void mpi3mr_issue_ioc_shutdown(struct mpi3mr_softc *sc) 6041 { 6042 U32 ioc_config, ioc_status; 6043 U8 retval = 1, retry = 0; 6044 U32 timeout = MPI3MR_DEFAULT_SHUTDOWN_TIME * 10; 6045 6046 mpi3mr_dprint(sc, MPI3MR_INFO, "sending shutdown notification\n"); 6047 if (sc->unrecoverable) { 6048 mpi3mr_dprint(sc, MPI3MR_ERROR, 6049 "controller is unrecoverable, shutdown not issued\n"); 6050 return; 6051 } 6052 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 6053 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK) 6054 == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_IN_PROGRESS) { 6055 mpi3mr_dprint(sc, MPI3MR_ERROR, "shutdown already in progress\n"); 6056 return; 6057 } 6058 6059 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 6060 ioc_config |= MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL; 6061 ioc_config |= MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; 6062 6063 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config); 6064 6065 if (sc->facts.shutdown_timeout) 6066 timeout = sc->facts.shutdown_timeout * 10; 6067 6068 do { 6069 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 6070 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK) 6071 == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_COMPLETE) { 6072 retval = 0; 6073 break; 6074 } 6075 6076 if (sc->unrecoverable) 6077 break; 6078 6079 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_FAULT)) { 6080 mpi3mr_print_fault_info(sc); 6081 6082 if (retry >= MPI3MR_MAX_SHUTDOWN_RETRY_COUNT) 6083 break; 6084 6085 if (mpi3mr_issue_reset(sc, 6086 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, 6087 MPI3MR_RESET_FROM_CTLR_CLEANUP)) 6088 break; 6089 6090 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 6091 ioc_config |= MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL; 6092 ioc_config |= MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; 6093 6094 mpi3mr_regwrite(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET, ioc_config); 6095 6096 if (sc->facts.shutdown_timeout) 6097 timeout = sc->facts.shutdown_timeout * 10; 6098 6099 retry++; 6100 } 6101 6102 DELAY(100 * 1000); 6103 6104 } while (--timeout); 6105 6106 ioc_status = mpi3mr_regread(sc, MPI3_SYSIF_IOC_STATUS_OFFSET); 6107 ioc_config = mpi3mr_regread(sc, MPI3_SYSIF_IOC_CONFIG_OFFSET); 6108 6109 if (retval) { 6110 if ((ioc_status & MPI3_SYSIF_IOC_STATUS_SHUTDOWN_MASK) 6111 == MPI3_SYSIF_IOC_STATUS_SHUTDOWN_IN_PROGRESS) 6112 mpi3mr_dprint(sc, MPI3MR_ERROR, 6113 "shutdown still in progress after timeout\n"); 6114 } 6115 6116 mpi3mr_dprint(sc, MPI3MR_INFO, 6117 "ioc_status/ioc_config after %s shutdown is (0x%x)/(0x%x)\n", 6118 (!retval)?"successful":"failed", ioc_status, 6119 ioc_config); 6120 } 6121 6122 /** 6123 * mpi3mr_cleanup_ioc - Cleanup controller 6124 * @sc: Adapter instance reference 6125 6126 * controller cleanup handler, Message unit reset or soft reset 6127 * and shutdown notification is issued to the controller. 6128 * 6129 * Return: Nothing. 6130 */ 6131 void mpi3mr_cleanup_ioc(struct mpi3mr_softc *sc) 6132 { 6133 enum mpi3mr_iocstate ioc_state; 6134 6135 mpi3mr_dprint(sc, MPI3MR_INFO, "cleaning up the controller\n"); 6136 mpi3mr_disable_interrupts(sc); 6137 6138 ioc_state = mpi3mr_get_iocstate(sc); 6139 6140 if ((!sc->unrecoverable) && (!sc->reset_in_progress) && 6141 (ioc_state == MRIOC_STATE_READY)) { 6142 if (mpi3mr_mur_ioc(sc, 6143 MPI3MR_RESET_FROM_CTLR_CLEANUP)) 6144 mpi3mr_issue_reset(sc, 6145 MPI3_SYSIF_HOST_DIAG_RESET_ACTION_SOFT_RESET, 6146 MPI3MR_RESET_FROM_MUR_FAILURE); 6147 mpi3mr_issue_ioc_shutdown(sc); 6148 } 6149 6150 mpi3mr_dprint(sc, MPI3MR_INFO, "controller cleanup completed\n"); 6151 } 6152