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