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