1 /* 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2020-2023, Broadcom Inc. All rights reserved. 5 * Support: <[email protected]> 6 * 7 * Authors: Sumit Saxena <[email protected]> 8 * Chandrakanth Patil <[email protected]> 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions are 12 * met: 13 * 14 * 1. Redistributions of source code must retain the above copyright notice, 15 * this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright notice, 17 * this list of conditions and the following disclaimer in the documentation and/or other 18 * materials provided with the distribution. 19 * 3. Neither the name of the Broadcom Inc. nor the names of its contributors 20 * may be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 * 35 * The views and conclusions contained in the software and documentation are 36 * those of the authors and should not be interpreted as representing 37 * official policies,either expressed or implied, of the FreeBSD Project. 38 * 39 * Mail to: Broadcom Inc 1320 Ridder Park Dr, San Jose, CA 95131 40 * 41 * Broadcom Inc. (Broadcom) MPI3MR Adapter FreeBSD 42 */ 43 44 #include <sys/cdefs.h> 45 #include <sys/types.h> 46 #include <sys/param.h> 47 #include <sys/systm.h> 48 #include <sys/kernel.h> 49 #include <sys/selinfo.h> 50 #include <sys/module.h> 51 #include <sys/bus.h> 52 #include <sys/conf.h> 53 #include <sys/bio.h> 54 #include <sys/malloc.h> 55 #include <sys/uio.h> 56 #include <sys/sysctl.h> 57 #include <sys/endian.h> 58 #include <sys/queue.h> 59 #include <sys/kthread.h> 60 #include <sys/taskqueue.h> 61 #include <sys/sbuf.h> 62 63 #include <machine/bus.h> 64 #include <machine/resource.h> 65 #include <sys/rman.h> 66 67 #include <machine/stdarg.h> 68 69 #include <cam/cam.h> 70 #include <cam/cam_ccb.h> 71 #include <cam/cam_debug.h> 72 #include <cam/cam_sim.h> 73 #include <cam/cam_xpt_sim.h> 74 #include <cam/cam_xpt_periph.h> 75 #include <cam/cam_periph.h> 76 #include <cam/scsi/scsi_all.h> 77 #include <cam/scsi/scsi_message.h> 78 #include <cam/scsi/smp_all.h> 79 80 #include <dev/nvme/nvme.h> 81 #include "mpi/mpi30_api.h" 82 #include "mpi3mr_cam.h" 83 #include "mpi3mr.h" 84 #include <sys/time.h> /* XXX for pcpu.h */ 85 #include <sys/pcpu.h> /* XXX for PCPU_GET */ 86 87 #define smp_processor_id() PCPU_GET(cpuid) 88 89 static void 90 mpi3mr_enqueue_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); 91 static void 92 mpi3mr_map_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm); 93 void 94 mpi3mr_release_simq_reinit(struct mpi3mr_cam_softc *cam_sc); 95 static void 96 mpi3mr_freeup_events(struct mpi3mr_softc *sc); 97 98 extern int 99 mpi3mr_register_events(struct mpi3mr_softc *sc); 100 extern void mpi3mr_add_sg_single(void *paddr, U8 flags, U32 length, 101 bus_addr_t dma_addr); 102 103 static U32 event_count; 104 105 static void mpi3mr_prepare_sgls(void *arg, 106 bus_dma_segment_t *segs, int nsegs, int error) 107 { 108 struct mpi3mr_softc *sc; 109 struct mpi3mr_cmd *cm; 110 u_int i; 111 bus_addr_t chain_dma; 112 void *chain; 113 U8 *sg_local; 114 U32 chain_length; 115 int sges_left; 116 U32 sges_in_segment; 117 U8 simple_sgl_flags; 118 U8 simple_sgl_flags_last; 119 U8 last_chain_sgl_flags; 120 struct mpi3mr_chain *chain_req; 121 Mpi3SCSIIORequest_t *scsiio_req; 122 union ccb *ccb; 123 124 cm = (struct mpi3mr_cmd *)arg; 125 sc = cm->sc; 126 scsiio_req = (Mpi3SCSIIORequest_t *) &cm->io_request; 127 ccb = cm->ccb; 128 129 if (error) { 130 device_printf(sc->mpi3mr_dev, "%s: error=%d\n",__func__, error); 131 if (error == EFBIG) { 132 mpi3mr_set_ccbstatus(ccb, CAM_REQ_TOO_BIG); 133 } else { 134 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); 135 } 136 mpi3mr_release_command(cm); 137 xpt_done(ccb); 138 return; 139 } 140 141 if (cm->data_dir == MPI3MR_READ) 142 bus_dmamap_sync(sc->buffer_dmat, cm->dmamap, 143 BUS_DMASYNC_PREREAD); 144 if (cm->data_dir == MPI3MR_WRITE) 145 bus_dmamap_sync(sc->buffer_dmat, cm->dmamap, 146 BUS_DMASYNC_PREWRITE); 147 148 KASSERT(nsegs <= MPI3MR_SG_DEPTH && nsegs > 0, 149 ("%s: bad SGE count: %d\n", device_get_nameunit(sc->mpi3mr_dev), nsegs)); 150 KASSERT(scsiio_req->DataLength != 0, 151 ("%s: Data segments (%d), but DataLength == 0\n", 152 device_get_nameunit(sc->mpi3mr_dev), nsegs)); 153 154 simple_sgl_flags = MPI3_SGE_FLAGS_ELEMENT_TYPE_SIMPLE | 155 MPI3_SGE_FLAGS_DLAS_SYSTEM; 156 simple_sgl_flags_last = simple_sgl_flags | 157 MPI3_SGE_FLAGS_END_OF_LIST; 158 last_chain_sgl_flags = MPI3_SGE_FLAGS_ELEMENT_TYPE_LAST_CHAIN | 159 MPI3_SGE_FLAGS_DLAS_SYSTEM; 160 161 sg_local = (U8 *)&scsiio_req->SGL; 162 163 sges_left = nsegs; 164 165 sges_in_segment = (sc->facts.op_req_sz - 166 offsetof(Mpi3SCSIIORequest_t, SGL))/sizeof(Mpi3SGESimple_t); 167 168 i = 0; 169 170 mpi3mr_dprint(sc, MPI3MR_TRACE, "SGE count: %d IO size: %d\n", 171 nsegs, scsiio_req->DataLength); 172 173 if (sges_left <= sges_in_segment) 174 goto fill_in_last_segment; 175 176 /* fill in main message segment when there is a chain following */ 177 while (sges_in_segment > 1) { 178 mpi3mr_add_sg_single(sg_local, simple_sgl_flags, 179 segs[i].ds_len, segs[i].ds_addr); 180 sg_local += sizeof(Mpi3SGESimple_t); 181 sges_left--; 182 sges_in_segment--; 183 i++; 184 } 185 186 chain_req = &sc->chain_sgl_list[cm->hosttag]; 187 188 chain = chain_req->buf; 189 chain_dma = chain_req->buf_phys; 190 memset(chain_req->buf, 0, PAGE_SIZE); 191 sges_in_segment = sges_left; 192 chain_length = sges_in_segment * sizeof(Mpi3SGESimple_t); 193 194 mpi3mr_add_sg_single(sg_local, last_chain_sgl_flags, 195 chain_length, chain_dma); 196 197 sg_local = chain; 198 199 fill_in_last_segment: 200 while (sges_left > 0) { 201 if (sges_left == 1) 202 mpi3mr_add_sg_single(sg_local, 203 simple_sgl_flags_last, segs[i].ds_len, 204 segs[i].ds_addr); 205 else 206 mpi3mr_add_sg_single(sg_local, simple_sgl_flags, 207 segs[i].ds_len, segs[i].ds_addr); 208 sg_local += sizeof(Mpi3SGESimple_t); 209 sges_left--; 210 i++; 211 } 212 213 /* 214 * Now that we've created the sgls, we send the request to the device. 215 * Unlike in Linux, dmaload isn't guaranteed to load every time, but 216 * this function is always called when the resources are available, so 217 * we can send the request to hardware here always. mpi3mr_map_request 218 * knows about this quirk and will only take evasive action when an 219 * error other than EINPROGRESS is returned from dmaload. 220 */ 221 mpi3mr_enqueue_request(sc, cm); 222 223 return; 224 } 225 226 static void 227 mpi3mr_map_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm) 228 { 229 u_int32_t retcode = 0; 230 union ccb *ccb; 231 232 ccb = cm->ccb; 233 if (cm->data != NULL) { 234 mtx_lock(&sc->io_lock); 235 /* Map data buffer into bus space */ 236 retcode = bus_dmamap_load_ccb(sc->buffer_dmat, cm->dmamap, 237 ccb, mpi3mr_prepare_sgls, cm, 0); 238 mtx_unlock(&sc->io_lock); 239 if (retcode != 0 && retcode != EINPROGRESS) { 240 device_printf(sc->mpi3mr_dev, 241 "bus_dmamap_load(): retcode = %d\n", retcode); 242 /* 243 * Any other error means prepare_sgls wasn't called, and 244 * will never be called, so we have to mop up. This error 245 * should never happen, though. 246 */ 247 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP_ERR); 248 mpi3mr_release_command(cm); 249 xpt_done(ccb); 250 } 251 } else { 252 /* 253 * No data, we enqueue it directly here. 254 */ 255 mpi3mr_enqueue_request(sc, cm); 256 } 257 } 258 259 void 260 mpi3mr_unmap_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cmd) 261 { 262 if (cmd->data != NULL) { 263 if (cmd->data_dir == MPI3MR_READ) 264 bus_dmamap_sync(sc->buffer_dmat, cmd->dmamap, BUS_DMASYNC_POSTREAD); 265 if (cmd->data_dir == MPI3MR_WRITE) 266 bus_dmamap_sync(sc->buffer_dmat, cmd->dmamap, BUS_DMASYNC_POSTWRITE); 267 mtx_lock(&sc->io_lock); 268 bus_dmamap_unload(sc->buffer_dmat, cmd->dmamap); 269 mtx_unlock(&sc->io_lock); 270 } 271 } 272 273 /** 274 * mpi3mr_allow_unmap_to_fw - Whether an unmap is allowed to fw 275 * @sc: Adapter instance reference 276 * @ccb: SCSI Command reference 277 * 278 * The controller hardware cannot handle certain unmap commands 279 * for NVMe drives, this routine checks those and return true 280 * and completes the SCSI command with proper status and sense 281 * data. 282 * 283 * Return: TRUE for allowed unmap, FALSE otherwise. 284 */ 285 static bool mpi3mr_allow_unmap_to_fw(struct mpi3mr_softc *sc, 286 union ccb *ccb) 287 { 288 struct ccb_scsiio *csio; 289 uint16_t param_list_len, block_desc_len, trunc_param_len = 0; 290 291 csio = &ccb->csio; 292 param_list_len = (uint16_t) ((scsiio_cdb_ptr(csio)[7] << 8) | scsiio_cdb_ptr(csio)[8]); 293 294 switch(pci_get_revid(sc->mpi3mr_dev)) { 295 case SAS4116_CHIP_REV_A0: 296 if (!param_list_len) { 297 mpi3mr_dprint(sc, MPI3MR_ERROR, 298 "%s: CDB received with zero parameter length\n", 299 __func__); 300 mpi3mr_print_cdb(ccb); 301 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 302 xpt_done(ccb); 303 return false; 304 } 305 306 if (param_list_len < 24) { 307 mpi3mr_dprint(sc, MPI3MR_ERROR, 308 "%s: CDB received with invalid param_list_len: %d\n", 309 __func__, param_list_len); 310 mpi3mr_print_cdb(ccb); 311 scsi_set_sense_data(&ccb->csio.sense_data, 312 /*sense_format*/ SSD_TYPE_FIXED, 313 /*current_error*/ 1, 314 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 315 /*asc*/ 0x1A, 316 /*ascq*/ 0x00, 317 /*extra args*/ SSD_ELEM_NONE); 318 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 319 ccb->ccb_h.status = 320 CAM_SCSI_STATUS_ERROR | 321 CAM_AUTOSNS_VALID; 322 return false; 323 } 324 325 if (param_list_len != csio->dxfer_len) { 326 mpi3mr_dprint(sc, MPI3MR_ERROR, 327 "%s: CDB received with param_list_len: %d bufflen: %d\n", 328 __func__, param_list_len, csio->dxfer_len); 329 mpi3mr_print_cdb(ccb); 330 scsi_set_sense_data(&ccb->csio.sense_data, 331 /*sense_format*/ SSD_TYPE_FIXED, 332 /*current_error*/ 1, 333 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 334 /*asc*/ 0x1A, 335 /*ascq*/ 0x00, 336 /*extra args*/ SSD_ELEM_NONE); 337 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 338 ccb->ccb_h.status = 339 CAM_SCSI_STATUS_ERROR | 340 CAM_AUTOSNS_VALID; 341 xpt_done(ccb); 342 return false; 343 } 344 345 block_desc_len = (uint16_t) (csio->data_ptr[2] << 8 | csio->data_ptr[3]); 346 347 if (block_desc_len < 16) { 348 mpi3mr_dprint(sc, MPI3MR_ERROR, 349 "%s: Invalid descriptor length in param list: %d\n", 350 __func__, block_desc_len); 351 mpi3mr_print_cdb(ccb); 352 scsi_set_sense_data(&ccb->csio.sense_data, 353 /*sense_format*/ SSD_TYPE_FIXED, 354 /*current_error*/ 1, 355 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 356 /*asc*/ 0x26, 357 /*ascq*/ 0x00, 358 /*extra args*/ SSD_ELEM_NONE); 359 ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND; 360 ccb->ccb_h.status = 361 CAM_SCSI_STATUS_ERROR | 362 CAM_AUTOSNS_VALID; 363 xpt_done(ccb); 364 return false; 365 } 366 367 if (param_list_len > (block_desc_len + 8)) { 368 mpi3mr_print_cdb(ccb); 369 mpi3mr_dprint(sc, MPI3MR_INFO, 370 "%s: Truncating param_list_len(%d) to block_desc_len+8(%d)\n", 371 __func__, param_list_len, (block_desc_len + 8)); 372 param_list_len = block_desc_len + 8; 373 scsiio_cdb_ptr(csio)[7] = (param_list_len >> 8) | 0xff; 374 scsiio_cdb_ptr(csio)[8] = param_list_len | 0xff; 375 mpi3mr_print_cdb(ccb); 376 } 377 break; 378 379 case SAS4116_CHIP_REV_B0: 380 if ((param_list_len > 24) && ((param_list_len - 8) & 0xF)) { 381 trunc_param_len -= (param_list_len - 8) & 0xF; 382 mpi3mr_print_cdb(ccb); 383 mpi3mr_dprint(sc, MPI3MR_INFO, 384 "%s: Truncating param_list_len from (%d) to (%d)\n", 385 __func__, param_list_len, trunc_param_len); 386 scsiio_cdb_ptr(csio)[7] = (param_list_len >> 8) | 0xff; 387 scsiio_cdb_ptr(csio)[8] = param_list_len | 0xff; 388 mpi3mr_print_cdb(ccb); 389 } 390 break; 391 } 392 393 return true; 394 } 395 396 /** 397 * mpi3mr_tm_response_name - get TM response as a string 398 * @resp_code: TM response code 399 * 400 * Convert known task management response code as a readable 401 * string. 402 * 403 * Return: response code string. 404 */ 405 static const char* mpi3mr_tm_response_name(U8 resp_code) 406 { 407 char *desc; 408 409 switch (resp_code) { 410 case MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE: 411 desc = "task management request completed"; 412 break; 413 case MPI3_SCSITASKMGMT_RSPCODE_INVALID_FRAME: 414 desc = "invalid frame"; 415 break; 416 case MPI3_SCSITASKMGMT_RSPCODE_TM_FUNCTION_NOT_SUPPORTED: 417 desc = "task management request not supported"; 418 break; 419 case MPI3_SCSITASKMGMT_RSPCODE_TM_FAILED: 420 desc = "task management request failed"; 421 break; 422 case MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED: 423 desc = "task management request succeeded"; 424 break; 425 case MPI3_SCSITASKMGMT_RSPCODE_TM_INVALID_LUN: 426 desc = "invalid LUN"; 427 break; 428 case MPI3_SCSITASKMGMT_RSPCODE_TM_OVERLAPPED_TAG: 429 desc = "overlapped tag attempted"; 430 break; 431 case MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC: 432 desc = "task queued, however not sent to target"; 433 break; 434 case MPI3_SCSITASKMGMT_RSPCODE_TM_NVME_DENIED: 435 desc = "task management request denied by NVMe device"; 436 break; 437 default: 438 desc = "unknown"; 439 break; 440 } 441 442 return desc; 443 } 444 445 void mpi3mr_poll_pend_io_completions(struct mpi3mr_softc *sc) 446 { 447 int i; 448 int num_of_reply_queues = sc->num_queues; 449 struct mpi3mr_irq_context *irq_ctx; 450 451 for (i = 0; i < num_of_reply_queues; i++) { 452 irq_ctx = &sc->irq_ctx[i]; 453 mpi3mr_complete_io_cmd(sc, irq_ctx); 454 } 455 } 456 457 void 458 trigger_reset_from_watchdog(struct mpi3mr_softc *sc, U8 reset_type, U32 reset_reason) 459 { 460 if (sc->reset_in_progress) { 461 mpi3mr_dprint(sc, MPI3MR_INFO, "Another reset is in progress, no need to trigger the reset\n"); 462 return; 463 } 464 sc->reset.type = reset_type; 465 sc->reset.reason = reset_reason; 466 467 return; 468 } 469 470 /** 471 * mpi3mr_issue_tm - Issue Task Management request 472 * @sc: Adapter instance reference 473 * @tm_type: Task Management type 474 * @handle: Device handle 475 * @lun: lun ID 476 * @htag: Host tag of the TM request 477 * @timeout: TM timeout value 478 * @drv_cmd: Internal command tracker 479 * @resp_code: Response code place holder 480 * @cmd: Timed out command reference 481 * 482 * Issues a Task Management Request to the controller for a 483 * specified target, lun and command and wait for its completion 484 * and check TM response. Recover the TM if it timed out by 485 * issuing controller reset. 486 * 487 * Return: 0 on success, non-zero on errors 488 */ 489 static int 490 mpi3mr_issue_tm(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cmd, 491 U8 tm_type, unsigned long timeout) 492 { 493 int retval = 0; 494 MPI3_SCSI_TASK_MGMT_REQUEST tm_req; 495 MPI3_SCSI_TASK_MGMT_REPLY *tm_reply = NULL; 496 struct mpi3mr_drvr_cmd *drv_cmd = NULL; 497 struct mpi3mr_target *tgtdev = NULL; 498 struct mpi3mr_op_req_queue *op_req_q = NULL; 499 union ccb *ccb; 500 U8 resp_code; 501 502 503 if (sc->unrecoverable) { 504 mpi3mr_dprint(sc, MPI3MR_INFO, 505 "Controller is in unrecoverable state!! TM not required\n"); 506 return retval; 507 } 508 if (sc->reset_in_progress) { 509 mpi3mr_dprint(sc, MPI3MR_INFO, 510 "controller reset in progress!! TM not required\n"); 511 return retval; 512 } 513 514 if (!cmd->ccb) { 515 mpi3mr_dprint(sc, MPI3MR_ERROR, "SCSIIO command timed-out with NULL ccb\n"); 516 return retval; 517 } 518 ccb = cmd->ccb; 519 520 tgtdev = cmd->targ; 521 if (tgtdev == NULL) { 522 mpi3mr_dprint(sc, MPI3MR_ERROR, "Device does not exist target ID:0x%x," 523 "TM is not required\n", ccb->ccb_h.target_id); 524 return retval; 525 } 526 if (tgtdev->dev_removed == 1) { 527 mpi3mr_dprint(sc, MPI3MR_ERROR, "Device(0x%x) is removed, TM is not required\n", 528 ccb->ccb_h.target_id); 529 return retval; 530 } 531 532 drv_cmd = &sc->host_tm_cmds; 533 mtx_lock(&drv_cmd->lock); 534 535 memset(&tm_req, 0, sizeof(tm_req)); 536 tm_req.DevHandle = htole16(tgtdev->dev_handle); 537 tm_req.TaskType = tm_type; 538 tm_req.HostTag = htole16(MPI3MR_HOSTTAG_TMS); 539 int_to_lun(ccb->ccb_h.target_lun, tm_req.LUN); 540 tm_req.Function = MPI3_FUNCTION_SCSI_TASK_MGMT; 541 drv_cmd->state = MPI3MR_CMD_PENDING; 542 drv_cmd->is_waiting = 1; 543 drv_cmd->callback = NULL; 544 545 if (ccb) { 546 if (tm_type == MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { 547 op_req_q = &sc->op_req_q[cmd->req_qidx]; 548 tm_req.TaskHostTag = htole16(cmd->hosttag); 549 tm_req.TaskRequestQueueID = htole16(op_req_q->qid); 550 } 551 } 552 553 if (tgtdev) 554 mpi3mr_atomic_inc(&tgtdev->block_io); 555 556 if (tgtdev && (tgtdev->dev_type == MPI3_DEVICE_DEVFORM_PCIE)) { 557 if ((tm_type == MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK) 558 && tgtdev->dev_spec.pcie_inf.abort_to) 559 timeout = tgtdev->dev_spec.pcie_inf.abort_to; 560 else if ((tm_type == MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET) 561 && tgtdev->dev_spec.pcie_inf.reset_to) 562 timeout = tgtdev->dev_spec.pcie_inf.reset_to; 563 } 564 565 sc->tm_chan = (void *)&drv_cmd; 566 567 mpi3mr_dprint(sc, MPI3MR_DEBUG_TM, 568 "posting task management request: type(%d), handle(0x%04x)\n", 569 tm_type, tgtdev->dev_handle); 570 571 init_completion(&drv_cmd->completion); 572 retval = mpi3mr_submit_admin_cmd(sc, &tm_req, sizeof(tm_req)); 573 if (retval) { 574 mpi3mr_dprint(sc, MPI3MR_ERROR, 575 "posting task management request is failed\n"); 576 retval = -1; 577 goto out_unlock; 578 } 579 wait_for_completion_timeout_tm(&drv_cmd->completion, timeout, sc); 580 581 if (!(drv_cmd->state & MPI3MR_CMD_COMPLETE)) { 582 drv_cmd->is_waiting = 0; 583 retval = -1; 584 if (!(drv_cmd->state & MPI3MR_CMD_RESET)) { 585 mpi3mr_dprint(sc, MPI3MR_ERROR, 586 "task management request timed out after %ld seconds\n", timeout); 587 if (sc->mpi3mr_debug & MPI3MR_DEBUG_TM) { 588 mpi3mr_dprint(sc, MPI3MR_INFO, "tm_request dump\n"); 589 mpi3mr_hexdump(&tm_req, sizeof(tm_req), 8); 590 } 591 trigger_reset_from_watchdog(sc, MPI3MR_TRIGGER_SOFT_RESET, MPI3MR_RESET_FROM_TM_TIMEOUT); 592 retval = ETIMEDOUT; 593 } 594 goto out_unlock; 595 } 596 597 if (!(drv_cmd->state & MPI3MR_CMD_REPLYVALID)) { 598 mpi3mr_dprint(sc, MPI3MR_ERROR, 599 "invalid task management reply message\n"); 600 retval = -1; 601 goto out_unlock; 602 } 603 tm_reply = (MPI3_SCSI_TASK_MGMT_REPLY *)drv_cmd->reply; 604 605 switch (drv_cmd->ioc_status) { 606 case MPI3_IOCSTATUS_SUCCESS: 607 resp_code = tm_reply->ResponseData & MPI3MR_RI_MASK_RESPCODE; 608 break; 609 case MPI3_IOCSTATUS_SCSI_IOC_TERMINATED: 610 resp_code = MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE; 611 break; 612 default: 613 mpi3mr_dprint(sc, MPI3MR_ERROR, 614 "task management request to handle(0x%04x) is failed with ioc_status(0x%04x) log_info(0x%08x)\n", 615 tgtdev->dev_handle, drv_cmd->ioc_status, drv_cmd->ioc_loginfo); 616 retval = -1; 617 goto out_unlock; 618 } 619 620 switch (resp_code) { 621 case MPI3_SCSITASKMGMT_RSPCODE_TM_SUCCEEDED: 622 case MPI3_SCSITASKMGMT_RSPCODE_TM_COMPLETE: 623 break; 624 case MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC: 625 if (tm_type != MPI3_SCSITASKMGMT_TASKTYPE_QUERY_TASK) 626 retval = -1; 627 break; 628 default: 629 retval = -1; 630 break; 631 } 632 633 mpi3mr_dprint(sc, MPI3MR_DEBUG_TM, 634 "task management request type(%d) completed for handle(0x%04x) with ioc_status(0x%04x), log_info(0x%08x)" 635 "termination_count(%u), response:%s(0x%x)\n", tm_type, tgtdev->dev_handle, drv_cmd->ioc_status, drv_cmd->ioc_loginfo, 636 tm_reply->TerminationCount, mpi3mr_tm_response_name(resp_code), resp_code); 637 638 if (retval) 639 goto out_unlock; 640 641 mpi3mr_disable_interrupts(sc); 642 mpi3mr_poll_pend_io_completions(sc); 643 mpi3mr_enable_interrupts(sc); 644 mpi3mr_poll_pend_io_completions(sc); 645 646 switch (tm_type) { 647 case MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK: 648 if (cmd->state == MPI3MR_CMD_STATE_IN_TM) { 649 mpi3mr_dprint(sc, MPI3MR_ERROR, 650 "%s: task abort returned success from firmware but corresponding CCB (%p) was not terminated" 651 "marking task abort failed!\n", sc->name, cmd->ccb); 652 retval = -1; 653 } 654 break; 655 case MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET: 656 if (mpi3mr_atomic_read(&tgtdev->outstanding)) { 657 mpi3mr_dprint(sc, MPI3MR_ERROR, 658 "%s: target reset returned success from firmware but IOs are still pending on the target (%p)" 659 "marking target reset failed!\n", 660 sc->name, tgtdev); 661 retval = -1; 662 } 663 break; 664 default: 665 break; 666 } 667 668 out_unlock: 669 drv_cmd->state = MPI3MR_CMD_NOTUSED; 670 mtx_unlock(&drv_cmd->lock); 671 if (tgtdev && mpi3mr_atomic_read(&tgtdev->block_io) > 0) 672 mpi3mr_atomic_dec(&tgtdev->block_io); 673 674 return retval; 675 } 676 677 /** 678 * mpi3mr_task_abort- Abort error handling callback 679 * @cmd: Timed out command reference 680 * 681 * Issue Abort Task Management if the command is in LLD scope 682 * and verify if it is aborted successfully and return status 683 * accordingly. 684 * 685 * Return: SUCCESS of successful abort the SCSI command else FAILED 686 */ 687 static int mpi3mr_task_abort(struct mpi3mr_cmd *cmd) 688 { 689 int retval = 0; 690 struct mpi3mr_softc *sc; 691 union ccb *ccb; 692 693 sc = cmd->sc; 694 695 if (!cmd->ccb) { 696 mpi3mr_dprint(sc, MPI3MR_ERROR, "SCSIIO command timed-out with NULL ccb\n"); 697 return retval; 698 } 699 ccb = cmd->ccb; 700 701 mpi3mr_dprint(sc, MPI3MR_INFO, 702 "attempting abort task for ccb(%p)\n", ccb); 703 704 mpi3mr_print_cdb(ccb); 705 706 if (cmd->state != MPI3MR_CMD_STATE_BUSY) { 707 mpi3mr_dprint(sc, MPI3MR_INFO, 708 "%s: ccb is not in driver scope, abort task is not required\n", 709 sc->name); 710 return retval; 711 } 712 cmd->state = MPI3MR_CMD_STATE_IN_TM; 713 714 retval = mpi3mr_issue_tm(sc, cmd, MPI3_SCSITASKMGMT_TASKTYPE_ABORT_TASK, MPI3MR_ABORTTM_TIMEOUT); 715 716 mpi3mr_dprint(sc, MPI3MR_INFO, 717 "abort task is %s for ccb(%p)\n", ((retval == 0) ? "SUCCESS" : "FAILED"), ccb); 718 719 return retval; 720 } 721 722 /** 723 * mpi3mr_target_reset - Target reset error handling callback 724 * @cmd: Timed out command reference 725 * 726 * Issue Target reset Task Management and verify the SCSI commands are 727 * terminated successfully and return status accordingly. 728 * 729 * Return: SUCCESS of successful termination of the SCSI commands else 730 * FAILED 731 */ 732 static int mpi3mr_target_reset(struct mpi3mr_cmd *cmd) 733 { 734 int retval = 0; 735 struct mpi3mr_softc *sc; 736 struct mpi3mr_target *target; 737 738 sc = cmd->sc; 739 740 target = cmd->targ; 741 if (target == NULL) { 742 mpi3mr_dprint(sc, MPI3MR_XINFO, "Device does not exist for target:0x%p," 743 "target reset is not required\n", target); 744 return retval; 745 } 746 747 mpi3mr_dprint(sc, MPI3MR_INFO, 748 "attempting target reset on target(%d)\n", target->per_id); 749 750 751 if (mpi3mr_atomic_read(&target->outstanding)) { 752 mpi3mr_dprint(sc, MPI3MR_INFO, 753 "no outstanding IOs on the target(%d)," 754 " target reset not required.\n", target->per_id); 755 return retval; 756 } 757 758 retval = mpi3mr_issue_tm(sc, cmd, MPI3_SCSITASKMGMT_TASKTYPE_TARGET_RESET, MPI3MR_RESETTM_TIMEOUT); 759 760 mpi3mr_dprint(sc, MPI3MR_INFO, 761 "target reset is %s for target(%d)\n", ((retval == 0) ? "SUCCESS" : "FAILED"), 762 target->per_id); 763 764 return retval; 765 } 766 767 /** 768 * mpi3mr_get_fw_pending_ios - Calculate pending I/O count 769 * @sc: Adapter instance reference 770 * 771 * Calculate the pending I/Os for the controller and return. 772 * 773 * Return: Number of pending I/Os 774 */ 775 static inline int mpi3mr_get_fw_pending_ios(struct mpi3mr_softc *sc) 776 { 777 U16 i, pend_ios = 0; 778 779 for (i = 0; i < sc->num_queues; i++) 780 pend_ios += mpi3mr_atomic_read(&sc->op_reply_q[i].pend_ios); 781 return pend_ios; 782 } 783 784 /** 785 * mpi3mr_wait_for_host_io - block for I/Os to complete 786 * @sc: Adapter instance reference 787 * @timeout: time out in seconds 788 * 789 * Waits for pending I/Os for the given adapter to complete or 790 * to hit the timeout. 791 * 792 * Return: Nothing 793 */ 794 static int mpi3mr_wait_for_host_io(struct mpi3mr_softc *sc, U32 timeout) 795 { 796 enum mpi3mr_iocstate iocstate; 797 798 iocstate = mpi3mr_get_iocstate(sc); 799 if (iocstate != MRIOC_STATE_READY) { 800 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s :Controller is in NON-READY state! Proceed with Reset\n", __func__); 801 return -1; 802 } 803 804 if (!mpi3mr_get_fw_pending_ios(sc)) 805 return 0; 806 807 mpi3mr_dprint(sc, MPI3MR_INFO, 808 "%s :Waiting for %d seconds prior to reset for %d pending I/Os to complete\n", 809 __func__, timeout, mpi3mr_get_fw_pending_ios(sc)); 810 811 int i; 812 for (i = 0; i < timeout; i++) { 813 if (!mpi3mr_get_fw_pending_ios(sc)) { 814 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :All pending I/Os got completed while waiting! Reset not required\n", __func__); 815 return 0; 816 817 } 818 iocstate = mpi3mr_get_iocstate(sc); 819 if (iocstate != MRIOC_STATE_READY) { 820 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s :Controller state becomes NON-READY while waiting! dont wait further" 821 "Proceed with Reset\n", __func__); 822 return -1; 823 } 824 DELAY(1000 * 1000); 825 } 826 827 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :Pending I/Os after wait exaust is %d! Proceed with Reset\n", __func__, 828 mpi3mr_get_fw_pending_ios(sc)); 829 830 return -1; 831 } 832 833 static void 834 mpi3mr_scsiio_timeout(void *data) 835 { 836 int retval = 0; 837 struct mpi3mr_softc *sc; 838 struct mpi3mr_cmd *cmd; 839 struct mpi3mr_target *targ_dev = NULL; 840 841 if (!data) 842 return; 843 844 cmd = (struct mpi3mr_cmd *)data; 845 sc = cmd->sc; 846 847 if (cmd->ccb == NULL) { 848 mpi3mr_dprint(sc, MPI3MR_ERROR, "SCSIIO command timed-out with NULL ccb\n"); 849 return; 850 } 851 852 /* 853 * TMs are not supported for IO timeouts on VD/LD, so directly issue controller reset 854 * with max timeout for outstanding IOs to complete is 180sec. 855 */ 856 targ_dev = cmd->targ; 857 if (targ_dev && (targ_dev->dev_type == MPI3_DEVICE_DEVFORM_VD)) { 858 if (mpi3mr_wait_for_host_io(sc, MPI3MR_RAID_ERRREC_RESET_TIMEOUT)) 859 trigger_reset_from_watchdog(sc, MPI3MR_TRIGGER_SOFT_RESET, MPI3MR_RESET_FROM_SCSIIO_TIMEOUT); 860 return; 861 } 862 863 /* Issue task abort to recover the timed out IO */ 864 retval = mpi3mr_task_abort(cmd); 865 if (!retval || (retval == ETIMEDOUT)) 866 return; 867 868 /* 869 * task abort has failed to recover the timed out IO, 870 * try with the target reset 871 */ 872 retval = mpi3mr_target_reset(cmd); 873 if (!retval || (retval == ETIMEDOUT)) 874 return; 875 876 /* 877 * task abort and target reset has failed. So issue Controller reset(soft reset) 878 * through OCR thread context 879 */ 880 trigger_reset_from_watchdog(sc, MPI3MR_TRIGGER_SOFT_RESET, MPI3MR_RESET_FROM_SCSIIO_TIMEOUT); 881 882 return; 883 } 884 885 void int_to_lun(unsigned int lun, U8 *req_lun) 886 { 887 int i; 888 889 memset(req_lun, 0, sizeof(*req_lun)); 890 891 for (i = 0; i < sizeof(lun); i += 2) { 892 req_lun[i] = (lun >> 8) & 0xFF; 893 req_lun[i+1] = lun & 0xFF; 894 lun = lun >> 16; 895 } 896 897 } 898 899 static U16 get_req_queue_index(struct mpi3mr_softc *sc) 900 { 901 U16 i = 0, reply_q_index = 0, reply_q_pend_ios = 0; 902 903 reply_q_pend_ios = mpi3mr_atomic_read(&sc->op_reply_q[0].pend_ios); 904 for (i = 0; i < sc->num_queues; i++) { 905 if (reply_q_pend_ios > mpi3mr_atomic_read(&sc->op_reply_q[i].pend_ios)) { 906 reply_q_pend_ios = mpi3mr_atomic_read(&sc->op_reply_q[i].pend_ios); 907 reply_q_index = i; 908 } 909 } 910 911 return reply_q_index; 912 } 913 914 static void 915 mpi3mr_action_scsiio(struct mpi3mr_cam_softc *cam_sc, union ccb *ccb) 916 { 917 Mpi3SCSIIORequest_t *req = NULL; 918 struct ccb_scsiio *csio; 919 struct mpi3mr_softc *sc; 920 struct mpi3mr_target *targ; 921 struct mpi3mr_cmd *cm; 922 uint8_t scsi_opcode, queue_idx; 923 uint32_t mpi_control; 924 925 sc = cam_sc->sc; 926 mtx_assert(&sc->mpi3mr_mtx, MA_OWNED); 927 928 if (sc->unrecoverable) { 929 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 930 xpt_done(ccb); 931 return; 932 } 933 934 csio = &ccb->csio; 935 KASSERT(csio->ccb_h.target_id < cam_sc->maxtargets, 936 ("Target %d out of bounds in XPT_SCSI_IO\n", 937 csio->ccb_h.target_id)); 938 939 scsi_opcode = scsiio_cdb_ptr(csio)[0]; 940 941 if ((sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) && 942 !((scsi_opcode == SYNCHRONIZE_CACHE) || 943 (scsi_opcode == START_STOP_UNIT))) { 944 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 945 xpt_done(ccb); 946 return; 947 } 948 949 targ = mpi3mr_find_target_by_per_id(cam_sc, csio->ccb_h.target_id); 950 if (targ == NULL) { 951 mpi3mr_dprint(sc, MPI3MR_XINFO, "Device with target ID: 0x%x does not exist\n", 952 csio->ccb_h.target_id); 953 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 954 xpt_done(ccb); 955 return; 956 } 957 958 if (targ && targ->is_hidden) { 959 mpi3mr_dprint(sc, MPI3MR_XINFO, "Device with target ID: 0x%x is hidden\n", 960 csio->ccb_h.target_id); 961 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 962 xpt_done(ccb); 963 return; 964 } 965 966 if (targ->dev_removed == 1) { 967 mpi3mr_dprint(sc, MPI3MR_XINFO, "Device with target ID: 0x%x is removed\n", csio->ccb_h.target_id); 968 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 969 xpt_done(ccb); 970 return; 971 } 972 973 if (targ->dev_handle == 0x0) { 974 mpi3mr_dprint(sc, MPI3MR_ERROR, "%s NULL handle for target 0x%x\n", 975 __func__, csio->ccb_h.target_id); 976 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 977 xpt_done(ccb); 978 return; 979 } 980 981 if (mpi3mr_atomic_read(&targ->block_io) || 982 (sc->reset_in_progress == 1) || (sc->prepare_for_reset == 1)) { 983 mpi3mr_dprint(sc, MPI3MR_TRACE, "%s target is busy target_id: 0x%x\n", 984 __func__, csio->ccb_h.target_id); 985 mpi3mr_set_ccbstatus(ccb, CAM_REQUEUE_REQ); 986 xpt_done(ccb); 987 return; 988 } 989 990 /* 991 * Sometimes, it is possible to get a command that is not "In 992 * Progress" and was actually aborted by the upper layer. Check for 993 * this here and complete the command without error. 994 */ 995 if (mpi3mr_get_ccbstatus(ccb) != CAM_REQ_INPROG) { 996 mpi3mr_dprint(sc, MPI3MR_TRACE, "%s Command is not in progress for " 997 "target %u\n", __func__, csio->ccb_h.target_id); 998 xpt_done(ccb); 999 return; 1000 } 1001 /* 1002 * If devinfo is 0 this will be a volume. In that case don't tell CAM 1003 * that the volume has timed out. We want volumes to be enumerated 1004 * until they are deleted/removed, not just failed. 1005 */ 1006 if (targ->flags & MPI3MRSAS_TARGET_INREMOVAL) { 1007 if (targ->devinfo == 0) 1008 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 1009 else 1010 mpi3mr_set_ccbstatus(ccb, CAM_SEL_TIMEOUT); 1011 xpt_done(ccb); 1012 return; 1013 } 1014 1015 if ((scsi_opcode == UNMAP) && 1016 (pci_get_device(sc->mpi3mr_dev) == MPI3_MFGPAGE_DEVID_SAS4116) && 1017 (targ->dev_type == MPI3_DEVICE_DEVFORM_PCIE) && 1018 (mpi3mr_allow_unmap_to_fw(sc, ccb) == false)) 1019 return; 1020 1021 cm = mpi3mr_get_command(sc); 1022 if (cm == NULL || (sc->mpi3mr_flags & MPI3MR_FLAGS_DIAGRESET)) { 1023 if (cm != NULL) { 1024 mpi3mr_release_command(cm); 1025 } 1026 if ((cam_sc->flags & MPI3MRSAS_QUEUE_FROZEN) == 0) { 1027 xpt_freeze_simq(cam_sc->sim, 1); 1028 cam_sc->flags |= MPI3MRSAS_QUEUE_FROZEN; 1029 } 1030 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1031 mpi3mr_set_ccbstatus(ccb, CAM_REQUEUE_REQ); 1032 xpt_done(ccb); 1033 return; 1034 } 1035 1036 switch (csio->ccb_h.flags & CAM_DIR_MASK) { 1037 case CAM_DIR_IN: 1038 mpi_control = MPI3_SCSIIO_FLAGS_DATADIRECTION_READ; 1039 cm->data_dir = MPI3MR_READ; 1040 break; 1041 case CAM_DIR_OUT: 1042 mpi_control = MPI3_SCSIIO_FLAGS_DATADIRECTION_WRITE; 1043 cm->data_dir = MPI3MR_WRITE; 1044 break; 1045 case CAM_DIR_NONE: 1046 default: 1047 mpi_control = MPI3_SCSIIO_FLAGS_DATADIRECTION_NO_DATA_TRANSFER; 1048 break; 1049 } 1050 1051 if (csio->cdb_len > 16) 1052 mpi_control |= MPI3_SCSIIO_FLAGS_CDB_GREATER_THAN_16; 1053 1054 req = (Mpi3SCSIIORequest_t *)&cm->io_request; 1055 bzero(req, sizeof(*req)); 1056 req->Function = MPI3_FUNCTION_SCSI_IO; 1057 req->HostTag = cm->hosttag; 1058 req->DataLength = htole32(csio->dxfer_len); 1059 req->DevHandle = htole16(targ->dev_handle); 1060 1061 /* 1062 * It looks like the hardware doesn't require an explicit tag 1063 * number for each transaction. SAM Task Management not supported 1064 * at the moment. 1065 */ 1066 switch (csio->tag_action) { 1067 case MSG_HEAD_OF_Q_TAG: 1068 mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_HEADOFQ; 1069 break; 1070 case MSG_ORDERED_Q_TAG: 1071 mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_ORDEREDQ; 1072 break; 1073 case MSG_ACA_TASK: 1074 mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_ACAQ; 1075 break; 1076 case CAM_TAG_ACTION_NONE: 1077 case MSG_SIMPLE_Q_TAG: 1078 default: 1079 mpi_control |= MPI3_SCSIIO_FLAGS_TASKATTRIBUTE_SIMPLEQ; 1080 break; 1081 } 1082 1083 req->Flags = htole32(mpi_control); 1084 1085 if (csio->ccb_h.flags & CAM_CDB_POINTER) 1086 bcopy(csio->cdb_io.cdb_ptr, &req->CDB.CDB32[0], csio->cdb_len); 1087 else { 1088 KASSERT(csio->cdb_len <= IOCDBLEN, 1089 ("cdb_len %d is greater than IOCDBLEN but CAM_CDB_POINTER " 1090 "is not set", csio->cdb_len)); 1091 bcopy(csio->cdb_io.cdb_bytes, &req->CDB.CDB32[0],csio->cdb_len); 1092 } 1093 1094 cm->length = csio->dxfer_len; 1095 cm->targ = targ; 1096 int_to_lun(csio->ccb_h.target_lun, req->LUN); 1097 cm->ccb = ccb; 1098 csio->ccb_h.qos.sim_data = sbinuptime(); 1099 queue_idx = get_req_queue_index(sc); 1100 cm->req_qidx = queue_idx; 1101 1102 mpi3mr_dprint(sc, MPI3MR_TRACE, "[QID:%d]: func: %s line:%d CDB: 0x%x targetid: %x SMID: 0x%x\n", 1103 (queue_idx + 1), __func__, __LINE__, scsi_opcode, csio->ccb_h.target_id, cm->hosttag); 1104 1105 switch ((ccb->ccb_h.flags & CAM_DATA_MASK)) { 1106 case CAM_DATA_PADDR: 1107 case CAM_DATA_SG_PADDR: 1108 device_printf(sc->mpi3mr_dev, "%s: physical addresses not supported\n", 1109 __func__); 1110 mpi3mr_set_ccbstatus(ccb, CAM_REQ_INVALID); 1111 mpi3mr_release_command(cm); 1112 xpt_done(ccb); 1113 return; 1114 case CAM_DATA_SG: 1115 device_printf(sc->mpi3mr_dev, "%s: scatter gather is not supported\n", 1116 __func__); 1117 mpi3mr_set_ccbstatus(ccb, CAM_REQ_INVALID); 1118 mpi3mr_release_command(cm); 1119 xpt_done(ccb); 1120 return; 1121 case CAM_DATA_VADDR: 1122 case CAM_DATA_BIO: 1123 if (csio->dxfer_len > (MPI3MR_SG_DEPTH * MPI3MR_4K_PGSZ)) { 1124 mpi3mr_set_ccbstatus(ccb, CAM_REQ_TOO_BIG); 1125 mpi3mr_release_command(cm); 1126 xpt_done(ccb); 1127 return; 1128 } 1129 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1130 cm->length = csio->dxfer_len; 1131 if (cm->length) 1132 cm->data = csio->data_ptr; 1133 break; 1134 default: 1135 mpi3mr_set_ccbstatus(ccb, CAM_REQ_INVALID); 1136 mpi3mr_release_command(cm); 1137 xpt_done(ccb); 1138 return; 1139 } 1140 1141 /* Prepare SGEs and queue to hardware */ 1142 mpi3mr_map_request(sc, cm); 1143 } 1144 1145 static void 1146 mpi3mr_enqueue_request(struct mpi3mr_softc *sc, struct mpi3mr_cmd *cm) 1147 { 1148 static int ratelimit; 1149 struct mpi3mr_op_req_queue *opreqq = &sc->op_req_q[cm->req_qidx]; 1150 struct mpi3mr_throttle_group_info *tg = NULL; 1151 uint32_t data_len_blks = 0; 1152 uint32_t tracked_io_sz = 0; 1153 uint32_t ioc_pend_data_len = 0, tg_pend_data_len = 0; 1154 struct mpi3mr_target *targ = cm->targ; 1155 union ccb *ccb = cm->ccb; 1156 Mpi3SCSIIORequest_t *req = (Mpi3SCSIIORequest_t *)&cm->io_request; 1157 1158 if (sc->iot_enable) { 1159 data_len_blks = ccb->csio.dxfer_len >> 9; 1160 1161 if ((data_len_blks >= sc->io_throttle_data_length) && 1162 targ->io_throttle_enabled) { 1163 1164 tracked_io_sz = data_len_blks; 1165 tg = targ->throttle_group; 1166 if (tg) { 1167 mpi3mr_atomic_add(&sc->pend_large_data_sz, data_len_blks); 1168 mpi3mr_atomic_add(&tg->pend_large_data_sz, data_len_blks); 1169 1170 ioc_pend_data_len = mpi3mr_atomic_read(&sc->pend_large_data_sz); 1171 tg_pend_data_len = mpi3mr_atomic_read(&tg->pend_large_data_sz); 1172 1173 if (ratelimit % 1000) { 1174 mpi3mr_dprint(sc, MPI3MR_IOT, 1175 "large vd_io persist_id(%d), handle(0x%04x), data_len(%d)," 1176 "ioc_pending(%d), tg_pending(%d), ioc_high(%d), tg_high(%d)\n", 1177 targ->per_id, targ->dev_handle, 1178 data_len_blks, ioc_pend_data_len, 1179 tg_pend_data_len, sc->io_throttle_high, 1180 tg->high); 1181 ratelimit++; 1182 } 1183 1184 if (!tg->io_divert && ((ioc_pend_data_len >= 1185 sc->io_throttle_high) || 1186 (tg_pend_data_len >= tg->high))) { 1187 tg->io_divert = 1; 1188 mpi3mr_dprint(sc, MPI3MR_IOT, 1189 "VD: Setting divert flag for tg_id(%d), persist_id(%d)\n", 1190 tg->id, targ->per_id); 1191 if (sc->mpi3mr_debug | MPI3MR_IOT) 1192 mpi3mr_print_cdb(ccb); 1193 mpi3mr_set_io_divert_for_all_vd_in_tg(sc, 1194 tg, 1); 1195 } 1196 } else { 1197 mpi3mr_atomic_add(&sc->pend_large_data_sz, data_len_blks); 1198 ioc_pend_data_len = mpi3mr_atomic_read(&sc->pend_large_data_sz); 1199 if (ratelimit % 1000) { 1200 mpi3mr_dprint(sc, MPI3MR_IOT, 1201 "large pd_io persist_id(%d), handle(0x%04x), data_len(%d), ioc_pending(%d), ioc_high(%d)\n", 1202 targ->per_id, targ->dev_handle, 1203 data_len_blks, ioc_pend_data_len, 1204 sc->io_throttle_high); 1205 ratelimit++; 1206 } 1207 1208 if (ioc_pend_data_len >= sc->io_throttle_high) { 1209 targ->io_divert = 1; 1210 mpi3mr_dprint(sc, MPI3MR_IOT, 1211 "PD: Setting divert flag for persist_id(%d)\n", 1212 targ->per_id); 1213 if (sc->mpi3mr_debug | MPI3MR_IOT) 1214 mpi3mr_print_cdb(ccb); 1215 } 1216 } 1217 } 1218 1219 if (targ->io_divert) { 1220 req->MsgFlags |= MPI3_SCSIIO_MSGFLAGS_DIVERT_TO_FIRMWARE; 1221 req->Flags = htole32(le32toh(req->Flags) | MPI3_SCSIIO_FLAGS_DIVERT_REASON_IO_THROTTLING); 1222 } 1223 } 1224 1225 if (mpi3mr_submit_io(sc, opreqq, (U8 *)&cm->io_request)) { 1226 if (tracked_io_sz) { 1227 mpi3mr_atomic_sub(&sc->pend_large_data_sz, tracked_io_sz); 1228 if (tg) 1229 mpi3mr_atomic_sub(&tg->pend_large_data_sz, tracked_io_sz); 1230 } 1231 mpi3mr_set_ccbstatus(ccb, CAM_RESRC_UNAVAIL); 1232 mpi3mr_release_command(cm); 1233 xpt_done(ccb); 1234 } else { 1235 callout_reset_sbt(&cm->callout, mstosbt(ccb->ccb_h.timeout), 0, 1236 mpi3mr_scsiio_timeout, cm, 0); 1237 cm->callout_owner = true; 1238 mpi3mr_atomic_inc(&sc->fw_outstanding); 1239 mpi3mr_atomic_inc(&targ->outstanding); 1240 if (mpi3mr_atomic_read(&sc->fw_outstanding) > sc->io_cmds_highwater) 1241 sc->io_cmds_highwater++; 1242 } 1243 1244 return; 1245 } 1246 1247 static void 1248 mpi3mr_cam_poll(struct cam_sim *sim) 1249 { 1250 struct mpi3mr_cam_softc *cam_sc; 1251 struct mpi3mr_irq_context *irq_ctx; 1252 struct mpi3mr_softc *sc; 1253 int i; 1254 1255 cam_sc = cam_sim_softc(sim); 1256 sc = cam_sc->sc; 1257 1258 mpi3mr_dprint(cam_sc->sc, MPI3MR_TRACE, "func: %s line: %d is called\n", 1259 __func__, __LINE__); 1260 1261 for (i = 0; i < sc->num_queues; i++) { 1262 irq_ctx = sc->irq_ctx + i; 1263 if (irq_ctx->op_reply_q->qid) { 1264 mpi3mr_complete_io_cmd(sc, irq_ctx); 1265 } 1266 } 1267 } 1268 1269 static void 1270 mpi3mr_cam_action(struct cam_sim *sim, union ccb *ccb) 1271 { 1272 struct mpi3mr_cam_softc *cam_sc; 1273 struct mpi3mr_target *targ; 1274 1275 cam_sc = cam_sim_softc(sim); 1276 1277 mpi3mr_dprint(cam_sc->sc, MPI3MR_TRACE, "ccb func_code 0x%x target id: 0x%x\n", 1278 ccb->ccb_h.func_code, ccb->ccb_h.target_id); 1279 1280 mtx_assert(&cam_sc->sc->mpi3mr_mtx, MA_OWNED); 1281 1282 switch (ccb->ccb_h.func_code) { 1283 case XPT_PATH_INQ: 1284 { 1285 struct ccb_pathinq *cpi = &ccb->cpi; 1286 1287 cpi->version_num = 1; 1288 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 1289 cpi->target_sprt = 0; 1290 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED | PIM_NOSCAN; 1291 cpi->hba_eng_cnt = 0; 1292 cpi->max_target = cam_sc->maxtargets - 1; 1293 cpi->max_lun = 0; 1294 1295 /* 1296 * initiator_id is set here to an ID outside the set of valid 1297 * target IDs (including volumes). 1298 */ 1299 cpi->initiator_id = cam_sc->maxtargets; 1300 strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1301 strlcpy(cpi->hba_vid, "Broadcom", HBA_IDLEN); 1302 strlcpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1303 cpi->unit_number = cam_sim_unit(sim); 1304 cpi->bus_id = cam_sim_bus(sim); 1305 /* 1306 * XXXSLM-I think this needs to change based on config page or 1307 * something instead of hardcoded to 150000. 1308 */ 1309 cpi->base_transfer_speed = 150000; 1310 cpi->transport = XPORT_SAS; 1311 cpi->transport_version = 0; 1312 cpi->protocol = PROTO_SCSI; 1313 cpi->protocol_version = SCSI_REV_SPC; 1314 1315 targ = mpi3mr_find_target_by_per_id(cam_sc, ccb->ccb_h.target_id); 1316 1317 if (targ && (targ->dev_type == MPI3_DEVICE_DEVFORM_PCIE) && 1318 ((targ->dev_spec.pcie_inf.dev_info & 1319 MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) == 1320 MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE)) { 1321 cpi->maxio = targ->dev_spec.pcie_inf.mdts; 1322 mpi3mr_dprint(cam_sc->sc, MPI3MR_XINFO, 1323 "PCI device target_id: %u max io size: %u\n", 1324 ccb->ccb_h.target_id, cpi->maxio); 1325 } else { 1326 cpi->maxio = PAGE_SIZE * (MPI3MR_SG_DEPTH - 1); 1327 } 1328 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 1329 break; 1330 } 1331 case XPT_GET_TRAN_SETTINGS: 1332 { 1333 struct ccb_trans_settings *cts; 1334 struct ccb_trans_settings_sas *sas; 1335 struct ccb_trans_settings_scsi *scsi; 1336 1337 cts = &ccb->cts; 1338 sas = &cts->xport_specific.sas; 1339 scsi = &cts->proto_specific.scsi; 1340 1341 KASSERT(cts->ccb_h.target_id < cam_sc->maxtargets, 1342 ("Target %d out of bounds in XPT_GET_TRAN_SETTINGS\n", 1343 cts->ccb_h.target_id)); 1344 targ = mpi3mr_find_target_by_per_id(cam_sc, cts->ccb_h.target_id); 1345 1346 if (targ == NULL) { 1347 mpi3mr_dprint(cam_sc->sc, MPI3MR_TRACE, "Device with target ID: 0x%x does not exist\n", 1348 cts->ccb_h.target_id); 1349 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 1350 break; 1351 } 1352 1353 if ((targ->dev_handle == 0x0) || (targ->dev_removed == 1)) { 1354 mpi3mr_set_ccbstatus(ccb, CAM_DEV_NOT_THERE); 1355 break; 1356 } 1357 1358 cts->protocol_version = SCSI_REV_SPC2; 1359 cts->transport = XPORT_SAS; 1360 cts->transport_version = 0; 1361 1362 sas->valid = CTS_SAS_VALID_SPEED; 1363 1364 switch (targ->link_rate) { 1365 case 0x08: 1366 sas->bitrate = 150000; 1367 break; 1368 case 0x09: 1369 sas->bitrate = 300000; 1370 break; 1371 case 0x0a: 1372 sas->bitrate = 600000; 1373 break; 1374 case 0x0b: 1375 sas->bitrate = 1200000; 1376 break; 1377 default: 1378 sas->valid = 0; 1379 } 1380 1381 cts->protocol = PROTO_SCSI; 1382 scsi->valid = CTS_SCSI_VALID_TQ; 1383 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 1384 1385 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 1386 break; 1387 } 1388 case XPT_CALC_GEOMETRY: 1389 cam_calc_geometry(&ccb->ccg, /*extended*/1); 1390 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 1391 break; 1392 case XPT_RESET_DEV: 1393 mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "mpi3mr_action " 1394 "XPT_RESET_DEV\n"); 1395 return; 1396 case XPT_RESET_BUS: 1397 case XPT_ABORT: 1398 case XPT_TERM_IO: 1399 mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "mpi3mr_action faking success " 1400 "for abort or reset\n"); 1401 mpi3mr_set_ccbstatus(ccb, CAM_REQ_CMP); 1402 break; 1403 case XPT_SCSI_IO: 1404 mpi3mr_action_scsiio(cam_sc, ccb); 1405 return; 1406 default: 1407 mpi3mr_set_ccbstatus(ccb, CAM_FUNC_NOTAVAIL); 1408 break; 1409 } 1410 xpt_done(ccb); 1411 } 1412 1413 void 1414 mpi3mr_startup_increment(struct mpi3mr_cam_softc *cam_sc) 1415 { 1416 if ((cam_sc->flags & MPI3MRSAS_IN_STARTUP) != 0) { 1417 if (cam_sc->startup_refcount++ == 0) { 1418 /* just starting, freeze the simq */ 1419 mpi3mr_dprint(cam_sc->sc, MPI3MR_XINFO, 1420 "%s freezing simq\n", __func__); 1421 xpt_hold_boot(); 1422 } 1423 mpi3mr_dprint(cam_sc->sc, MPI3MR_XINFO, "%s refcount %u\n", __func__, 1424 cam_sc->startup_refcount); 1425 } 1426 } 1427 1428 void 1429 mpi3mr_release_simq_reinit(struct mpi3mr_cam_softc *cam_sc) 1430 { 1431 if (cam_sc->flags & MPI3MRSAS_QUEUE_FROZEN) { 1432 cam_sc->flags &= ~MPI3MRSAS_QUEUE_FROZEN; 1433 xpt_release_simq(cam_sc->sim, 1); 1434 mpi3mr_dprint(cam_sc->sc, MPI3MR_INFO, "Unfreezing SIM queue\n"); 1435 } 1436 } 1437 1438 void 1439 mpi3mr_rescan_target(struct mpi3mr_softc *sc, struct mpi3mr_target *targ) 1440 { 1441 struct mpi3mr_cam_softc *cam_sc = sc->cam_sc; 1442 path_id_t pathid; 1443 target_id_t targetid; 1444 union ccb *ccb; 1445 1446 pathid = cam_sim_path(cam_sc->sim); 1447 if (targ == NULL) 1448 targetid = CAM_TARGET_WILDCARD; 1449 else 1450 targetid = targ->per_id; 1451 1452 /* 1453 * Allocate a CCB and schedule a rescan. 1454 */ 1455 ccb = xpt_alloc_ccb_nowait(); 1456 if (ccb == NULL) { 1457 mpi3mr_dprint(sc, MPI3MR_ERROR, "unable to alloc CCB for rescan\n"); 1458 return; 1459 } 1460 1461 if (xpt_create_path(&ccb->ccb_h.path, NULL, pathid, targetid, 1462 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1463 mpi3mr_dprint(sc, MPI3MR_ERROR, "unable to create path for rescan\n"); 1464 xpt_free_ccb(ccb); 1465 return; 1466 } 1467 1468 if (targetid == CAM_TARGET_WILDCARD) 1469 ccb->ccb_h.func_code = XPT_SCAN_BUS; 1470 else 1471 ccb->ccb_h.func_code = XPT_SCAN_TGT; 1472 1473 mpi3mr_dprint(sc, MPI3MR_EVENT, "%s target id 0x%x\n", __func__, targetid); 1474 xpt_rescan(ccb); 1475 } 1476 1477 void 1478 mpi3mr_startup_decrement(struct mpi3mr_cam_softc *cam_sc) 1479 { 1480 if ((cam_sc->flags & MPI3MRSAS_IN_STARTUP) != 0) { 1481 if (--cam_sc->startup_refcount == 0) { 1482 /* finished all discovery-related actions, release 1483 * the simq and rescan for the latest topology. 1484 */ 1485 mpi3mr_dprint(cam_sc->sc, MPI3MR_XINFO, 1486 "%s releasing simq\n", __func__); 1487 cam_sc->flags &= ~MPI3MRSAS_IN_STARTUP; 1488 xpt_release_simq(cam_sc->sim, 1); 1489 xpt_release_boot(); 1490 } 1491 mpi3mr_dprint(cam_sc->sc, MPI3MR_XINFO, "%s refcount %u\n", __func__, 1492 cam_sc->startup_refcount); 1493 } 1494 } 1495 1496 static void 1497 mpi3mr_fw_event_free(struct mpi3mr_softc *sc, struct mpi3mr_fw_event_work *fw_event) 1498 { 1499 if (!fw_event) 1500 return; 1501 1502 if (fw_event->event_data != NULL) { 1503 free(fw_event->event_data, M_MPI3MR); 1504 fw_event->event_data = NULL; 1505 } 1506 1507 free(fw_event, M_MPI3MR); 1508 fw_event = NULL; 1509 } 1510 1511 static void 1512 mpi3mr_freeup_events(struct mpi3mr_softc *sc) 1513 { 1514 struct mpi3mr_fw_event_work *fw_event = NULL; 1515 mtx_lock(&sc->mpi3mr_mtx); 1516 while ((fw_event = TAILQ_FIRST(&sc->cam_sc->ev_queue)) != NULL) { 1517 TAILQ_REMOVE(&sc->cam_sc->ev_queue, fw_event, ev_link); 1518 mpi3mr_fw_event_free(sc, fw_event); 1519 } 1520 mtx_unlock(&sc->mpi3mr_mtx); 1521 } 1522 1523 static void 1524 mpi3mr_sastopochg_evt_debug(struct mpi3mr_softc *sc, 1525 Mpi3EventDataSasTopologyChangeList_t *event_data) 1526 { 1527 int i; 1528 U16 handle; 1529 U8 reason_code, phy_number; 1530 char *status_str = NULL; 1531 U8 link_rate, prev_link_rate; 1532 1533 switch (event_data->ExpStatus) { 1534 case MPI3_EVENT_SAS_TOPO_ES_NOT_RESPONDING: 1535 status_str = "remove"; 1536 break; 1537 case MPI3_EVENT_SAS_TOPO_ES_RESPONDING: 1538 status_str = "responding"; 1539 break; 1540 case MPI3_EVENT_SAS_TOPO_ES_DELAY_NOT_RESPONDING: 1541 status_str = "remove delay"; 1542 break; 1543 case MPI3_EVENT_SAS_TOPO_ES_NO_EXPANDER: 1544 status_str = "direct attached"; 1545 break; 1546 default: 1547 status_str = "unknown status"; 1548 break; 1549 } 1550 1551 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :sas topology change: (%s)\n", 1552 __func__, status_str); 1553 mpi3mr_dprint(sc, MPI3MR_INFO, 1554 "%s :\texpander_handle(0x%04x), enclosure_handle(0x%04x) " 1555 "start_phy(%02d), num_entries(%d)\n", __func__, 1556 (event_data->ExpanderDevHandle), 1557 (event_data->EnclosureHandle), 1558 event_data->StartPhyNum, event_data->NumEntries); 1559 for (i = 0; i < event_data->NumEntries; i++) { 1560 handle = (event_data->PhyEntry[i].AttachedDevHandle); 1561 if (!handle) 1562 continue; 1563 phy_number = event_data->StartPhyNum + i; 1564 reason_code = event_data->PhyEntry[i].Status & 1565 MPI3_EVENT_SAS_TOPO_PHY_RC_MASK; 1566 switch (reason_code) { 1567 case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING: 1568 status_str = "target remove"; 1569 break; 1570 case MPI3_EVENT_SAS_TOPO_PHY_RC_DELAY_NOT_RESPONDING: 1571 status_str = "delay target remove"; 1572 break; 1573 case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED: 1574 status_str = "link rate change"; 1575 break; 1576 case MPI3_EVENT_SAS_TOPO_PHY_RC_NO_CHANGE: 1577 status_str = "target responding"; 1578 break; 1579 default: 1580 status_str = "unknown"; 1581 break; 1582 } 1583 link_rate = event_data->PhyEntry[i].LinkRate >> 4; 1584 prev_link_rate = event_data->PhyEntry[i].LinkRate & 0xF; 1585 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :\tphy(%02d), attached_handle(0x%04x): %s:" 1586 " link rate: new(0x%02x), old(0x%02x)\n", __func__, 1587 phy_number, handle, status_str, link_rate, prev_link_rate); 1588 } 1589 } 1590 1591 static void 1592 mpi3mr_process_sastopochg_evt(struct mpi3mr_softc *sc, struct mpi3mr_fw_event_work *fwevt) 1593 { 1594 1595 Mpi3EventDataSasTopologyChangeList_t *event_data = 1596 (Mpi3EventDataSasTopologyChangeList_t *)fwevt->event_data; 1597 int i; 1598 U16 handle; 1599 U8 reason_code, link_rate; 1600 struct mpi3mr_target *target = NULL; 1601 1602 1603 mpi3mr_sastopochg_evt_debug(sc, event_data); 1604 1605 for (i = 0; i < event_data->NumEntries; i++) { 1606 handle = le16toh(event_data->PhyEntry[i].AttachedDevHandle); 1607 link_rate = event_data->PhyEntry[i].LinkRate >> 4; 1608 1609 if (!handle) 1610 continue; 1611 target = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle); 1612 1613 if (!target) 1614 continue; 1615 1616 target->link_rate = link_rate; 1617 reason_code = event_data->PhyEntry[i].Status & 1618 MPI3_EVENT_SAS_TOPO_PHY_RC_MASK; 1619 1620 switch (reason_code) { 1621 case MPI3_EVENT_SAS_TOPO_PHY_RC_TARG_NOT_RESPONDING: 1622 if (target->exposed_to_os) 1623 mpi3mr_remove_device_from_os(sc, target->dev_handle); 1624 mpi3mr_remove_device_from_list(sc, target, false); 1625 break; 1626 case MPI3_EVENT_SAS_TOPO_PHY_RC_PHY_CHANGED: 1627 break; 1628 default: 1629 break; 1630 } 1631 } 1632 1633 /* 1634 * refcount was incremented for this event in 1635 * mpi3mr_evt_handler. Decrement it here because the event has 1636 * been processed. 1637 */ 1638 mpi3mr_startup_decrement(sc->cam_sc); 1639 return; 1640 } 1641 1642 static inline void 1643 mpi3mr_logdata_evt_bh(struct mpi3mr_softc *sc, 1644 struct mpi3mr_fw_event_work *fwevt) 1645 { 1646 mpi3mr_app_save_logdata(sc, fwevt->event_data, 1647 fwevt->event_data_size); 1648 } 1649 1650 static void 1651 mpi3mr_pcietopochg_evt_debug(struct mpi3mr_softc *sc, 1652 Mpi3EventDataPcieTopologyChangeList_t *event_data) 1653 { 1654 int i; 1655 U16 handle; 1656 U16 reason_code; 1657 U8 port_number; 1658 char *status_str = NULL; 1659 U8 link_rate, prev_link_rate; 1660 1661 switch (event_data->SwitchStatus) { 1662 case MPI3_EVENT_PCIE_TOPO_SS_NOT_RESPONDING: 1663 status_str = "remove"; 1664 break; 1665 case MPI3_EVENT_PCIE_TOPO_SS_RESPONDING: 1666 status_str = "responding"; 1667 break; 1668 case MPI3_EVENT_PCIE_TOPO_SS_DELAY_NOT_RESPONDING: 1669 status_str = "remove delay"; 1670 break; 1671 case MPI3_EVENT_PCIE_TOPO_SS_NO_PCIE_SWITCH: 1672 status_str = "direct attached"; 1673 break; 1674 default: 1675 status_str = "unknown status"; 1676 break; 1677 } 1678 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :pcie topology change: (%s)\n", 1679 __func__, status_str); 1680 mpi3mr_dprint(sc, MPI3MR_INFO, 1681 "%s :\tswitch_handle(0x%04x), enclosure_handle(0x%04x)" 1682 "start_port(%02d), num_entries(%d)\n", __func__, 1683 le16toh(event_data->SwitchDevHandle), 1684 le16toh(event_data->EnclosureHandle), 1685 event_data->StartPortNum, event_data->NumEntries); 1686 for (i = 0; i < event_data->NumEntries; i++) { 1687 handle = 1688 le16toh(event_data->PortEntry[i].AttachedDevHandle); 1689 if (!handle) 1690 continue; 1691 port_number = event_data->StartPortNum + i; 1692 reason_code = event_data->PortEntry[i].PortStatus; 1693 switch (reason_code) { 1694 case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING: 1695 status_str = "target remove"; 1696 break; 1697 case MPI3_EVENT_PCIE_TOPO_PS_DELAY_NOT_RESPONDING: 1698 status_str = "delay target remove"; 1699 break; 1700 case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED: 1701 status_str = "link rate change"; 1702 break; 1703 case MPI3_EVENT_PCIE_TOPO_PS_NO_CHANGE: 1704 status_str = "target responding"; 1705 break; 1706 default: 1707 status_str = "unknown"; 1708 break; 1709 } 1710 link_rate = event_data->PortEntry[i].CurrentPortInfo & 1711 MPI3_EVENT_PCIE_TOPO_PI_RATE_MASK; 1712 prev_link_rate = event_data->PortEntry[i].PreviousPortInfo & 1713 MPI3_EVENT_PCIE_TOPO_PI_RATE_MASK; 1714 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :\tport(%02d), attached_handle(0x%04x): %s:" 1715 " link rate: new(0x%02x), old(0x%02x)\n", __func__, 1716 port_number, handle, status_str, link_rate, prev_link_rate); 1717 } 1718 } 1719 1720 static void mpi3mr_process_pcietopochg_evt(struct mpi3mr_softc *sc, 1721 struct mpi3mr_fw_event_work *fwevt) 1722 { 1723 Mpi3EventDataPcieTopologyChangeList_t *event_data = 1724 (Mpi3EventDataPcieTopologyChangeList_t *)fwevt->event_data; 1725 int i; 1726 U16 handle; 1727 U8 reason_code, link_rate; 1728 struct mpi3mr_target *target = NULL; 1729 1730 1731 mpi3mr_pcietopochg_evt_debug(sc, event_data); 1732 1733 for (i = 0; i < event_data->NumEntries; i++) { 1734 handle = 1735 le16toh(event_data->PortEntry[i].AttachedDevHandle); 1736 if (!handle) 1737 continue; 1738 target = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle); 1739 if (!target) 1740 continue; 1741 1742 link_rate = event_data->PortEntry[i].CurrentPortInfo & 1743 MPI3_EVENT_PCIE_TOPO_PI_RATE_MASK; 1744 target->link_rate = link_rate; 1745 1746 reason_code = event_data->PortEntry[i].PortStatus; 1747 1748 switch (reason_code) { 1749 case MPI3_EVENT_PCIE_TOPO_PS_NOT_RESPONDING: 1750 if (target->exposed_to_os) 1751 mpi3mr_remove_device_from_os(sc, target->dev_handle); 1752 mpi3mr_remove_device_from_list(sc, target, false); 1753 break; 1754 case MPI3_EVENT_PCIE_TOPO_PS_PORT_CHANGED: 1755 break; 1756 default: 1757 break; 1758 } 1759 } 1760 1761 /* 1762 * refcount was incremented for this event in 1763 * mpi3mr_evt_handler. Decrement it here because the event has 1764 * been processed. 1765 */ 1766 mpi3mr_startup_decrement(sc->cam_sc); 1767 return; 1768 } 1769 1770 void mpi3mr_add_device(struct mpi3mr_softc *sc, U16 per_id) 1771 { 1772 struct mpi3mr_target *target; 1773 1774 mpi3mr_dprint(sc, MPI3MR_EVENT, 1775 "Adding device(persistent id: 0x%x)\n", per_id); 1776 1777 mpi3mr_startup_increment(sc->cam_sc); 1778 target = mpi3mr_find_target_by_per_id(sc->cam_sc, per_id); 1779 1780 if (!target) { 1781 mpi3mr_dprint(sc, MPI3MR_INFO, "Not available in driver's" 1782 "internal target list, persistent_id: %d\n", 1783 per_id); 1784 goto out; 1785 } 1786 1787 if (target->is_hidden) { 1788 mpi3mr_dprint(sc, MPI3MR_EVENT, "Target is hidden, persistent_id: %d\n", 1789 per_id); 1790 goto out; 1791 } 1792 1793 if (!target->exposed_to_os && !sc->reset_in_progress) { 1794 mpi3mr_rescan_target(sc, target); 1795 mpi3mr_dprint(sc, MPI3MR_INFO, 1796 "Added device persistent_id: %d dev_handle: %d\n", per_id, target->dev_handle); 1797 target->exposed_to_os = 1; 1798 } 1799 1800 out: 1801 mpi3mr_startup_decrement(sc->cam_sc); 1802 } 1803 1804 int mpi3mr_remove_device_from_os(struct mpi3mr_softc *sc, U16 handle) 1805 { 1806 U32 i = 0; 1807 int retval = 0; 1808 struct mpi3mr_target *target; 1809 1810 mpi3mr_dprint(sc, MPI3MR_EVENT, 1811 "Removing Device (dev_handle: %d)\n", handle); 1812 1813 target = mpi3mr_find_target_by_dev_handle(sc->cam_sc, handle); 1814 1815 if (!target) { 1816 mpi3mr_dprint(sc, MPI3MR_INFO, 1817 "Device (persistent_id: %d dev_handle: %d) is already removed from driver's list\n", 1818 target->per_id, handle); 1819 mpi3mr_rescan_target(sc, NULL); 1820 retval = -1; 1821 goto out; 1822 } 1823 1824 target->flags |= MPI3MRSAS_TARGET_INREMOVAL; 1825 1826 while (mpi3mr_atomic_read(&target->outstanding) && (i < 30)) { 1827 i++; 1828 if (!(i % 2)) { 1829 mpi3mr_dprint(sc, MPI3MR_INFO, 1830 "[%2d]waiting for " 1831 "waiting for outstanding commands to complete on target: %d\n", 1832 i, target->per_id); 1833 } 1834 DELAY(1000 * 1000); 1835 } 1836 1837 if (target->exposed_to_os && !sc->reset_in_progress) { 1838 mpi3mr_rescan_target(sc, target); 1839 mpi3mr_dprint(sc, MPI3MR_INFO, 1840 "Removed device(persistent_id: %d dev_handle: %d)\n", target->per_id, handle); 1841 target->exposed_to_os = 0; 1842 } 1843 1844 target->flags &= ~MPI3MRSAS_TARGET_INREMOVAL; 1845 out: 1846 return retval; 1847 } 1848 1849 void mpi3mr_remove_device_from_list(struct mpi3mr_softc *sc, 1850 struct mpi3mr_target *target, bool must_delete) 1851 { 1852 mtx_lock_spin(&sc->target_lock); 1853 if ((target->state == MPI3MR_DEV_REMOVE_HS_STARTED) || 1854 (must_delete == true)) { 1855 TAILQ_REMOVE(&sc->cam_sc->tgt_list, target, tgt_next); 1856 target->state = MPI3MR_DEV_DELETED; 1857 } 1858 mtx_unlock_spin(&sc->target_lock); 1859 1860 if (target->state == MPI3MR_DEV_DELETED) { 1861 free(target, M_MPI3MR); 1862 target = NULL; 1863 } 1864 1865 return; 1866 } 1867 1868 /** 1869 * mpi3mr_devstatuschg_evt_bh - DevStatusChange evt bottomhalf 1870 * @sc: Adapter instance reference 1871 * @fwevt: Firmware event 1872 * 1873 * Process Device Status Change event and based on device's new 1874 * information, either expose the device to the upper layers, or 1875 * remove the device from upper layers. 1876 * 1877 * Return: Nothing. 1878 */ 1879 static void mpi3mr_devstatuschg_evt_bh(struct mpi3mr_softc *sc, 1880 struct mpi3mr_fw_event_work *fwevt) 1881 { 1882 U16 dev_handle = 0; 1883 U8 uhide = 0, delete = 0, cleanup = 0; 1884 struct mpi3mr_target *tgtdev = NULL; 1885 Mpi3EventDataDeviceStatusChange_t *evtdata = 1886 (Mpi3EventDataDeviceStatusChange_t *)fwevt->event_data; 1887 1888 1889 1890 dev_handle = le16toh(evtdata->DevHandle); 1891 mpi3mr_dprint(sc, MPI3MR_INFO, 1892 "%s :device status change: handle(0x%04x): reason code(0x%x)\n", 1893 __func__, dev_handle, evtdata->ReasonCode); 1894 switch (evtdata->ReasonCode) { 1895 case MPI3_EVENT_DEV_STAT_RC_HIDDEN: 1896 delete = 1; 1897 break; 1898 case MPI3_EVENT_DEV_STAT_RC_NOT_HIDDEN: 1899 uhide = 1; 1900 break; 1901 case MPI3_EVENT_DEV_STAT_RC_VD_NOT_RESPONDING: 1902 delete = 1; 1903 cleanup = 1; 1904 break; 1905 default: 1906 mpi3mr_dprint(sc, MPI3MR_INFO, "%s :Unhandled reason code(0x%x)\n", __func__, 1907 evtdata->ReasonCode); 1908 break; 1909 } 1910 1911 tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, dev_handle); 1912 if (!tgtdev) 1913 return; 1914 1915 if (uhide) { 1916 if (!tgtdev->exposed_to_os) 1917 mpi3mr_add_device(sc, tgtdev->per_id); 1918 } 1919 1920 if (delete) 1921 mpi3mr_remove_device_from_os(sc, dev_handle); 1922 1923 if (cleanup) 1924 mpi3mr_remove_device_from_list(sc, tgtdev, false); 1925 } 1926 1927 /** 1928 * mpi3mr_devinfochg_evt_bh - DeviceInfoChange evt bottomhalf 1929 * @sc: Adapter instance reference 1930 * @dev_pg0: New device page0 1931 * 1932 * Process Device Info Change event and based on device's new 1933 * information, either expose the device to the upper layers, or 1934 * remove the device from upper layers or update the details of 1935 * the device. 1936 * 1937 * Return: Nothing. 1938 */ 1939 static void mpi3mr_devinfochg_evt_bh(struct mpi3mr_softc *sc, 1940 Mpi3DevicePage0_t *dev_pg0) 1941 { 1942 struct mpi3mr_target *tgtdev = NULL; 1943 U16 dev_handle = 0, perst_id = 0; 1944 1945 perst_id = le16toh(dev_pg0->PersistentID); 1946 dev_handle = le16toh(dev_pg0->DevHandle); 1947 mpi3mr_dprint(sc, MPI3MR_INFO, 1948 "%s :Device info change: handle(0x%04x): persist_id(0x%x)\n", 1949 __func__, dev_handle, perst_id); 1950 tgtdev = mpi3mr_find_target_by_dev_handle(sc->cam_sc, dev_handle); 1951 if (!tgtdev) 1952 return; 1953 1954 mpi3mr_update_device(sc, tgtdev, dev_pg0, false); 1955 if (!tgtdev->is_hidden && !tgtdev->exposed_to_os) 1956 mpi3mr_add_device(sc, perst_id); 1957 1958 if (tgtdev->is_hidden && tgtdev->exposed_to_os) 1959 mpi3mr_remove_device_from_os(sc, tgtdev->dev_handle); 1960 } 1961 1962 static void 1963 mpi3mr_fw_work(struct mpi3mr_softc *sc, struct mpi3mr_fw_event_work *fw_event) 1964 { 1965 if (sc->mpi3mr_flags & MPI3MR_FLAGS_SHUTDOWN) 1966 goto out; 1967 1968 if (!fw_event->process_event) 1969 goto evt_ack; 1970 1971 mpi3mr_dprint(sc, MPI3MR_EVENT, "(%d)->(%s) Working on Event: [%x]\n", 1972 event_count++, __func__, fw_event->event); 1973 1974 switch (fw_event->event) { 1975 case MPI3_EVENT_DEVICE_ADDED: 1976 { 1977 Mpi3DevicePage0_t *dev_pg0 = 1978 (Mpi3DevicePage0_t *) fw_event->event_data; 1979 mpi3mr_add_device(sc, dev_pg0->PersistentID); 1980 break; 1981 } 1982 case MPI3_EVENT_DEVICE_INFO_CHANGED: 1983 { 1984 mpi3mr_devinfochg_evt_bh(sc, 1985 (Mpi3DevicePage0_t *) fw_event->event_data); 1986 break; 1987 } 1988 case MPI3_EVENT_DEVICE_STATUS_CHANGE: 1989 { 1990 mpi3mr_devstatuschg_evt_bh(sc, fw_event); 1991 break; 1992 } 1993 case MPI3_EVENT_SAS_TOPOLOGY_CHANGE_LIST: 1994 { 1995 mpi3mr_process_sastopochg_evt(sc, fw_event); 1996 break; 1997 } 1998 case MPI3_EVENT_PCIE_TOPOLOGY_CHANGE_LIST: 1999 { 2000 mpi3mr_process_pcietopochg_evt(sc, fw_event); 2001 break; 2002 } 2003 case MPI3_EVENT_LOG_DATA: 2004 { 2005 mpi3mr_logdata_evt_bh(sc, fw_event); 2006 break; 2007 } 2008 default: 2009 mpi3mr_dprint(sc, MPI3MR_TRACE,"Unhandled event 0x%0X\n", 2010 fw_event->event); 2011 break; 2012 2013 } 2014 2015 evt_ack: 2016 if (fw_event->send_ack) { 2017 mpi3mr_dprint(sc, MPI3MR_EVENT,"Process event ACK for event 0x%0X\n", 2018 fw_event->event); 2019 mpi3mr_process_event_ack(sc, fw_event->event, 2020 fw_event->event_context); 2021 } 2022 2023 out: 2024 mpi3mr_dprint(sc, MPI3MR_EVENT, "(%d)->(%s) Event Free: [%x]\n", event_count, 2025 __func__, fw_event->event); 2026 2027 mpi3mr_fw_event_free(sc, fw_event); 2028 } 2029 2030 void 2031 mpi3mr_firmware_event_work(void *arg, int pending) 2032 { 2033 struct mpi3mr_fw_event_work *fw_event; 2034 struct mpi3mr_softc *sc; 2035 2036 sc = (struct mpi3mr_softc *)arg; 2037 2038 mtx_lock(&sc->fwevt_lock); 2039 while ((fw_event = TAILQ_FIRST(&sc->cam_sc->ev_queue)) != NULL) { 2040 TAILQ_REMOVE(&sc->cam_sc->ev_queue, fw_event, ev_link); 2041 mtx_unlock(&sc->fwevt_lock); 2042 mpi3mr_fw_work(sc, fw_event); 2043 mtx_lock(&sc->fwevt_lock); 2044 } 2045 mtx_unlock(&sc->fwevt_lock); 2046 } 2047 2048 2049 /* 2050 * mpi3mr_cam_attach - CAM layer registration 2051 * @sc: Adapter reference 2052 * 2053 * This function does simq allocation, cam registration, xpt_bus registration, 2054 * event taskqueue initialization and async event handler registration. 2055 * 2056 * Return: 0 on success and proper error codes on failure 2057 */ 2058 int 2059 mpi3mr_cam_attach(struct mpi3mr_softc *sc) 2060 { 2061 struct mpi3mr_cam_softc *cam_sc; 2062 cam_status status; 2063 int unit, error = 0, reqs; 2064 2065 mpi3mr_dprint(sc, MPI3MR_XINFO, "Starting CAM Attach\n"); 2066 2067 cam_sc = malloc(sizeof(struct mpi3mr_cam_softc), M_MPI3MR, M_WAITOK|M_ZERO); 2068 if (!cam_sc) { 2069 mpi3mr_dprint(sc, MPI3MR_ERROR, 2070 "Failed to allocate memory for controller CAM instance\n"); 2071 return (ENOMEM); 2072 } 2073 2074 cam_sc->maxtargets = sc->facts.max_perids + 1; 2075 2076 TAILQ_INIT(&cam_sc->tgt_list); 2077 2078 sc->cam_sc = cam_sc; 2079 cam_sc->sc = sc; 2080 2081 reqs = sc->max_host_ios; 2082 2083 if ((cam_sc->devq = cam_simq_alloc(reqs)) == NULL) { 2084 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate SIMQ\n"); 2085 error = ENOMEM; 2086 goto out; 2087 } 2088 2089 unit = device_get_unit(sc->mpi3mr_dev); 2090 cam_sc->sim = cam_sim_alloc(mpi3mr_cam_action, mpi3mr_cam_poll, "mpi3mr", cam_sc, 2091 unit, &sc->mpi3mr_mtx, reqs, reqs, cam_sc->devq); 2092 if (cam_sc->sim == NULL) { 2093 mpi3mr_dprint(sc, MPI3MR_ERROR, "Failed to allocate SIM\n"); 2094 error = EINVAL; 2095 goto out; 2096 } 2097 2098 TAILQ_INIT(&cam_sc->ev_queue); 2099 2100 /* Initialize taskqueue for Event Handling */ 2101 TASK_INIT(&cam_sc->ev_task, 0, mpi3mr_firmware_event_work, sc); 2102 cam_sc->ev_tq = taskqueue_create("mpi3mr_taskq", M_NOWAIT | M_ZERO, 2103 taskqueue_thread_enqueue, &cam_sc->ev_tq); 2104 taskqueue_start_threads(&cam_sc->ev_tq, 1, PRIBIO, "%s taskq", 2105 device_get_nameunit(sc->mpi3mr_dev)); 2106 2107 mtx_lock(&sc->mpi3mr_mtx); 2108 2109 /* 2110 * XXX There should be a bus for every port on the adapter, but since 2111 * we're just going to fake the topology for now, we'll pretend that 2112 * everything is just a target on a single bus. 2113 */ 2114 if ((error = xpt_bus_register(cam_sc->sim, sc->mpi3mr_dev, 0)) != 0) { 2115 mpi3mr_dprint(sc, MPI3MR_ERROR, 2116 "Error 0x%x registering SCSI bus\n", error); 2117 mtx_unlock(&sc->mpi3mr_mtx); 2118 goto out; 2119 } 2120 2121 /* 2122 * Assume that discovery events will start right away. 2123 * 2124 * Hold off boot until discovery is complete. 2125 */ 2126 cam_sc->flags |= MPI3MRSAS_IN_STARTUP | MPI3MRSAS_IN_DISCOVERY; 2127 sc->cam_sc->startup_refcount = 0; 2128 mpi3mr_startup_increment(cam_sc); 2129 2130 callout_init(&cam_sc->discovery_callout, 1 /*mpsafe*/); 2131 2132 /* 2133 * Register for async events so we can determine the EEDP 2134 * capabilities of devices. 2135 */ 2136 status = xpt_create_path(&cam_sc->path, /*periph*/NULL, 2137 cam_sim_path(sc->cam_sc->sim), CAM_TARGET_WILDCARD, 2138 CAM_LUN_WILDCARD); 2139 if (status != CAM_REQ_CMP) { 2140 mpi3mr_dprint(sc, MPI3MR_ERROR, 2141 "Error 0x%x creating sim path\n", status); 2142 cam_sc->path = NULL; 2143 } 2144 2145 if (status != CAM_REQ_CMP) { 2146 /* 2147 * EEDP use is the exception, not the rule. 2148 * Warn the user, but do not fail to attach. 2149 */ 2150 mpi3mr_dprint(sc, MPI3MR_INFO, "EEDP capabilities disabled.\n"); 2151 } 2152 2153 mtx_unlock(&sc->mpi3mr_mtx); 2154 2155 error = mpi3mr_register_events(sc); 2156 2157 out: 2158 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s Exiting CAM attach, error: 0x%x n", __func__, error); 2159 return (error); 2160 } 2161 2162 int 2163 mpi3mr_cam_detach(struct mpi3mr_softc *sc) 2164 { 2165 struct mpi3mr_cam_softc *cam_sc; 2166 struct mpi3mr_target *target; 2167 2168 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s, Starting CAM detach\n", __func__); 2169 if (sc->cam_sc == NULL) 2170 return (0); 2171 2172 cam_sc = sc->cam_sc; 2173 2174 mpi3mr_freeup_events(sc); 2175 2176 /* 2177 * Drain and free the event handling taskqueue with the lock 2178 * unheld so that any parallel processing tasks drain properly 2179 * without deadlocking. 2180 */ 2181 if (cam_sc->ev_tq != NULL) 2182 taskqueue_free(cam_sc->ev_tq); 2183 2184 mtx_lock(&sc->mpi3mr_mtx); 2185 2186 while (cam_sc->startup_refcount != 0) 2187 mpi3mr_startup_decrement(cam_sc); 2188 2189 /* Deregister our async handler */ 2190 if (cam_sc->path != NULL) { 2191 xpt_free_path(cam_sc->path); 2192 cam_sc->path = NULL; 2193 } 2194 2195 if (cam_sc->flags & MPI3MRSAS_IN_STARTUP) 2196 xpt_release_simq(cam_sc->sim, 1); 2197 2198 if (cam_sc->sim != NULL) { 2199 xpt_bus_deregister(cam_sim_path(cam_sc->sim)); 2200 cam_sim_free(cam_sc->sim, FALSE); 2201 } 2202 2203 mtx_unlock(&sc->mpi3mr_mtx); 2204 2205 if (cam_sc->devq != NULL) 2206 cam_simq_free(cam_sc->devq); 2207 2208 get_target: 2209 mtx_lock_spin(&sc->target_lock); 2210 TAILQ_FOREACH(target, &cam_sc->tgt_list, tgt_next) { 2211 TAILQ_REMOVE(&sc->cam_sc->tgt_list, target, tgt_next); 2212 mtx_unlock_spin(&sc->target_lock); 2213 goto out_tgt_free; 2214 } 2215 mtx_unlock_spin(&sc->target_lock); 2216 out_tgt_free: 2217 if (target) { 2218 free(target, M_MPI3MR); 2219 target = NULL; 2220 goto get_target; 2221 } 2222 2223 free(cam_sc, M_MPI3MR); 2224 sc->cam_sc = NULL; 2225 2226 mpi3mr_dprint(sc, MPI3MR_XINFO, "%s, Exiting CAM detach\n", __func__); 2227 return (0); 2228 } 2229