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