1 /*- 2 * Copyright (c) 2017 Broadcom. All rights reserved. 3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 /** 35 * @defgroup scsi_api_target SCSI Target API 36 * @defgroup scsi_api_initiator SCSI Initiator API 37 * @defgroup cam_api Common Access Method (CAM) API 38 * @defgroup cam_io CAM IO 39 */ 40 41 /** 42 * @file 43 * Provides CAM functionality. 44 */ 45 46 #include "ocs.h" 47 #include "ocs_scsi.h" 48 #include "ocs_device.h" 49 50 /* Default IO timeout value for initiators is 30 seconds */ 51 #define OCS_CAM_IO_TIMEOUT 30 52 53 typedef struct { 54 ocs_scsi_sgl_t *sgl; 55 uint32_t sgl_max; 56 uint32_t sgl_count; 57 int32_t rc; 58 } ocs_dmamap_load_arg_t; 59 60 static void ocs_action(struct cam_sim *, union ccb *); 61 static void ocs_poll(struct cam_sim *); 62 63 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *, 64 struct ccb_hdr *, uint32_t *); 65 static int32_t ocs_tgt_resource_abort(struct ocs_softc *, ocs_tgt_resource_t *); 66 static uint32_t ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb); 67 static void ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb); 68 static void ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb); 69 static int32_t ocs_target_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *); 70 static int32_t ocs_io_abort_cb(ocs_io_t *, ocs_scsi_io_status_e, uint32_t, void *); 71 static int32_t ocs_task_set_full_or_busy(ocs_io_t *io); 72 static int32_t ocs_initiator_tmf_cb(ocs_io_t *, ocs_scsi_io_status_e, 73 ocs_scsi_cmd_resp_t *, uint32_t, void *); 74 static uint32_t 75 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role); 76 77 static void ocs_ldt(void *arg); 78 static void ocs_ldt_task(void *arg, int pending); 79 static void ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt); 80 uint32_t ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp); 81 uint32_t ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id); 82 83 int32_t ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node); 84 85 static inline ocs_io_t *ocs_scsi_find_io(struct ocs_softc *ocs, uint32_t tag) 86 { 87 88 return ocs_io_get_instance(ocs, tag); 89 } 90 91 static inline void ocs_target_io_free(ocs_io_t *io) 92 { 93 io->tgt_io.state = OCS_CAM_IO_FREE; 94 io->tgt_io.flags = 0; 95 io->tgt_io.app = NULL; 96 ocs_scsi_io_complete(io); 97 if(io->ocs->io_in_use != 0) 98 atomic_subtract_acq_32(&io->ocs->io_in_use, 1); 99 } 100 101 static int32_t 102 ocs_attach_port(ocs_t *ocs, int chan) 103 { 104 105 struct cam_sim *sim = NULL; 106 struct cam_path *path = NULL; 107 uint32_t max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS); 108 ocs_fcport *fcp = FCPORT(ocs, chan); 109 110 if (NULL == (sim = cam_sim_alloc(ocs_action, ocs_poll, 111 device_get_name(ocs->dev), ocs, 112 device_get_unit(ocs->dev), &ocs->sim_lock, 113 max_io, max_io, ocs->devq))) { 114 device_printf(ocs->dev, "Can't allocate SIM\n"); 115 return 1; 116 } 117 118 mtx_lock(&ocs->sim_lock); 119 if (CAM_SUCCESS != xpt_bus_register(sim, ocs->dev, chan)) { 120 device_printf(ocs->dev, "Can't register bus %d\n", 0); 121 mtx_unlock(&ocs->sim_lock); 122 cam_sim_free(sim, FALSE); 123 return 1; 124 } 125 mtx_unlock(&ocs->sim_lock); 126 127 if (CAM_REQ_CMP != xpt_create_path(&path, NULL, cam_sim_path(sim), 128 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD)) { 129 device_printf(ocs->dev, "Can't create path\n"); 130 xpt_bus_deregister(cam_sim_path(sim)); 131 mtx_unlock(&ocs->sim_lock); 132 cam_sim_free(sim, FALSE); 133 return 1; 134 } 135 136 fcp->ocs = ocs; 137 fcp->sim = sim; 138 fcp->path = path; 139 140 callout_init_mtx(&fcp->ldt, &ocs->sim_lock, 0); 141 TASK_INIT(&fcp->ltask, 1, ocs_ldt_task, fcp); 142 143 return 0; 144 } 145 146 static int32_t 147 ocs_detach_port(ocs_t *ocs, int32_t chan) 148 { 149 ocs_fcport *fcp = NULL; 150 struct cam_sim *sim = NULL; 151 struct cam_path *path = NULL; 152 fcp = FCPORT(ocs, chan); 153 154 sim = fcp->sim; 155 path = fcp->path; 156 157 callout_drain(&fcp->ldt); 158 ocs_ldt_task(fcp, 0); 159 160 if (fcp->sim) { 161 mtx_lock(&ocs->sim_lock); 162 ocs_tgt_resource_abort(ocs, &fcp->targ_rsrc_wildcard); 163 if (path) { 164 xpt_async(AC_LOST_DEVICE, path, NULL); 165 xpt_free_path(path); 166 fcp->path = NULL; 167 } 168 xpt_bus_deregister(cam_sim_path(sim)); 169 170 cam_sim_free(sim, FALSE); 171 fcp->sim = NULL; 172 mtx_unlock(&ocs->sim_lock); 173 } 174 175 return 0; 176 } 177 178 int32_t 179 ocs_cam_attach(ocs_t *ocs) 180 { 181 struct cam_devq *devq = NULL; 182 int i = 0; 183 uint32_t max_io = ocs_scsi_get_property(ocs, OCS_SCSI_MAX_IOS); 184 185 if (NULL == (devq = cam_simq_alloc(max_io))) { 186 device_printf(ocs->dev, "Can't allocate SIMQ\n"); 187 return -1; 188 } 189 190 ocs->devq = devq; 191 192 if (mtx_initialized(&ocs->sim_lock) == 0) { 193 mtx_init(&ocs->sim_lock, "ocs_sim_lock", NULL, MTX_DEF); 194 } 195 196 for (i = 0; i < (ocs->num_vports + 1); i++) { 197 if (ocs_attach_port(ocs, i)) { 198 ocs_log_err(ocs, "Attach port failed for chan: %d\n", i); 199 goto detach_port; 200 } 201 } 202 203 ocs->io_high_watermark = max_io; 204 ocs->io_in_use = 0; 205 return 0; 206 207 detach_port: 208 while (--i >= 0) { 209 ocs_detach_port(ocs, i); 210 } 211 212 cam_simq_free(ocs->devq); 213 214 if (mtx_initialized(&ocs->sim_lock)) 215 mtx_destroy(&ocs->sim_lock); 216 217 return 1; 218 } 219 220 int32_t 221 ocs_cam_detach(ocs_t *ocs) 222 { 223 int i = 0; 224 225 for (i = (ocs->num_vports); i >= 0; i--) { 226 ocs_detach_port(ocs, i); 227 } 228 229 cam_simq_free(ocs->devq); 230 231 if (mtx_initialized(&ocs->sim_lock)) 232 mtx_destroy(&ocs->sim_lock); 233 234 return 0; 235 } 236 237 /*************************************************************************** 238 * Functions required by SCSI base driver API 239 */ 240 241 /** 242 * @ingroup scsi_api_target 243 * @brief Attach driver to the BSD SCSI layer (a.k.a CAM) 244 * 245 * Allocates + initializes CAM related resources and attaches to the CAM 246 * 247 * @param ocs the driver instance's software context 248 * 249 * @return 0 on success, non-zero otherwise 250 */ 251 int32_t 252 ocs_scsi_tgt_new_device(ocs_t *ocs) 253 { 254 ocs->enable_task_set_full = ocs_scsi_get_property(ocs, 255 OCS_SCSI_ENABLE_TASK_SET_FULL); 256 ocs_log_debug(ocs, "task set full processing is %s\n", 257 ocs->enable_task_set_full ? "enabled" : "disabled"); 258 259 return 0; 260 } 261 262 /** 263 * @ingroup scsi_api_target 264 * @brief Tears down target members of ocs structure. 265 * 266 * Called by OS code when device is removed. 267 * 268 * @param ocs pointer to ocs 269 * 270 * @return returns 0 for success, a negative error code value for failure. 271 */ 272 int32_t 273 ocs_scsi_tgt_del_device(ocs_t *ocs) 274 { 275 276 return 0; 277 } 278 279 /** 280 * @ingroup scsi_api_target 281 * @brief accept new domain notification 282 * 283 * Called by base drive when new domain is discovered. A target-server 284 * will use this call to prepare for new remote node notifications 285 * arising from ocs_scsi_new_initiator(). 286 * 287 * The domain context has an element <b>ocs_scsi_tgt_domain_t tgt_domain</b> 288 * which is declared by the target-server code and is used for target-server 289 * private data. 290 * 291 * This function will only be called if the base-driver has been enabled for 292 * target capability. 293 * 294 * Note that this call is made to target-server backends, 295 * the ocs_scsi_ini_new_domain() function is called to initiator-client backends. 296 * 297 * @param domain pointer to domain 298 * 299 * @return returns 0 for success, a negative error code value for failure. 300 */ 301 int32_t 302 ocs_scsi_tgt_new_domain(ocs_domain_t *domain) 303 { 304 return 0; 305 } 306 307 /** 308 * @ingroup scsi_api_target 309 * @brief accept domain lost notification 310 * 311 * Called by base-driver when a domain goes away. A target-server will 312 * use this call to clean up all domain scoped resources. 313 * 314 * Note that this call is made to target-server backends, 315 * the ocs_scsi_ini_del_domain() function is called to initiator-client backends. 316 * 317 * @param domain pointer to domain 318 * 319 * @return returns 0 for success, a negative error code value for failure. 320 */ 321 void 322 ocs_scsi_tgt_del_domain(ocs_domain_t *domain) 323 { 324 } 325 326 /** 327 * @ingroup scsi_api_target 328 * @brief accept new sli port (sport) notification 329 * 330 * Called by base drive when new sport is discovered. A target-server 331 * will use this call to prepare for new remote node notifications 332 * arising from ocs_scsi_new_initiator(). 333 * 334 * The domain context has an element <b>ocs_scsi_tgt_sport_t tgt_sport</b> 335 * which is declared by the target-server code and is used for 336 * target-server private data. 337 * 338 * This function will only be called if the base-driver has been enabled for 339 * target capability. 340 * 341 * Note that this call is made to target-server backends, 342 * the ocs_scsi_tgt_new_domain() is called to initiator-client backends. 343 * 344 * @param sport pointer to SLI port 345 * 346 * @return returns 0 for success, a negative error code value for failure. 347 */ 348 int32_t 349 ocs_scsi_tgt_new_sport(ocs_sport_t *sport) 350 { 351 ocs_t *ocs = sport->ocs; 352 353 if(!sport->is_vport) { 354 sport->tgt_data = FCPORT(ocs, 0); 355 } 356 357 return 0; 358 } 359 360 /** 361 * @ingroup scsi_api_target 362 * @brief accept SLI port gone notification 363 * 364 * Called by base-driver when a sport goes away. A target-server will 365 * use this call to clean up all sport scoped resources. 366 * 367 * Note that this call is made to target-server backends, 368 * the ocs_scsi_ini_del_sport() is called to initiator-client backends. 369 * 370 * @param sport pointer to SLI port 371 * 372 * @return returns 0 for success, a negative error code value for failure. 373 */ 374 void 375 ocs_scsi_tgt_del_sport(ocs_sport_t *sport) 376 { 377 return; 378 } 379 380 /** 381 * @ingroup scsi_api_target 382 * @brief receive notification of a new SCSI initiator node 383 * 384 * Sent by base driver to notify a target-server of the presense of a new 385 * remote initiator. The target-server may use this call to prepare for 386 * inbound IO from this node. 387 * 388 * The ocs_node_t structure has and elment of type ocs_scsi_tgt_node_t named 389 * tgt_node that is declared and used by a target-server for private 390 * information. 391 * 392 * This function is only called if the target capability is enabled in driver. 393 * 394 * @param node pointer to new remote initiator node 395 * 396 * @return returns 0 for success, a negative error code value for failure. 397 * 398 * @note 399 */ 400 int32_t 401 ocs_scsi_new_initiator(ocs_node_t *node) 402 { 403 ocs_t *ocs = node->ocs; 404 struct ac_contract ac; 405 struct ac_device_changed *adc; 406 407 ocs_fcport *fcp = NULL; 408 409 fcp = node->sport->tgt_data; 410 if (fcp == NULL) { 411 ocs_log_err(ocs, "FCP is NULL \n"); 412 return 1; 413 } 414 415 /* 416 * Update the IO watermark by decrementing it by the 417 * number of IOs reserved for each initiator. 418 */ 419 atomic_subtract_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO); 420 421 ac.contract_number = AC_CONTRACT_DEV_CHG; 422 adc = (struct ac_device_changed *) ac.contract_data; 423 adc->wwpn = ocs_node_get_wwpn(node); 424 adc->port = node->rnode.fc_id; 425 adc->target = node->instance_index; 426 adc->arrived = 1; 427 xpt_async(AC_CONTRACT, fcp->path, &ac); 428 429 return 0; 430 } 431 432 /** 433 * @ingroup scsi_api_target 434 * @brief validate new initiator 435 * 436 * Sent by base driver to validate a remote initiatiator. The target-server 437 * returns TRUE if this initiator should be accepted. 438 * 439 * This function is only called if the target capability is enabled in driver. 440 * 441 * @param node pointer to remote initiator node to validate 442 * 443 * @return TRUE if initiator should be accepted, FALSE if it should be rejected 444 * 445 * @note 446 */ 447 448 int32_t 449 ocs_scsi_validate_initiator(ocs_node_t *node) 450 { 451 return 1; 452 } 453 454 /** 455 * @ingroup scsi_api_target 456 * @brief Delete a SCSI initiator node 457 * 458 * Sent by base driver to notify a target-server that a remote initiator 459 * is now gone. The base driver will have terminated all outstanding IOs 460 * and the target-server will receive appropriate completions. 461 * 462 * This function is only called if the base driver is enabled for 463 * target capability. 464 * 465 * @param node pointer node being deleted 466 * @param reason Reason why initiator is gone. 467 * 468 * @return OCS_SCSI_CALL_COMPLETE to indicate that all work was completed 469 * 470 * @note 471 */ 472 int32_t 473 ocs_scsi_del_initiator(ocs_node_t *node, ocs_scsi_del_initiator_reason_e reason) 474 { 475 ocs_t *ocs = node->ocs; 476 477 struct ac_contract ac; 478 struct ac_device_changed *adc; 479 ocs_fcport *fcp = NULL; 480 481 fcp = node->sport->tgt_data; 482 if (fcp == NULL) { 483 ocs_log_err(ocs, "FCP is NULL \n"); 484 return 1; 485 } 486 487 ac.contract_number = AC_CONTRACT_DEV_CHG; 488 adc = (struct ac_device_changed *) ac.contract_data; 489 adc->wwpn = ocs_node_get_wwpn(node); 490 adc->port = node->rnode.fc_id; 491 adc->target = node->instance_index; 492 adc->arrived = 0; 493 xpt_async(AC_CONTRACT, fcp->path, &ac); 494 495 if (reason == OCS_SCSI_INITIATOR_MISSING) { 496 return OCS_SCSI_CALL_COMPLETE; 497 } 498 499 /* 500 * Update the IO watermark by incrementing it by the 501 * number of IOs reserved for each initiator. 502 */ 503 atomic_add_acq_32(&ocs->io_high_watermark, OCS_RSVD_INI_IO); 504 505 return OCS_SCSI_CALL_COMPLETE; 506 } 507 508 /** 509 * @ingroup scsi_api_target 510 * @brief receive FCP SCSI Command 511 * 512 * Called by the base driver when a new SCSI command has been received. The 513 * target-server will process the command, and issue data and/or response phase 514 * requests to the base driver. 515 * 516 * The IO context (ocs_io_t) structure has and element of type 517 * ocs_scsi_tgt_io_t named tgt_io that is declared and used by 518 * a target-server for private information. 519 * 520 * @param io pointer to IO context 521 * @param lun LUN for this IO 522 * @param cdb pointer to SCSI CDB 523 * @param cdb_len length of CDB in bytes 524 * @param flags command flags 525 * 526 * @return returns 0 for success, a negative error code value for failure. 527 */ 528 int32_t ocs_scsi_recv_cmd(ocs_io_t *io, uint64_t lun, uint8_t *cdb, 529 uint32_t cdb_len, uint32_t flags) 530 { 531 ocs_t *ocs = io->ocs; 532 struct ccb_accept_tio *atio = NULL; 533 ocs_node_t *node = io->node; 534 ocs_tgt_resource_t *trsrc = NULL; 535 int32_t rc = -1; 536 ocs_fcport *fcp = NULL; 537 538 fcp = node->sport->tgt_data; 539 if (fcp == NULL) { 540 ocs_log_err(ocs, "FCP is NULL \n"); 541 return 1; 542 } 543 544 atomic_add_acq_32(&ocs->io_in_use, 1); 545 546 /* set target io timeout */ 547 io->timeout = ocs->target_io_timer_sec; 548 549 if (ocs->enable_task_set_full && 550 (ocs->io_in_use >= ocs->io_high_watermark)) { 551 return ocs_task_set_full_or_busy(io); 552 } else { 553 atomic_store_rel_32(&io->node->tgt_node.busy_sent, FALSE); 554 } 555 556 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) { 557 trsrc = &fcp->targ_rsrc[lun]; 558 } else if (fcp->targ_rsrc_wildcard.enabled) { 559 trsrc = &fcp->targ_rsrc_wildcard; 560 } 561 562 if (trsrc) { 563 atio = (struct ccb_accept_tio *)STAILQ_FIRST(&trsrc->atio); 564 } 565 566 if (atio) { 567 STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe); 568 569 atio->ccb_h.status = CAM_CDB_RECVD; 570 atio->ccb_h.target_lun = lun; 571 atio->sense_len = 0; 572 573 atio->init_id = node->instance_index; 574 atio->tag_id = io->tag; 575 atio->ccb_h.ccb_io_ptr = io; 576 577 if (flags & OCS_SCSI_CMD_SIMPLE) 578 atio->tag_action = MSG_SIMPLE_Q_TAG; 579 else if (flags & FCP_TASK_ATTR_HEAD_OF_QUEUE) 580 atio->tag_action = MSG_HEAD_OF_Q_TAG; 581 else if (flags & FCP_TASK_ATTR_ORDERED) 582 atio->tag_action = MSG_ORDERED_Q_TAG; 583 else 584 atio->tag_action = 0; 585 586 atio->cdb_len = cdb_len; 587 ocs_memcpy(atio->cdb_io.cdb_bytes, cdb, cdb_len); 588 589 io->tgt_io.flags = 0; 590 io->tgt_io.state = OCS_CAM_IO_COMMAND; 591 io->tgt_io.lun = lun; 592 593 xpt_done((union ccb *)atio); 594 595 rc = 0; 596 } else { 597 device_printf( 598 ocs->dev, "%s: no ATIO for LUN %lx (en=%s) OX_ID %#x\n", 599 __func__, (unsigned long)lun, 600 trsrc ? (trsrc->enabled ? "T" : "F") : "X", 601 be16toh(io->init_task_tag)); 602 603 io->tgt_io.state = OCS_CAM_IO_MAX; 604 ocs_target_io_free(io); 605 } 606 607 return rc; 608 } 609 610 /** 611 * @ingroup scsi_api_target 612 * @brief receive FCP SCSI Command with first burst data. 613 * 614 * Receive a new FCP SCSI command from the base driver with first burst data. 615 * 616 * @param io pointer to IO context 617 * @param lun LUN for this IO 618 * @param cdb pointer to SCSI CDB 619 * @param cdb_len length of CDB in bytes 620 * @param flags command flags 621 * @param first_burst_buffers first burst buffers 622 * @param first_burst_buffer_count The number of bytes received in the first burst 623 * 624 * @return returns 0 for success, a negative error code value for failure. 625 */ 626 int32_t ocs_scsi_recv_cmd_first_burst(ocs_io_t *io, uint64_t lun, uint8_t *cdb, 627 uint32_t cdb_len, uint32_t flags, 628 ocs_dma_t first_burst_buffers[], 629 uint32_t first_burst_buffer_count) 630 { 631 return -1; 632 } 633 634 /** 635 * @ingroup scsi_api_target 636 * @brief receive a TMF command IO 637 * 638 * Called by the base driver when a SCSI TMF command has been received. The 639 * target-server will process the command, aborting commands as needed, and post 640 * a response using ocs_scsi_send_resp() 641 * 642 * The IO context (ocs_io_t) structure has and element of type ocs_scsi_tgt_io_t named 643 * tgt_io that is declared and used by a target-server for private information. 644 * 645 * If the target-server walks the nodes active_ios linked list, and starts IO 646 * abort processing, the code <b>must</b> be sure not to abort the IO passed into the 647 * ocs_scsi_recv_tmf() command. 648 * 649 * @param tmfio pointer to IO context 650 * @param lun logical unit value 651 * @param cmd command request 652 * @param abortio pointer to IO object to abort for TASK_ABORT (NULL for all other TMF) 653 * @param flags flags 654 * 655 * @return returns 0 for success, a negative error code value for failure. 656 */ 657 int32_t ocs_scsi_recv_tmf(ocs_io_t *tmfio, uint64_t lun, ocs_scsi_tmf_cmd_e cmd, 658 ocs_io_t *abortio, uint32_t flags) 659 { 660 ocs_t *ocs = tmfio->ocs; 661 ocs_node_t *node = tmfio->node; 662 ocs_tgt_resource_t *trsrc = NULL; 663 struct ccb_immediate_notify *inot = NULL; 664 int32_t rc = -1; 665 ocs_fcport *fcp = NULL; 666 667 fcp = node->sport->tgt_data; 668 if (fcp == NULL) { 669 ocs_log_err(ocs, "FCP is NULL \n"); 670 return 1; 671 } 672 673 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) { 674 trsrc = &fcp->targ_rsrc[lun]; 675 } else if (fcp->targ_rsrc_wildcard.enabled) { 676 trsrc = &fcp->targ_rsrc_wildcard; 677 } 678 679 device_printf(tmfio->ocs->dev, "%s: io=%p cmd=%#x LU=%lx en=%s\n", 680 __func__, tmfio, cmd, (unsigned long)lun, 681 trsrc ? (trsrc->enabled ? "T" : "F") : "X"); 682 if (trsrc) { 683 inot = (struct ccb_immediate_notify *)STAILQ_FIRST(&trsrc->inot); 684 } 685 686 if (!inot) { 687 device_printf( 688 ocs->dev, "%s: no INOT for LUN %llx (en=%s) OX_ID %#x\n", 689 __func__, (unsigned long long)lun, trsrc ? (trsrc->enabled ? "T" : "F") : "X", 690 be16toh(tmfio->init_task_tag)); 691 692 if (abortio) { 693 ocs_scsi_io_complete(abortio); 694 } 695 ocs_scsi_io_complete(tmfio); 696 goto ocs_scsi_recv_tmf_out; 697 } 698 699 tmfio->tgt_io.app = abortio; 700 701 STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe); 702 703 inot->tag_id = tmfio->tag; 704 inot->seq_id = tmfio->tag; 705 706 if ((lun < OCS_MAX_LUN) && fcp->targ_rsrc[lun].enabled) { 707 inot->initiator_id = node->instance_index; 708 } else { 709 inot->initiator_id = CAM_TARGET_WILDCARD; 710 } 711 712 inot->ccb_h.status = CAM_MESSAGE_RECV; 713 inot->ccb_h.target_lun = lun; 714 715 switch (cmd) { 716 case OCS_SCSI_TMF_ABORT_TASK: 717 inot->arg = MSG_ABORT_TASK; 718 inot->seq_id = abortio->tag; 719 device_printf(ocs->dev, "%s: ABTS IO.%#x st=%#x\n", 720 __func__, abortio->tag, abortio->tgt_io.state); 721 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_RECV; 722 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_NOTIFY; 723 break; 724 case OCS_SCSI_TMF_QUERY_TASK_SET: 725 device_printf(ocs->dev, 726 "%s: OCS_SCSI_TMF_QUERY_TASK_SET not supported\n", 727 __func__); 728 STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe); 729 ocs_scsi_io_complete(tmfio); 730 goto ocs_scsi_recv_tmf_out; 731 break; 732 case OCS_SCSI_TMF_ABORT_TASK_SET: 733 inot->arg = MSG_ABORT_TASK_SET; 734 break; 735 case OCS_SCSI_TMF_CLEAR_TASK_SET: 736 inot->arg = MSG_CLEAR_TASK_SET; 737 break; 738 case OCS_SCSI_TMF_QUERY_ASYNCHRONOUS_EVENT: 739 inot->arg = MSG_QUERY_ASYNC_EVENT; 740 break; 741 case OCS_SCSI_TMF_LOGICAL_UNIT_RESET: 742 inot->arg = MSG_LOGICAL_UNIT_RESET; 743 break; 744 case OCS_SCSI_TMF_CLEAR_ACA: 745 inot->arg = MSG_CLEAR_ACA; 746 break; 747 case OCS_SCSI_TMF_TARGET_RESET: 748 inot->arg = MSG_TARGET_RESET; 749 break; 750 default: 751 device_printf(ocs->dev, "%s: unsupported TMF %#x\n", 752 __func__, cmd); 753 STAILQ_INSERT_TAIL(&trsrc->inot, &inot->ccb_h, sim_links.stqe); 754 goto ocs_scsi_recv_tmf_out; 755 } 756 757 rc = 0; 758 759 xpt_print(inot->ccb_h.path, "%s: func=%#x stat=%#x id=%#x lun=%#x" 760 " flags=%#x tag=%#x seq=%#x ini=%#x arg=%#x\n", 761 __func__, inot->ccb_h.func_code, inot->ccb_h.status, 762 inot->ccb_h.target_id, 763 (unsigned int)inot->ccb_h.target_lun, inot->ccb_h.flags, 764 inot->tag_id, inot->seq_id, inot->initiator_id, 765 inot->arg); 766 xpt_done((union ccb *)inot); 767 768 if (abortio) { 769 abortio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_DEV; 770 rc = ocs_scsi_tgt_abort_io(abortio, ocs_io_abort_cb, tmfio); 771 } 772 773 ocs_scsi_recv_tmf_out: 774 return rc; 775 } 776 777 /** 778 * @ingroup scsi_api_initiator 779 * @brief Initializes any initiator fields on the ocs structure. 780 * 781 * Called by OS initialization code when a new device is discovered. 782 * 783 * @param ocs pointer to ocs 784 * 785 * @return returns 0 for success, a negative error code value for failure. 786 */ 787 int32_t 788 ocs_scsi_ini_new_device(ocs_t *ocs) 789 { 790 791 return 0; 792 } 793 794 /** 795 * @ingroup scsi_api_initiator 796 * @brief Tears down initiator members of ocs structure. 797 * 798 * Called by OS code when device is removed. 799 * 800 * @param ocs pointer to ocs 801 * 802 * @return returns 0 for success, a negative error code value for failure. 803 */ 804 805 int32_t 806 ocs_scsi_ini_del_device(ocs_t *ocs) 807 { 808 809 return 0; 810 } 811 812 /** 813 * @ingroup scsi_api_initiator 814 * @brief accept new domain notification 815 * 816 * Called by base drive when new domain is discovered. An initiator-client 817 * will accept this call to prepare for new remote node notifications 818 * arising from ocs_scsi_new_target(). 819 * 820 * The domain context has the element <b>ocs_scsi_ini_domain_t ini_domain</b> 821 * which is declared by the initiator-client code and is used for 822 * initiator-client private data. 823 * 824 * This function will only be called if the base-driver has been enabled for 825 * initiator capability. 826 * 827 * Note that this call is made to initiator-client backends, 828 * the ocs_scsi_tgt_new_domain() function is called to target-server backends. 829 * 830 * @param domain pointer to domain 831 * 832 * @return returns 0 for success, a negative error code value for failure. 833 */ 834 int32_t 835 ocs_scsi_ini_new_domain(ocs_domain_t *domain) 836 { 837 return 0; 838 } 839 840 /** 841 * @ingroup scsi_api_initiator 842 * @brief accept domain lost notification 843 * 844 * Called by base-driver when a domain goes away. An initiator-client will 845 * use this call to clean up all domain scoped resources. 846 * 847 * This function will only be called if the base-driver has been enabled for 848 * initiator capability. 849 * 850 * Note that this call is made to initiator-client backends, 851 * the ocs_scsi_tgt_del_domain() function is called to target-server backends. 852 * 853 * @param domain pointer to domain 854 * 855 * @return returns 0 for success, a negative error code value for failure. 856 */ 857 void 858 ocs_scsi_ini_del_domain(ocs_domain_t *domain) 859 { 860 } 861 862 /** 863 * @ingroup scsi_api_initiator 864 * @brief accept new sli port notification 865 * 866 * Called by base drive when new sli port (sport) is discovered. 867 * A target-server will use this call to prepare for new remote node 868 * notifications arising from ocs_scsi_new_initiator(). 869 * 870 * This function will only be called if the base-driver has been enabled for 871 * target capability. 872 * 873 * Note that this call is made to target-server backends, 874 * the ocs_scsi_ini_new_sport() function is called to initiator-client backends. 875 * 876 * @param sport pointer to sport 877 * 878 * @return returns 0 for success, a negative error code value for failure. 879 */ 880 int32_t 881 ocs_scsi_ini_new_sport(ocs_sport_t *sport) 882 { 883 ocs_t *ocs = sport->ocs; 884 ocs_fcport *fcp = FCPORT(ocs, 0); 885 886 if (!sport->is_vport) { 887 sport->tgt_data = fcp; 888 fcp->fc_id = sport->fc_id; 889 } 890 891 return 0; 892 } 893 894 /** 895 * @ingroup scsi_api_initiator 896 * @brief accept sli port gone notification 897 * 898 * Called by base-driver when a sport goes away. A target-server will 899 * use this call to clean up all sport scoped resources. 900 * 901 * Note that this call is made to target-server backends, 902 * the ocs_scsi_ini_del_sport() function is called to initiator-client backends. 903 * 904 * @param sport pointer to SLI port 905 * 906 * @return returns 0 for success, a negative error code value for failure. 907 */ 908 void 909 ocs_scsi_ini_del_sport(ocs_sport_t *sport) 910 { 911 ocs_t *ocs = sport->ocs; 912 ocs_fcport *fcp = FCPORT(ocs, 0); 913 914 if (!sport->is_vport) { 915 fcp->fc_id = 0; 916 } 917 } 918 919 void 920 ocs_scsi_sport_deleted(ocs_sport_t *sport) 921 { 922 ocs_t *ocs = sport->ocs; 923 ocs_fcport *fcp = NULL; 924 925 ocs_xport_stats_t value; 926 927 if (!sport->is_vport) { 928 return; 929 } 930 931 fcp = sport->tgt_data; 932 933 ocs_xport_status(ocs->xport, OCS_XPORT_PORT_STATUS, &value); 934 935 if (value.value == 0) { 936 ocs_log_debug(ocs, "PORT offline,.. skipping\n"); 937 return; 938 } 939 940 if ((fcp->role != KNOB_ROLE_NONE)) { 941 if(fcp->vport->sport != NULL) { 942 ocs_log_debug(ocs,"sport is not NULL, skipping\n"); 943 return; 944 } 945 946 ocs_sport_vport_alloc(ocs->domain, fcp->vport); 947 return; 948 } 949 950 } 951 952 int32_t 953 ocs_tgt_find(ocs_fcport *fcp, ocs_node_t *node) 954 { 955 ocs_fc_target_t *tgt = NULL; 956 uint32_t i; 957 958 for (i = 0; i < OCS_MAX_TARGETS; i++) { 959 tgt = &fcp->tgt[i]; 960 961 if (tgt->state == OCS_TGT_STATE_NONE) 962 continue; 963 964 if (ocs_node_get_wwpn(node) == tgt->wwpn) { 965 return i; 966 } 967 } 968 969 return -1; 970 } 971 972 /** 973 * @ingroup scsi_api_initiator 974 * @brief receive notification of a new SCSI target node 975 * 976 * Sent by base driver to notify an initiator-client of the presense of a new 977 * remote target. The initiator-server may use this call to prepare for 978 * inbound IO from this node. 979 * 980 * This function is only called if the base driver is enabled for 981 * initiator capability. 982 * 983 * @param node pointer to new remote initiator node 984 * 985 * @return none 986 * 987 * @note 988 */ 989 990 uint32_t 991 ocs_update_tgt(ocs_node_t *node, ocs_fcport *fcp, uint32_t tgt_id) 992 { 993 ocs_fc_target_t *tgt = NULL; 994 995 tgt = &fcp->tgt[tgt_id]; 996 997 tgt->node_id = node->instance_index; 998 tgt->state = OCS_TGT_STATE_VALID; 999 1000 tgt->port_id = node->rnode.fc_id; 1001 tgt->wwpn = ocs_node_get_wwpn(node); 1002 tgt->wwnn = ocs_node_get_wwnn(node); 1003 return 0; 1004 } 1005 1006 uint32_t 1007 ocs_add_new_tgt(ocs_node_t *node, ocs_fcport *fcp) 1008 { 1009 uint32_t i; 1010 1011 struct ocs_softc *ocs = node->ocs; 1012 union ccb *ccb = NULL; 1013 for (i = 0; i < OCS_MAX_TARGETS; i++) { 1014 if (fcp->tgt[i].state == OCS_TGT_STATE_NONE) 1015 break; 1016 } 1017 1018 if (NULL == (ccb = xpt_alloc_ccb_nowait())) { 1019 device_printf(ocs->dev, "%s: ccb allocation failed\n", __func__); 1020 return -1; 1021 } 1022 1023 if (CAM_REQ_CMP != xpt_create_path(&ccb->ccb_h.path, xpt_periph, 1024 cam_sim_path(fcp->sim), 1025 i, CAM_LUN_WILDCARD)) { 1026 device_printf( 1027 ocs->dev, "%s: target path creation failed\n", __func__); 1028 xpt_free_ccb(ccb); 1029 return -1; 1030 } 1031 1032 ocs_update_tgt(node, fcp, i); 1033 xpt_rescan(ccb); 1034 return 0; 1035 } 1036 1037 int32_t 1038 ocs_scsi_new_target(ocs_node_t *node) 1039 { 1040 ocs_fcport *fcp = NULL; 1041 int32_t i; 1042 1043 fcp = node->sport->tgt_data; 1044 if (fcp == NULL) { 1045 printf("%s:FCP is NULL \n", __func__); 1046 return 0; 1047 } 1048 1049 i = ocs_tgt_find(fcp, node); 1050 1051 if (i < 0) { 1052 ocs_add_new_tgt(node, fcp); 1053 return 0; 1054 } 1055 1056 ocs_update_tgt(node, fcp, i); 1057 return 0; 1058 } 1059 1060 static void 1061 ocs_delete_target(ocs_t *ocs, ocs_fcport *fcp, int tgt) 1062 { 1063 struct cam_path *cpath = NULL; 1064 1065 if (!fcp->sim) { 1066 device_printf(ocs->dev, "%s: calling with NULL sim\n", __func__); 1067 return; 1068 } 1069 1070 if (CAM_REQ_CMP == xpt_create_path(&cpath, NULL, cam_sim_path(fcp->sim), 1071 tgt, CAM_LUN_WILDCARD)) { 1072 xpt_async(AC_LOST_DEVICE, cpath, NULL); 1073 1074 xpt_free_path(cpath); 1075 } 1076 } 1077 1078 /* 1079 * Device Lost Timer Function- when we have decided that a device was lost, 1080 * we wait a specific period of time prior to telling the OS about lost device. 1081 * 1082 * This timer function gets activated when the device was lost. 1083 * This function fires once a second and then scans the port database 1084 * for devices that are marked dead but still have a virtual target assigned. 1085 * We decrement a counter for that port database entry, and when it hits zero, 1086 * we tell the OS the device was lost. Timer will be stopped when the device 1087 * comes back active or removed from the OS. 1088 */ 1089 static void 1090 ocs_ldt(void *arg) 1091 { 1092 ocs_fcport *fcp = arg; 1093 taskqueue_enqueue(taskqueue_thread, &fcp->ltask); 1094 } 1095 1096 static void 1097 ocs_ldt_task(void *arg, int pending) 1098 { 1099 ocs_fcport *fcp = arg; 1100 ocs_t *ocs = fcp->ocs; 1101 int i, more_to_do = 0; 1102 ocs_fc_target_t *tgt = NULL; 1103 1104 for (i = 0; i < OCS_MAX_TARGETS; i++) { 1105 tgt = &fcp->tgt[i]; 1106 1107 if (tgt->state != OCS_TGT_STATE_LOST) { 1108 continue; 1109 } 1110 1111 if ((tgt->gone_timer != 0) && (ocs->attached)){ 1112 tgt->gone_timer -= 1; 1113 more_to_do++; 1114 continue; 1115 } 1116 1117 if (tgt->is_target) { 1118 tgt->is_target = 0; 1119 ocs_delete_target(ocs, fcp, i); 1120 } 1121 1122 tgt->state = OCS_TGT_STATE_NONE; 1123 } 1124 1125 if (more_to_do) { 1126 callout_reset(&fcp->ldt, hz, ocs_ldt, fcp); 1127 } else { 1128 callout_deactivate(&fcp->ldt); 1129 } 1130 1131 } 1132 1133 /** 1134 * @ingroup scsi_api_initiator 1135 * @brief Delete a SCSI target node 1136 * 1137 * Sent by base driver to notify a initiator-client that a remote target 1138 * is now gone. The base driver will have terminated all outstanding IOs 1139 * and the initiator-client will receive appropriate completions. 1140 * 1141 * The ocs_node_t structure has and elment of type ocs_scsi_ini_node_t named 1142 * ini_node that is declared and used by a target-server for private 1143 * information. 1144 * 1145 * This function is only called if the base driver is enabled for 1146 * initiator capability. 1147 * 1148 * @param node pointer node being deleted 1149 * @param reason reason for deleting the target 1150 * 1151 * @return Returns OCS_SCSI_CALL_ASYNC if target delete is queued for async 1152 * completion and OCS_SCSI_CALL_COMPLETE if call completed or error. 1153 * 1154 * @note 1155 */ 1156 int32_t 1157 ocs_scsi_del_target(ocs_node_t *node, ocs_scsi_del_target_reason_e reason) 1158 { 1159 struct ocs_softc *ocs = node->ocs; 1160 ocs_fcport *fcp = NULL; 1161 ocs_fc_target_t *tgt = NULL; 1162 int32_t tgt_id; 1163 1164 if (ocs == NULL) { 1165 ocs_log_err(ocs,"OCS is NULL \n"); 1166 return -1; 1167 } 1168 1169 fcp = node->sport->tgt_data; 1170 if (fcp == NULL) { 1171 ocs_log_err(ocs,"FCP is NULL \n"); 1172 return -1; 1173 } 1174 1175 tgt_id = ocs_tgt_find(fcp, node); 1176 if (tgt_id == -1) { 1177 ocs_log_err(ocs,"target is invalid\n"); 1178 return -1; 1179 } 1180 1181 tgt = &fcp->tgt[tgt_id]; 1182 1183 // IF in shutdown delete target. 1184 if(!ocs->attached) { 1185 ocs_delete_target(ocs, fcp, tgt_id); 1186 } else { 1187 tgt->state = OCS_TGT_STATE_LOST; 1188 tgt->gone_timer = 30; 1189 if (!callout_active(&fcp->ldt)) { 1190 callout_reset(&fcp->ldt, hz, ocs_ldt, fcp); 1191 } 1192 } 1193 1194 return 0; 1195 } 1196 1197 /** 1198 * @brief Initialize SCSI IO 1199 * 1200 * Initialize SCSI IO, this function is called once per IO during IO pool 1201 * allocation so that the target server may initialize any of its own private 1202 * data. 1203 * 1204 * @param io pointer to SCSI IO object 1205 * 1206 * @return returns 0 for success, a negative error code value for failure. 1207 */ 1208 int32_t 1209 ocs_scsi_tgt_io_init(ocs_io_t *io) 1210 { 1211 return 0; 1212 } 1213 1214 /** 1215 * @brief Uninitialize SCSI IO 1216 * 1217 * Uninitialize target server private data in a SCSI io object 1218 * 1219 * @param io pointer to SCSI IO object 1220 * 1221 * @return returns 0 for success, a negative error code value for failure. 1222 */ 1223 int32_t 1224 ocs_scsi_tgt_io_exit(ocs_io_t *io) 1225 { 1226 return 0; 1227 } 1228 1229 /** 1230 * @brief Initialize SCSI IO 1231 * 1232 * Initialize SCSI IO, this function is called once per IO during IO pool 1233 * allocation so that the initiator client may initialize any of its own private 1234 * data. 1235 * 1236 * @param io pointer to SCSI IO object 1237 * 1238 * @return returns 0 for success, a negative error code value for failure. 1239 */ 1240 int32_t 1241 ocs_scsi_ini_io_init(ocs_io_t *io) 1242 { 1243 return 0; 1244 } 1245 1246 /** 1247 * @brief Uninitialize SCSI IO 1248 * 1249 * Uninitialize initiator client private data in a SCSI io object 1250 * 1251 * @param io pointer to SCSI IO object 1252 * 1253 * @return returns 0 for success, a negative error code value for failure. 1254 */ 1255 int32_t 1256 ocs_scsi_ini_io_exit(ocs_io_t *io) 1257 { 1258 return 0; 1259 } 1260 /* 1261 * End of functions required by SCSI base driver API 1262 ***************************************************************************/ 1263 1264 static __inline void 1265 ocs_set_ccb_status(union ccb *ccb, cam_status status) 1266 { 1267 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1268 ccb->ccb_h.status |= status; 1269 } 1270 1271 static int32_t 1272 ocs_task_set_full_or_busy_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, 1273 uint32_t flags, void *arg) 1274 { 1275 1276 ocs_target_io_free(io); 1277 1278 return 0; 1279 } 1280 1281 /** 1282 * @brief send SCSI task set full or busy status 1283 * 1284 * A SCSI task set full or busy response is sent depending on whether 1285 * another IO is already active on the LUN. 1286 * 1287 * @param io pointer to IO context 1288 * 1289 * @return returns 0 for success, a negative error code value for failure. 1290 */ 1291 1292 static int32_t 1293 ocs_task_set_full_or_busy(ocs_io_t *io) 1294 { 1295 ocs_scsi_cmd_resp_t rsp = { 0 }; 1296 ocs_t *ocs = io->ocs; 1297 1298 /* 1299 * If there is another command for the LUN, then send task set full, 1300 * if this is the first one, then send the busy status. 1301 * 1302 * if 'busy sent' is FALSE, set it to TRUE and send BUSY 1303 * otherwise send FULL 1304 */ 1305 if (atomic_cmpset_acq_32(&io->node->tgt_node.busy_sent, FALSE, TRUE)) { 1306 rsp.scsi_status = SCSI_STATUS_BUSY; /* Busy */ 1307 printf("%s: busy [%s] tag=%x iiu=%d ihw=%d\n", __func__, 1308 io->node->display_name, io->tag, 1309 io->ocs->io_in_use, io->ocs->io_high_watermark); 1310 } else { 1311 rsp.scsi_status = SCSI_STATUS_TASK_SET_FULL; /* Task set full */ 1312 printf("%s: full tag=%x iiu=%d\n", __func__, io->tag, 1313 io->ocs->io_in_use); 1314 } 1315 1316 /* Log a message here indicating a busy or task set full state */ 1317 if (OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs)) { 1318 /* Log Task Set Full */ 1319 if (rsp.scsi_status == SCSI_STATUS_TASK_SET_FULL) { 1320 /* Task Set Full Message */ 1321 ocs_log_info(ocs, "OCS CAM TASK SET FULL. Tasks >= %d\n", 1322 ocs->io_high_watermark); 1323 } 1324 else if (rsp.scsi_status == SCSI_STATUS_BUSY) { 1325 /* Log Busy Message */ 1326 ocs_log_info(ocs, "OCS CAM SCSI BUSY\n"); 1327 } 1328 } 1329 1330 /* Send the response */ 1331 return 1332 ocs_scsi_send_resp(io, 0, &rsp, ocs_task_set_full_or_busy_cb, NULL); 1333 } 1334 1335 /** 1336 * @ingroup cam_io 1337 * @brief Process target IO completions 1338 * 1339 * @param io 1340 * @param scsi_status did the IO complete successfully 1341 * @param flags 1342 * @param arg application specific pointer provided in the call to ocs_target_io() 1343 * 1344 * @todo 1345 */ 1346 static int32_t ocs_scsi_target_io_cb(ocs_io_t *io, 1347 ocs_scsi_io_status_e scsi_status, 1348 uint32_t flags, void *arg) 1349 { 1350 union ccb *ccb = arg; 1351 struct ccb_scsiio *csio = &ccb->csio; 1352 struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr; 1353 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 1354 uint32_t io_is_done = 1355 (ccb->ccb_h.flags & CAM_SEND_STATUS) == CAM_SEND_STATUS; 1356 1357 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1358 1359 if (CAM_DIR_NONE != cam_dir) { 1360 bus_dmasync_op_t op; 1361 1362 if (CAM_DIR_IN == cam_dir) { 1363 op = BUS_DMASYNC_POSTREAD; 1364 } else { 1365 op = BUS_DMASYNC_POSTWRITE; 1366 } 1367 /* Synchronize the DMA memory with the CPU and free the mapping */ 1368 bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op); 1369 if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) { 1370 bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap); 1371 } 1372 } 1373 1374 if (io->tgt_io.sendresp) { 1375 io->tgt_io.sendresp = 0; 1376 ocs_scsi_cmd_resp_t resp = { 0 }; 1377 io->tgt_io.state = OCS_CAM_IO_RESP; 1378 resp.scsi_status = scsi_status; 1379 if (ccb->ccb_h.flags & CAM_SEND_SENSE) { 1380 resp.sense_data = (uint8_t *)&csio->sense_data; 1381 resp.sense_data_length = csio->sense_len; 1382 } 1383 resp.residual = io->exp_xfer_len - io->transferred; 1384 1385 return ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb); 1386 } 1387 1388 switch (scsi_status) { 1389 case OCS_SCSI_STATUS_GOOD: 1390 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 1391 break; 1392 case OCS_SCSI_STATUS_ABORTED: 1393 ocs_set_ccb_status(ccb, CAM_REQ_ABORTED); 1394 break; 1395 default: 1396 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 1397 } 1398 1399 if (io_is_done) { 1400 if ((io->tgt_io.flags & OCS_CAM_IO_F_ABORT_NOTIFY) == 0) { 1401 ocs_target_io_free(io); 1402 } 1403 } else { 1404 io->tgt_io.state = OCS_CAM_IO_DATA_DONE; 1405 /*device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n", 1406 __func__, io->tgt_io.state, io->tag);*/ 1407 } 1408 1409 xpt_done(ccb); 1410 1411 return 0; 1412 } 1413 1414 /** 1415 * @note 1. Since the CCB is assigned to the ocs_io_t on an XPT_CONT_TARGET_IO 1416 * action, if an initiator aborts a command prior to the SIM receiving 1417 * a CTIO, the IO's CCB will be NULL. 1418 */ 1419 static int32_t 1420 ocs_io_abort_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, void *arg) 1421 { 1422 struct ocs_softc *ocs = NULL; 1423 ocs_io_t *tmfio = arg; 1424 ocs_scsi_tmf_resp_e tmf_resp = OCS_SCSI_TMF_FUNCTION_COMPLETE; 1425 int32_t rc = 0; 1426 1427 ocs = io->ocs; 1428 1429 io->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_DEV; 1430 1431 /* A good status indicates the IO was aborted and will be completed in 1432 * the IO's completion handler. Handle the other cases here. */ 1433 switch (scsi_status) { 1434 case OCS_SCSI_STATUS_GOOD: 1435 break; 1436 case OCS_SCSI_STATUS_NO_IO: 1437 break; 1438 default: 1439 device_printf(ocs->dev, "%s: unhandled status %d\n", 1440 __func__, scsi_status); 1441 tmf_resp = OCS_SCSI_TMF_FUNCTION_REJECTED; 1442 rc = -1; 1443 } 1444 1445 ocs_scsi_send_tmf_resp(tmfio, tmf_resp, NULL, ocs_target_tmf_cb, NULL); 1446 1447 return rc; 1448 } 1449 1450 /** 1451 * @ingroup cam_io 1452 * @brief Process initiator IO completions 1453 * 1454 * @param io 1455 * @param scsi_status did the IO complete successfully 1456 * @param rsp pointer to response buffer 1457 * @param flags 1458 * @param arg application specific pointer provided in the call to ocs_target_io() 1459 * 1460 * @todo 1461 */ 1462 static int32_t ocs_scsi_initiator_io_cb(ocs_io_t *io, 1463 ocs_scsi_io_status_e scsi_status, 1464 ocs_scsi_cmd_resp_t *rsp, 1465 uint32_t flags, void *arg) 1466 { 1467 union ccb *ccb = arg; 1468 struct ccb_scsiio *csio = &ccb->csio; 1469 struct ocs_softc *ocs = csio->ccb_h.ccb_ocs_ptr; 1470 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 1471 cam_status ccb_status= CAM_REQ_CMP_ERR; 1472 1473 if (CAM_DIR_NONE != cam_dir) { 1474 bus_dmasync_op_t op; 1475 1476 if (CAM_DIR_IN == cam_dir) { 1477 op = BUS_DMASYNC_POSTREAD; 1478 } else { 1479 op = BUS_DMASYNC_POSTWRITE; 1480 } 1481 /* Synchronize the DMA memory with the CPU and free the mapping */ 1482 bus_dmamap_sync(ocs->buf_dmat, io->tgt_io.dmap, op); 1483 if (io->tgt_io.flags & OCS_CAM_IO_F_DMAPPED) { 1484 bus_dmamap_unload(ocs->buf_dmat, io->tgt_io.dmap); 1485 } 1486 } 1487 1488 if (scsi_status == OCS_SCSI_STATUS_CHECK_RESPONSE) { 1489 csio->scsi_status = rsp->scsi_status; 1490 if (SCSI_STATUS_OK != rsp->scsi_status) { 1491 ccb_status = CAM_SCSI_STATUS_ERROR; 1492 } 1493 1494 csio->resid = rsp->residual; 1495 if (rsp->residual > 0) { 1496 uint32_t length = rsp->response_wire_length; 1497 /* underflow */ 1498 if (csio->dxfer_len == (length + csio->resid)) { 1499 ccb_status = CAM_REQ_CMP; 1500 } 1501 } else if (rsp->residual < 0) { 1502 ccb_status = CAM_DATA_RUN_ERR; 1503 } 1504 1505 if ((rsp->sense_data_length) && 1506 !(ccb->ccb_h.flags & (CAM_SENSE_PHYS | CAM_SENSE_PTR))) { 1507 uint32_t sense_len = 0; 1508 1509 ccb->ccb_h.status |= CAM_AUTOSNS_VALID; 1510 if (rsp->sense_data_length < csio->sense_len) { 1511 csio->sense_resid = 1512 csio->sense_len - rsp->sense_data_length; 1513 sense_len = rsp->sense_data_length; 1514 } else { 1515 csio->sense_resid = 0; 1516 sense_len = csio->sense_len; 1517 } 1518 ocs_memcpy(&csio->sense_data, rsp->sense_data, sense_len); 1519 } 1520 } else if (scsi_status != OCS_SCSI_STATUS_GOOD) { 1521 ccb_status = CAM_REQ_CMP_ERR; 1522 ocs_set_ccb_status(ccb, ccb_status); 1523 csio->ccb_h.status |= CAM_DEV_QFRZN; 1524 xpt_freeze_devq(csio->ccb_h.path, 1); 1525 1526 } else { 1527 ccb_status = CAM_REQ_CMP; 1528 } 1529 1530 ocs_set_ccb_status(ccb, ccb_status); 1531 1532 ocs_scsi_io_free(io); 1533 1534 csio->ccb_h.ccb_io_ptr = NULL; 1535 csio->ccb_h.ccb_ocs_ptr = NULL; 1536 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1537 1538 xpt_done(ccb); 1539 1540 return 0; 1541 } 1542 1543 /** 1544 * @brief Load scatter-gather list entries into an IO 1545 * 1546 * This routine relies on the driver instance's software context pointer and 1547 * the IO object pointer having been already assigned to hooks in the CCB. 1548 * Although the routine does not return success/fail, callers can look at the 1549 * n_sge member to determine if the mapping failed (0 on failure). 1550 * 1551 * @param arg pointer to the CAM ccb for this IO 1552 * @param seg DMA address/length pairs 1553 * @param nseg number of DMA address/length pairs 1554 * @param error any errors while mapping the IO 1555 */ 1556 static void 1557 ocs_scsi_dmamap_load(void *arg, bus_dma_segment_t *seg, int nseg, int error) 1558 { 1559 ocs_dmamap_load_arg_t *sglarg = (ocs_dmamap_load_arg_t*) arg; 1560 1561 if (error) { 1562 printf("%s: seg=%p nseg=%d error=%d\n", 1563 __func__, seg, nseg, error); 1564 sglarg->rc = -1; 1565 } else { 1566 uint32_t i = 0; 1567 uint32_t c = 0; 1568 1569 if ((sglarg->sgl_count + nseg) > sglarg->sgl_max) { 1570 printf("%s: sgl_count=%d nseg=%d max=%d\n", __func__, 1571 sglarg->sgl_count, nseg, sglarg->sgl_max); 1572 sglarg->rc = -2; 1573 return; 1574 } 1575 1576 for (i = 0, c = sglarg->sgl_count; i < nseg; i++, c++) { 1577 sglarg->sgl[c].addr = seg[i].ds_addr; 1578 sglarg->sgl[c].len = seg[i].ds_len; 1579 } 1580 1581 sglarg->sgl_count = c; 1582 1583 sglarg->rc = 0; 1584 } 1585 } 1586 1587 /** 1588 * @brief Build a scatter-gather list from a CAM CCB 1589 * 1590 * @param ocs the driver instance's software context 1591 * @param ccb pointer to the CCB 1592 * @param io pointer to the previously allocated IO object 1593 * @param sgl pointer to SGL 1594 * @param sgl_max number of entries in sgl 1595 * 1596 * @return 0 on success, non-zero otherwise 1597 */ 1598 static int32_t 1599 ocs_build_scsi_sgl(struct ocs_softc *ocs, union ccb *ccb, ocs_io_t *io, 1600 ocs_scsi_sgl_t *sgl, uint32_t sgl_max) 1601 { 1602 ocs_dmamap_load_arg_t dmaarg; 1603 int32_t err = 0; 1604 1605 if (!ocs || !ccb || !io || !sgl) { 1606 printf("%s: bad param o=%p c=%p i=%p s=%p\n", __func__, 1607 ocs, ccb, io, sgl); 1608 return -1; 1609 } 1610 1611 io->tgt_io.flags &= ~OCS_CAM_IO_F_DMAPPED; 1612 1613 dmaarg.sgl = sgl; 1614 dmaarg.sgl_count = 0; 1615 dmaarg.sgl_max = sgl_max; 1616 dmaarg.rc = 0; 1617 1618 err = bus_dmamap_load_ccb(ocs->buf_dmat, io->tgt_io.dmap, ccb, 1619 ocs_scsi_dmamap_load, &dmaarg, 0); 1620 1621 if (err || dmaarg.rc) { 1622 device_printf( 1623 ocs->dev, "%s: bus_dmamap_load_ccb error (%d %d)\n", 1624 __func__, err, dmaarg.rc); 1625 return -1; 1626 } 1627 1628 io->tgt_io.flags |= OCS_CAM_IO_F_DMAPPED; 1629 return dmaarg.sgl_count; 1630 } 1631 1632 /** 1633 * @ingroup cam_io 1634 * @brief Send a target IO 1635 * 1636 * @param ocs the driver instance's software context 1637 * @param ccb pointer to the CCB 1638 * 1639 * @return 0 on success, non-zero otherwise 1640 */ 1641 static int32_t 1642 ocs_target_io(struct ocs_softc *ocs, union ccb *ccb) 1643 { 1644 struct ccb_scsiio *csio = &ccb->csio; 1645 ocs_io_t *io = NULL; 1646 uint32_t cam_dir = ccb->ccb_h.flags & CAM_DIR_MASK; 1647 bool sendstatus = ccb->ccb_h.flags & CAM_SEND_STATUS; 1648 uint32_t xferlen = csio->dxfer_len; 1649 int32_t rc = 0; 1650 1651 io = ocs_scsi_find_io(ocs, csio->tag_id); 1652 if (io == NULL) { 1653 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 1654 panic("bad tag value"); 1655 return 1; 1656 } 1657 1658 /* Received an ABORT TASK for this IO */ 1659 if (io->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) { 1660 /*device_printf(ocs->dev, 1661 "%s: XPT_CONT_TARGET_IO state=%d tag=%#x xid=%#x flags=%#x\n", 1662 __func__, io->tgt_io.state, io->tag, io->init_task_tag, 1663 io->tgt_io.flags);*/ 1664 io->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM; 1665 1666 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 1667 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 1668 ocs_target_io_free(io); 1669 return 1; 1670 } 1671 1672 ocs_set_ccb_status(ccb, CAM_REQ_ABORTED); 1673 1674 return 1; 1675 } 1676 1677 io->tgt_io.app = ccb; 1678 1679 ocs_set_ccb_status(ccb, CAM_REQ_INPROG); 1680 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1681 1682 csio->ccb_h.ccb_ocs_ptr = ocs; 1683 csio->ccb_h.ccb_io_ptr = io; 1684 1685 if ((sendstatus && (xferlen == 0))) { 1686 ocs_scsi_cmd_resp_t resp = { 0 }; 1687 1688 ocs_assert(ccb->ccb_h.flags & CAM_SEND_STATUS, -1); 1689 1690 io->tgt_io.state = OCS_CAM_IO_RESP; 1691 1692 resp.scsi_status = csio->scsi_status; 1693 1694 if (ccb->ccb_h.flags & CAM_SEND_SENSE) { 1695 resp.sense_data = (uint8_t *)&csio->sense_data; 1696 resp.sense_data_length = csio->sense_len; 1697 } 1698 1699 resp.residual = io->exp_xfer_len - io->transferred; 1700 rc = ocs_scsi_send_resp(io, 0, &resp, ocs_scsi_target_io_cb, ccb); 1701 1702 } else if (xferlen != 0) { 1703 ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL]; 1704 int32_t sgl_count = 0; 1705 1706 io->tgt_io.state = OCS_CAM_IO_DATA; 1707 1708 if (sendstatus) 1709 io->tgt_io.sendresp = 1; 1710 1711 sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl)); 1712 if (sgl_count > 0) { 1713 if (cam_dir == CAM_DIR_IN) { 1714 rc = ocs_scsi_send_rd_data(io, 0, NULL, sgl, 1715 sgl_count, csio->dxfer_len, 1716 ocs_scsi_target_io_cb, ccb); 1717 } else if (cam_dir == CAM_DIR_OUT) { 1718 rc = ocs_scsi_recv_wr_data(io, 0, NULL, sgl, 1719 sgl_count, csio->dxfer_len, 1720 ocs_scsi_target_io_cb, ccb); 1721 } else { 1722 device_printf(ocs->dev, "%s:" 1723 " unknown CAM direction %#x\n", 1724 __func__, cam_dir); 1725 ocs_set_ccb_status(ccb, CAM_REQ_INVALID); 1726 rc = 1; 1727 } 1728 } else { 1729 device_printf(ocs->dev, "%s: building SGL failed\n", 1730 __func__); 1731 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 1732 rc = 1; 1733 } 1734 } else { 1735 device_printf(ocs->dev, "%s: Wrong value xfer and sendstatus" 1736 " are 0 \n", __func__); 1737 ocs_set_ccb_status(ccb, CAM_REQ_INVALID); 1738 rc = 1; 1739 } 1740 1741 if (rc) { 1742 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 1743 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1744 io->tgt_io.state = OCS_CAM_IO_DATA_DONE; 1745 device_printf(ocs->dev, "%s: CTIO state=%d tag=%#x\n", 1746 __func__, io->tgt_io.state, io->tag); 1747 if ((sendstatus && (xferlen == 0))) { 1748 ocs_target_io_free(io); 1749 } 1750 } 1751 1752 return rc; 1753 } 1754 1755 static int32_t 1756 ocs_target_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, uint32_t flags, 1757 void *arg) 1758 { 1759 1760 /*device_printf(io->ocs->dev, "%s: tag=%x io=%p s=%#x\n", 1761 __func__, io->tag, io, scsi_status);*/ 1762 ocs_scsi_io_complete(io); 1763 1764 return 0; 1765 } 1766 1767 /** 1768 * @ingroup cam_io 1769 * @brief Send an initiator IO 1770 * 1771 * @param ocs the driver instance's software context 1772 * @param ccb pointer to the CCB 1773 * 1774 * @return 0 on success, non-zero otherwise 1775 */ 1776 static int32_t 1777 ocs_initiator_io(struct ocs_softc *ocs, union ccb *ccb) 1778 { 1779 int32_t rc; 1780 struct ccb_scsiio *csio = &ccb->csio; 1781 struct ccb_hdr *ccb_h = &csio->ccb_h; 1782 ocs_node_t *node = NULL; 1783 ocs_io_t *io = NULL; 1784 ocs_scsi_sgl_t sgl[OCS_FC_MAX_SGL]; 1785 int32_t sgl_count; 1786 ocs_fcport *fcp; 1787 1788 fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path))); 1789 1790 if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_LOST) { 1791 device_printf(ocs->dev, "%s: device LOST %d\n", __func__, 1792 ccb_h->target_id); 1793 return CAM_REQUEUE_REQ; 1794 } 1795 1796 if (fcp->tgt[ccb_h->target_id].state == OCS_TGT_STATE_NONE) { 1797 device_printf(ocs->dev, "%s: device not ready %d\n", __func__, 1798 ccb_h->target_id); 1799 return CAM_SEL_TIMEOUT; 1800 } 1801 1802 node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id); 1803 if (node == NULL) { 1804 device_printf(ocs->dev, "%s: no device %d\n", __func__, 1805 ccb_h->target_id); 1806 return CAM_SEL_TIMEOUT; 1807 } 1808 1809 if (!node->targ) { 1810 device_printf(ocs->dev, "%s: not target device %d\n", __func__, 1811 ccb_h->target_id); 1812 return CAM_SEL_TIMEOUT; 1813 } 1814 1815 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR); 1816 if (io == NULL) { 1817 device_printf(ocs->dev, "%s: unable to alloc IO\n", __func__); 1818 return -1; 1819 } 1820 1821 /* eventhough this is INI, use target structure as ocs_build_scsi_sgl 1822 * only references the tgt_io part of an ocs_io_t */ 1823 io->tgt_io.app = ccb; 1824 1825 csio->ccb_h.ccb_ocs_ptr = ocs; 1826 csio->ccb_h.ccb_io_ptr = io; 1827 1828 sgl_count = ocs_build_scsi_sgl(ocs, ccb, io, sgl, ARRAY_SIZE(sgl)); 1829 if (sgl_count < 0) { 1830 ocs_scsi_io_free(io); 1831 device_printf(ocs->dev, "%s: building SGL failed\n", __func__); 1832 return -1; 1833 } 1834 1835 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) { 1836 io->timeout = 0; 1837 } else if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) { 1838 io->timeout = OCS_CAM_IO_TIMEOUT; 1839 } else { 1840 io->timeout = ccb->ccb_h.timeout; 1841 } 1842 1843 switch (ccb->ccb_h.flags & CAM_DIR_MASK) { 1844 case CAM_DIR_NONE: 1845 rc = ocs_scsi_send_nodata_io(node, io, ccb_h->target_lun, 1846 ccb->ccb_h.flags & CAM_CDB_POINTER ? 1847 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes, 1848 csio->cdb_len, 1849 ocs_scsi_initiator_io_cb, ccb); 1850 break; 1851 case CAM_DIR_IN: 1852 rc = ocs_scsi_send_rd_io(node, io, ccb_h->target_lun, 1853 ccb->ccb_h.flags & CAM_CDB_POINTER ? 1854 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes, 1855 csio->cdb_len, 1856 NULL, 1857 sgl, sgl_count, csio->dxfer_len, 1858 ocs_scsi_initiator_io_cb, ccb); 1859 break; 1860 case CAM_DIR_OUT: 1861 rc = ocs_scsi_send_wr_io(node, io, ccb_h->target_lun, 1862 ccb->ccb_h.flags & CAM_CDB_POINTER ? 1863 csio->cdb_io.cdb_ptr: csio->cdb_io.cdb_bytes, 1864 csio->cdb_len, 1865 NULL, 1866 sgl, sgl_count, csio->dxfer_len, 1867 ocs_scsi_initiator_io_cb, ccb); 1868 break; 1869 default: 1870 panic("%s invalid data direction %08x\n", __func__, 1871 ccb->ccb_h.flags); 1872 break; 1873 } 1874 1875 return rc; 1876 } 1877 1878 static uint32_t 1879 ocs_fcp_change_role(struct ocs_softc *ocs, ocs_fcport *fcp, uint32_t new_role) 1880 { 1881 1882 uint32_t rc = 0, was = 0, i = 0; 1883 ocs_vport_spec_t *vport = fcp->vport; 1884 1885 for (was = 0, i = 0; i < (ocs->num_vports + 1); i++) { 1886 if (FCPORT(ocs, i)->role != KNOB_ROLE_NONE) 1887 was++; 1888 } 1889 1890 // Physical port 1891 if ((was == 0) || (vport == NULL)) { 1892 fcp->role = new_role; 1893 if (vport == NULL) { 1894 ocs->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0; 1895 ocs->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0; 1896 } else { 1897 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0; 1898 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0; 1899 } 1900 1901 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE); 1902 if (rc) { 1903 ocs_log_debug(ocs, "port offline failed : %d\n", rc); 1904 } 1905 1906 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE); 1907 if (rc) { 1908 ocs_log_debug(ocs, "port online failed : %d\n", rc); 1909 } 1910 1911 return 0; 1912 } 1913 1914 if ((fcp->role != KNOB_ROLE_NONE)){ 1915 fcp->role = new_role; 1916 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0; 1917 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0; 1918 /* New Sport will be created in sport deleted cb */ 1919 return ocs_sport_vport_del(ocs, ocs->domain, vport->wwpn, vport->wwnn); 1920 } 1921 1922 fcp->role = new_role; 1923 1924 vport->enable_ini = (new_role & KNOB_ROLE_INITIATOR)? 1:0; 1925 vport->enable_tgt = (new_role & KNOB_ROLE_TARGET)? 1:0; 1926 1927 if (fcp->role != KNOB_ROLE_NONE) { 1928 return ocs_sport_vport_alloc(ocs->domain, vport); 1929 } 1930 1931 return (0); 1932 } 1933 1934 /** 1935 * @ingroup cam_api 1936 * @brief Process CAM actions 1937 * 1938 * The driver supplies this routine to the CAM during intialization and 1939 * is the main entry point for processing CAM Control Blocks (CCB) 1940 * 1941 * @param sim pointer to the SCSI Interface Module 1942 * @param ccb CAM control block 1943 * 1944 * @todo 1945 * - populate path inquiry data via info retrieved from SLI port 1946 */ 1947 static void 1948 ocs_action(struct cam_sim *sim, union ccb *ccb) 1949 { 1950 struct ocs_softc *ocs = (struct ocs_softc *)cam_sim_softc(sim); 1951 struct ccb_hdr *ccb_h = &ccb->ccb_h; 1952 1953 int32_t rc, bus; 1954 bus = cam_sim_bus(sim); 1955 1956 switch (ccb_h->func_code) { 1957 case XPT_SCSI_IO: 1958 1959 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 1960 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 1961 ccb->ccb_h.status = CAM_REQ_INVALID; 1962 xpt_done(ccb); 1963 break; 1964 } 1965 } 1966 1967 rc = ocs_initiator_io(ocs, ccb); 1968 if (0 == rc) { 1969 ocs_set_ccb_status(ccb, CAM_REQ_INPROG | CAM_SIM_QUEUED); 1970 break; 1971 } else { 1972 if (rc == CAM_REQUEUE_REQ) { 1973 cam_freeze_devq(ccb->ccb_h.path); 1974 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0); 1975 ccb->ccb_h.status = CAM_REQUEUE_REQ; 1976 xpt_done(ccb); 1977 break; 1978 } 1979 1980 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1981 if (rc > 0) { 1982 ocs_set_ccb_status(ccb, rc); 1983 } else { 1984 ocs_set_ccb_status(ccb, CAM_SEL_TIMEOUT); 1985 } 1986 } 1987 xpt_done(ccb); 1988 break; 1989 case XPT_PATH_INQ: 1990 { 1991 struct ccb_pathinq *cpi = &ccb->cpi; 1992 struct ccb_pathinq_settings_fc *fc = &cpi->xport_specific.fc; 1993 ocs_fcport *fcp = FCPORT(ocs, bus); 1994 1995 uint64_t wwn = 0; 1996 ocs_xport_stats_t value; 1997 1998 cpi->version_num = 1; 1999 2000 cpi->protocol = PROTO_SCSI; 2001 cpi->protocol_version = SCSI_REV_SPC; 2002 2003 if (ocs->ocs_xport == OCS_XPORT_FC) { 2004 cpi->transport = XPORT_FC; 2005 } else { 2006 cpi->transport = XPORT_UNKNOWN; 2007 } 2008 2009 cpi->transport_version = 0; 2010 2011 /* Set the transport parameters of the SIM */ 2012 ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value); 2013 fc->bitrate = value.value * 1000; /* speed in Mbps */ 2014 2015 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWPN)); 2016 fc->wwpn = be64toh(wwn); 2017 2018 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, OCS_SCSI_WWNN)); 2019 fc->wwnn = be64toh(wwn); 2020 2021 fc->port = fcp->fc_id; 2022 2023 if (ocs->config_tgt) { 2024 cpi->target_sprt = 2025 PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 2026 } 2027 2028 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED; 2029 cpi->hba_misc |= PIM_EXTLUNS | PIM_NOSCAN; 2030 2031 cpi->hba_inquiry = PI_TAG_ABLE; 2032 cpi->max_target = OCS_MAX_TARGETS; 2033 cpi->initiator_id = ocs->max_remote_nodes + 1; 2034 2035 if (!ocs->enable_ini) { 2036 cpi->hba_misc |= PIM_NOINITIATOR; 2037 } 2038 2039 cpi->max_lun = OCS_MAX_LUN; 2040 cpi->bus_id = cam_sim_bus(sim); 2041 2042 /* Need to supply a base transfer speed prior to linking up 2043 * Worst case, this would be FC 1Gbps */ 2044 cpi->base_transfer_speed = 1 * 1000 * 1000; 2045 2046 /* Calculate the max IO supported 2047 * Worst case would be an OS page per SGL entry */ 2048 cpi->maxio = PAGE_SIZE * 2049 (ocs_scsi_get_property(ocs, OCS_SCSI_MAX_SGL) - 1); 2050 2051 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 2052 strncpy(cpi->hba_vid, "Emulex", HBA_IDLEN); 2053 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 2054 cpi->unit_number = cam_sim_unit(sim); 2055 2056 cpi->ccb_h.status = CAM_REQ_CMP; 2057 xpt_done(ccb); 2058 break; 2059 } 2060 case XPT_GET_TRAN_SETTINGS: 2061 { 2062 struct ccb_trans_settings *cts = &ccb->cts; 2063 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 2064 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc; 2065 ocs_xport_stats_t value; 2066 ocs_fcport *fcp = FCPORT(ocs, bus); 2067 ocs_fc_target_t *tgt = NULL; 2068 2069 if (ocs->ocs_xport != OCS_XPORT_FC) { 2070 ocs_set_ccb_status(ccb, CAM_REQ_INVALID); 2071 xpt_done(ccb); 2072 break; 2073 } 2074 2075 if (cts->ccb_h.target_id > OCS_MAX_TARGETS) { 2076 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE); 2077 xpt_done(ccb); 2078 break; 2079 } 2080 2081 tgt = &fcp->tgt[cts->ccb_h.target_id]; 2082 if (tgt->state == OCS_TGT_STATE_NONE) { 2083 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE); 2084 xpt_done(ccb); 2085 break; 2086 } 2087 2088 cts->protocol = PROTO_SCSI; 2089 cts->protocol_version = SCSI_REV_SPC2; 2090 cts->transport = XPORT_FC; 2091 cts->transport_version = 2; 2092 2093 scsi->valid = CTS_SCSI_VALID_TQ; 2094 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 2095 2096 /* speed in Mbps */ 2097 ocs_xport_status(ocs->xport, OCS_XPORT_LINK_SPEED, &value); 2098 fc->bitrate = value.value * 100; 2099 2100 fc->wwpn = tgt->wwpn; 2101 2102 fc->wwnn = tgt->wwnn; 2103 2104 fc->port = tgt->port_id; 2105 2106 fc->valid = CTS_FC_VALID_SPEED | 2107 CTS_FC_VALID_WWPN | 2108 CTS_FC_VALID_WWNN | 2109 CTS_FC_VALID_PORT; 2110 2111 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2112 xpt_done(ccb); 2113 break; 2114 } 2115 case XPT_SET_TRAN_SETTINGS: 2116 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2117 xpt_done(ccb); 2118 break; 2119 2120 case XPT_CALC_GEOMETRY: 2121 cam_calc_geometry(&ccb->ccg, TRUE); 2122 xpt_done(ccb); 2123 break; 2124 2125 case XPT_GET_SIM_KNOB: 2126 { 2127 struct ccb_sim_knob *knob = &ccb->knob; 2128 uint64_t wwn = 0; 2129 ocs_fcport *fcp = FCPORT(ocs, bus); 2130 2131 if (ocs->ocs_xport != OCS_XPORT_FC) { 2132 ocs_set_ccb_status(ccb, CAM_REQ_INVALID); 2133 xpt_done(ccb); 2134 break; 2135 } 2136 2137 if (bus == 0) { 2138 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, 2139 OCS_SCSI_WWNN)); 2140 knob->xport_specific.fc.wwnn = be64toh(wwn); 2141 2142 wwn = *((uint64_t *)ocs_scsi_get_property_ptr(ocs, 2143 OCS_SCSI_WWPN)); 2144 knob->xport_specific.fc.wwpn = be64toh(wwn); 2145 } else { 2146 knob->xport_specific.fc.wwnn = fcp->vport->wwnn; 2147 knob->xport_specific.fc.wwpn = fcp->vport->wwpn; 2148 } 2149 2150 knob->xport_specific.fc.role = fcp->role; 2151 knob->xport_specific.fc.valid = KNOB_VALID_ADDRESS | 2152 KNOB_VALID_ROLE; 2153 2154 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2155 xpt_done(ccb); 2156 break; 2157 } 2158 case XPT_SET_SIM_KNOB: 2159 { 2160 struct ccb_sim_knob *knob = &ccb->knob; 2161 bool role_changed = FALSE; 2162 ocs_fcport *fcp = FCPORT(ocs, bus); 2163 2164 if (ocs->ocs_xport != OCS_XPORT_FC) { 2165 ocs_set_ccb_status(ccb, CAM_REQ_INVALID); 2166 xpt_done(ccb); 2167 break; 2168 } 2169 2170 if (knob->xport_specific.fc.valid & KNOB_VALID_ADDRESS) { 2171 device_printf(ocs->dev, 2172 "%s: XPT_SET_SIM_KNOB wwnn=%llx wwpn=%llx\n", 2173 __func__, 2174 (unsigned long long)knob->xport_specific.fc.wwnn, 2175 (unsigned long long)knob->xport_specific.fc.wwpn); 2176 } 2177 2178 if (knob->xport_specific.fc.valid & KNOB_VALID_ROLE) { 2179 switch (knob->xport_specific.fc.role) { 2180 case KNOB_ROLE_NONE: 2181 if (fcp->role != KNOB_ROLE_NONE) { 2182 role_changed = TRUE; 2183 } 2184 break; 2185 case KNOB_ROLE_TARGET: 2186 if (fcp->role != KNOB_ROLE_TARGET) { 2187 role_changed = TRUE; 2188 } 2189 break; 2190 case KNOB_ROLE_INITIATOR: 2191 if (fcp->role != KNOB_ROLE_INITIATOR) { 2192 role_changed = TRUE; 2193 } 2194 break; 2195 case KNOB_ROLE_BOTH: 2196 if (fcp->role != KNOB_ROLE_BOTH) { 2197 role_changed = TRUE; 2198 } 2199 break; 2200 default: 2201 device_printf(ocs->dev, 2202 "%s: XPT_SET_SIM_KNOB unsupported role: %d\n", 2203 __func__, knob->xport_specific.fc.role); 2204 } 2205 2206 if (role_changed) { 2207 device_printf(ocs->dev, 2208 "BUS:%d XPT_SET_SIM_KNOB old_role: %d new_role: %d\n", 2209 bus, fcp->role, knob->xport_specific.fc.role); 2210 2211 ocs_fcp_change_role(ocs, fcp, knob->xport_specific.fc.role); 2212 } 2213 } 2214 2215 2216 2217 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2218 xpt_done(ccb); 2219 break; 2220 } 2221 case XPT_ABORT: 2222 { 2223 union ccb *accb = ccb->cab.abort_ccb; 2224 2225 switch (accb->ccb_h.func_code) { 2226 case XPT_ACCEPT_TARGET_IO: 2227 ocs_abort_atio(ocs, ccb); 2228 break; 2229 case XPT_IMMEDIATE_NOTIFY: 2230 ocs_abort_inot(ocs, ccb); 2231 break; 2232 case XPT_SCSI_IO: 2233 rc = ocs_abort_initiator_io(ocs, accb); 2234 if (rc) { 2235 ccb->ccb_h.status = CAM_UA_ABORT; 2236 } else { 2237 ccb->ccb_h.status = CAM_REQ_CMP; 2238 } 2239 2240 break; 2241 default: 2242 printf("abort of unknown func %#x\n", 2243 accb->ccb_h.func_code); 2244 ccb->ccb_h.status = CAM_REQ_INVALID; 2245 break; 2246 } 2247 break; 2248 } 2249 case XPT_RESET_BUS: 2250 if (ocs_xport_control(ocs->xport, OCS_XPORT_PORT_OFFLINE) == 0) { 2251 rc = ocs_xport_control(ocs->xport, OCS_XPORT_PORT_ONLINE); 2252 if (rc) { 2253 ocs_log_debug(ocs, "Failed to bring port online" 2254 " : %d\n", rc); 2255 } 2256 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2257 } else { 2258 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 2259 } 2260 xpt_done(ccb); 2261 break; 2262 case XPT_RESET_DEV: 2263 { 2264 ocs_node_t *node = NULL; 2265 ocs_io_t *io = NULL; 2266 int32_t rc = 0; 2267 ocs_fcport *fcp = FCPORT(ocs, bus); 2268 2269 node = ocs_node_get_instance(ocs, fcp->tgt[ccb_h->target_id].node_id); 2270 if (node == NULL) { 2271 device_printf(ocs->dev, "%s: no device %d\n", 2272 __func__, ccb_h->target_id); 2273 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE); 2274 xpt_done(ccb); 2275 break; 2276 } 2277 2278 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR); 2279 if (io == NULL) { 2280 device_printf(ocs->dev, "%s: unable to alloc IO\n", 2281 __func__); 2282 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 2283 xpt_done(ccb); 2284 break; 2285 } 2286 2287 rc = ocs_scsi_send_tmf(node, io, NULL, ccb_h->target_lun, 2288 OCS_SCSI_TMF_LOGICAL_UNIT_RESET, 2289 NULL, 0, 0, /* sgl, sgl_count, length */ 2290 ocs_initiator_tmf_cb, NULL/*arg*/); 2291 2292 if (rc) { 2293 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 2294 } else { 2295 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2296 } 2297 2298 if (node->fcp2device) { 2299 ocs_reset_crn(node, ccb_h->target_lun); 2300 } 2301 2302 xpt_done(ccb); 2303 break; 2304 } 2305 case XPT_EN_LUN: /* target support */ 2306 { 2307 ocs_tgt_resource_t *trsrc = NULL; 2308 uint32_t status = 0; 2309 ocs_fcport *fcp = FCPORT(ocs, bus); 2310 2311 device_printf(ocs->dev, "XPT_EN_LUN %sable %d:%d\n", 2312 ccb->cel.enable ? "en" : "dis", 2313 ccb->ccb_h.target_id, 2314 (unsigned int)ccb->ccb_h.target_lun); 2315 2316 trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status); 2317 if (trsrc) { 2318 trsrc->enabled = ccb->cel.enable; 2319 2320 /* Abort all ATIO/INOT on LUN disable */ 2321 if (trsrc->enabled == FALSE) { 2322 ocs_tgt_resource_abort(ocs, trsrc); 2323 } else { 2324 STAILQ_INIT(&trsrc->atio); 2325 STAILQ_INIT(&trsrc->inot); 2326 } 2327 status = CAM_REQ_CMP; 2328 } 2329 2330 ocs_set_ccb_status(ccb, status); 2331 xpt_done(ccb); 2332 break; 2333 } 2334 /* 2335 * The flow of target IOs in CAM is: 2336 * - CAM supplies a number of CCBs to the driver used for received 2337 * commands. 2338 * - when the driver receives a command, it copies the relevant 2339 * information to the CCB and returns it to the CAM using xpt_done() 2340 * - after the target server processes the request, it creates 2341 * a new CCB containing information on how to continue the IO and 2342 * passes that to the driver 2343 * - the driver processes the "continue IO" (a.k.a CTIO) CCB 2344 * - once the IO completes, the driver returns the CTIO to the CAM 2345 * using xpt_done() 2346 */ 2347 case XPT_ACCEPT_TARGET_IO: /* used to inform upper layer of 2348 received CDB (a.k.a. ATIO) */ 2349 case XPT_IMMEDIATE_NOTIFY: /* used to inform upper layer of other 2350 event (a.k.a. INOT) */ 2351 { 2352 ocs_tgt_resource_t *trsrc = NULL; 2353 uint32_t status = 0; 2354 ocs_fcport *fcp = FCPORT(ocs, bus); 2355 2356 /*printf("XPT_%s %p\n", ccb_h->func_code == XPT_ACCEPT_TARGET_IO ? 2357 "ACCEPT_TARGET_IO" : "IMMEDIATE_NOTIFY", ccb);*/ 2358 trsrc = ocs_tgt_resource_get(fcp, &ccb->ccb_h, &status); 2359 if (trsrc == NULL) { 2360 ocs_set_ccb_status(ccb, CAM_DEV_NOT_THERE); 2361 xpt_done(ccb); 2362 break; 2363 } 2364 2365 if (XPT_ACCEPT_TARGET_IO == ccb->ccb_h.func_code) { 2366 struct ccb_accept_tio *atio = NULL; 2367 2368 atio = (struct ccb_accept_tio *)ccb; 2369 atio->init_id = 0x0badbeef; 2370 atio->tag_id = 0xdeadc0de; 2371 2372 STAILQ_INSERT_TAIL(&trsrc->atio, &ccb->ccb_h, 2373 sim_links.stqe); 2374 } else { 2375 STAILQ_INSERT_TAIL(&trsrc->inot, &ccb->ccb_h, 2376 sim_links.stqe); 2377 } 2378 ccb->ccb_h.ccb_io_ptr = NULL; 2379 ccb->ccb_h.ccb_ocs_ptr = ocs; 2380 ocs_set_ccb_status(ccb, CAM_REQ_INPROG); 2381 /* 2382 * These actions give resources to the target driver. 2383 * If we didn't return here, this function would call 2384 * xpt_done(), signaling to the upper layers that an 2385 * IO or other event had arrived. 2386 */ 2387 break; 2388 } 2389 case XPT_NOTIFY_ACKNOWLEDGE: 2390 { 2391 ocs_io_t *io = NULL; 2392 ocs_io_t *abortio = NULL; 2393 2394 /* Get the IO reference for this tag */ 2395 io = ocs_scsi_find_io(ocs, ccb->cna2.tag_id); 2396 if (io == NULL) { 2397 device_printf(ocs->dev, 2398 "%s: XPT_NOTIFY_ACKNOWLEDGE no IO with tag %#x\n", 2399 __func__, ccb->cna2.tag_id); 2400 ocs_set_ccb_status(ccb, CAM_REQ_CMP_ERR); 2401 xpt_done(ccb); 2402 break; 2403 } 2404 2405 abortio = io->tgt_io.app; 2406 if (abortio) { 2407 abortio->tgt_io.flags &= ~OCS_CAM_IO_F_ABORT_NOTIFY; 2408 device_printf(ocs->dev, 2409 "%s: XPT_NOTIFY_ACK state=%d tag=%#x xid=%#x" 2410 " flags=%#x\n", __func__, abortio->tgt_io.state, 2411 abortio->tag, abortio->init_task_tag, 2412 abortio->tgt_io.flags); 2413 /* TMF response was sent in abort callback */ 2414 } else { 2415 ocs_scsi_send_tmf_resp(io, 2416 OCS_SCSI_TMF_FUNCTION_COMPLETE, 2417 NULL, ocs_target_tmf_cb, NULL); 2418 } 2419 2420 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2421 xpt_done(ccb); 2422 break; 2423 } 2424 case XPT_CONT_TARGET_IO: /* continue target IO, sending data/response (a.k.a. CTIO) */ 2425 if (ocs_target_io(ocs, ccb)) { 2426 device_printf(ocs->dev, 2427 "XPT_CONT_TARGET_IO failed flags=%x tag=%#x\n", 2428 ccb->ccb_h.flags, ccb->csio.tag_id); 2429 xpt_done(ccb); 2430 } 2431 break; 2432 default: 2433 device_printf(ocs->dev, "unhandled func_code = %#x\n", 2434 ccb_h->func_code); 2435 ccb_h->status = CAM_REQ_INVALID; 2436 xpt_done(ccb); 2437 break; 2438 } 2439 } 2440 2441 /** 2442 * @ingroup cam_api 2443 * @brief Process events 2444 * 2445 * @param sim pointer to the SCSI Interface Module 2446 * 2447 */ 2448 static void 2449 ocs_poll(struct cam_sim *sim) 2450 { 2451 printf("%s\n", __func__); 2452 } 2453 2454 static int32_t 2455 ocs_initiator_tmf_cb(ocs_io_t *io, ocs_scsi_io_status_e scsi_status, 2456 ocs_scsi_cmd_resp_t *rsp, uint32_t flags, void *arg) 2457 { 2458 int32_t rc = 0; 2459 2460 switch (scsi_status) { 2461 case OCS_SCSI_STATUS_GOOD: 2462 case OCS_SCSI_STATUS_NO_IO: 2463 break; 2464 case OCS_SCSI_STATUS_CHECK_RESPONSE: 2465 if (rsp->response_data_length == 0) { 2466 ocs_log_test(io->ocs, "check response without data?!?\n"); 2467 rc = -1; 2468 break; 2469 } 2470 2471 if (rsp->response_data[3] != 0) { 2472 ocs_log_test(io->ocs, "TMF status %08x\n", 2473 be32toh(*((uint32_t *)rsp->response_data))); 2474 rc = -1; 2475 break; 2476 } 2477 break; 2478 default: 2479 ocs_log_test(io->ocs, "status=%#x\n", scsi_status); 2480 rc = -1; 2481 } 2482 2483 ocs_scsi_io_free(io); 2484 2485 return rc; 2486 } 2487 2488 /** 2489 * @brief lookup target resource structure 2490 * 2491 * Arbitrarily support 2492 * - wildcard target ID + LU 2493 * - 0 target ID + non-wildcard LU 2494 * 2495 * @param ocs the driver instance's software context 2496 * @param ccb_h pointer to the CCB header 2497 * @param status returned status value 2498 * 2499 * @return pointer to the target resource, NULL if none available (e.g. if LU 2500 * is not enabled) 2501 */ 2502 static ocs_tgt_resource_t *ocs_tgt_resource_get(ocs_fcport *fcp, 2503 struct ccb_hdr *ccb_h, uint32_t *status) 2504 { 2505 target_id_t tid = ccb_h->target_id; 2506 lun_id_t lun = ccb_h->target_lun; 2507 2508 if (CAM_TARGET_WILDCARD == tid) { 2509 if (CAM_LUN_WILDCARD != lun) { 2510 *status = CAM_LUN_INVALID; 2511 return NULL; 2512 } 2513 return &fcp->targ_rsrc_wildcard; 2514 } else { 2515 if (lun < OCS_MAX_LUN) { 2516 return &fcp->targ_rsrc[lun]; 2517 } else { 2518 *status = CAM_LUN_INVALID; 2519 return NULL; 2520 } 2521 } 2522 2523 } 2524 2525 static int32_t 2526 ocs_tgt_resource_abort(struct ocs_softc *ocs, ocs_tgt_resource_t *trsrc) 2527 { 2528 union ccb *ccb = NULL; 2529 uint32_t count; 2530 2531 count = 0; 2532 do { 2533 ccb = (union ccb *)STAILQ_FIRST(&trsrc->atio); 2534 if (ccb) { 2535 STAILQ_REMOVE_HEAD(&trsrc->atio, sim_links.stqe); 2536 ccb->ccb_h.status = CAM_REQ_ABORTED; 2537 xpt_done(ccb); 2538 count++; 2539 } 2540 } while (ccb); 2541 2542 count = 0; 2543 do { 2544 ccb = (union ccb *)STAILQ_FIRST(&trsrc->inot); 2545 if (ccb) { 2546 STAILQ_REMOVE_HEAD(&trsrc->inot, sim_links.stqe); 2547 ccb->ccb_h.status = CAM_REQ_ABORTED; 2548 xpt_done(ccb); 2549 count++; 2550 } 2551 } while (ccb); 2552 2553 return 0; 2554 } 2555 2556 static void 2557 ocs_abort_atio(struct ocs_softc *ocs, union ccb *ccb) 2558 { 2559 2560 ocs_io_t *aio = NULL; 2561 ocs_tgt_resource_t *trsrc = NULL; 2562 uint32_t status = CAM_REQ_INVALID; 2563 struct ccb_hdr *cur = NULL; 2564 union ccb *accb = ccb->cab.abort_ccb; 2565 2566 int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)); 2567 ocs_fcport *fcp = FCPORT(ocs, bus); 2568 2569 trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status); 2570 if (trsrc != NULL) { 2571 STAILQ_FOREACH(cur, &trsrc->atio, sim_links.stqe) { 2572 if (cur != &accb->ccb_h) 2573 continue; 2574 2575 STAILQ_REMOVE(&trsrc->atio, cur, ccb_hdr, 2576 sim_links.stqe); 2577 accb->ccb_h.status = CAM_REQ_ABORTED; 2578 xpt_done(accb); 2579 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2580 return; 2581 } 2582 } 2583 2584 /* if the ATIO has a valid IO pointer, CAM is telling 2585 * the driver that the ATIO (which represents the entire 2586 * exchange) has been aborted. */ 2587 2588 aio = accb->ccb_h.ccb_io_ptr; 2589 if (aio == NULL) { 2590 ccb->ccb_h.status = CAM_UA_ABORT; 2591 return; 2592 } 2593 2594 device_printf(ocs->dev, 2595 "%s: XPT_ABORT ATIO state=%d tag=%#x" 2596 " xid=%#x flags=%#x\n", __func__, 2597 aio->tgt_io.state, aio->tag, 2598 aio->init_task_tag, aio->tgt_io.flags); 2599 /* Expectations are: 2600 * - abort task was received 2601 * - already aborted IO in the DEVICE 2602 * - already received NOTIFY ACKNOWLEDGE */ 2603 2604 if ((aio->tgt_io.flags & OCS_CAM_IO_F_ABORT_RECV) == 0) { 2605 device_printf(ocs->dev, "%s: abort not received or io completed \n", __func__); 2606 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2607 return; 2608 } 2609 2610 aio->tgt_io.flags |= OCS_CAM_IO_F_ABORT_CAM; 2611 ocs_target_io_free(aio); 2612 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2613 2614 return; 2615 } 2616 2617 static void 2618 ocs_abort_inot(struct ocs_softc *ocs, union ccb *ccb) 2619 { 2620 ocs_tgt_resource_t *trsrc = NULL; 2621 uint32_t status = CAM_REQ_INVALID; 2622 struct ccb_hdr *cur = NULL; 2623 union ccb *accb = ccb->cab.abort_ccb; 2624 2625 int bus = cam_sim_bus(xpt_path_sim((ccb)->ccb_h.path)); 2626 ocs_fcport *fcp = FCPORT(ocs, bus); 2627 2628 trsrc = ocs_tgt_resource_get(fcp, &accb->ccb_h, &status); 2629 if (trsrc) { 2630 STAILQ_FOREACH(cur, &trsrc->inot, sim_links.stqe) { 2631 if (cur != &accb->ccb_h) 2632 continue; 2633 2634 STAILQ_REMOVE(&trsrc->inot, cur, ccb_hdr, 2635 sim_links.stqe); 2636 accb->ccb_h.status = CAM_REQ_ABORTED; 2637 xpt_done(accb); 2638 ocs_set_ccb_status(ccb, CAM_REQ_CMP); 2639 return; 2640 } 2641 } 2642 2643 ocs_set_ccb_status(ccb, CAM_UA_ABORT); 2644 return; 2645 } 2646 2647 static uint32_t 2648 ocs_abort_initiator_io(struct ocs_softc *ocs, union ccb *accb) 2649 { 2650 2651 ocs_node_t *node = NULL; 2652 ocs_io_t *io = NULL; 2653 int32_t rc = 0; 2654 struct ccb_scsiio *csio = &accb->csio; 2655 2656 ocs_fcport *fcp = FCPORT(ocs, cam_sim_bus(xpt_path_sim((accb)->ccb_h.path))); 2657 node = ocs_node_get_instance(ocs, fcp->tgt[accb->ccb_h.target_id].node_id); 2658 if (node == NULL) { 2659 device_printf(ocs->dev, "%s: no device %d\n", 2660 __func__, accb->ccb_h.target_id); 2661 ocs_set_ccb_status(accb, CAM_DEV_NOT_THERE); 2662 xpt_done(accb); 2663 return (-1); 2664 } 2665 2666 io = ocs_scsi_io_alloc(node, OCS_SCSI_IO_ROLE_ORIGINATOR); 2667 if (io == NULL) { 2668 device_printf(ocs->dev, 2669 "%s: unable to alloc IO\n", __func__); 2670 ocs_set_ccb_status(accb, CAM_REQ_CMP_ERR); 2671 xpt_done(accb); 2672 return (-1); 2673 } 2674 2675 rc = ocs_scsi_send_tmf(node, io, 2676 (ocs_io_t *)csio->ccb_h.ccb_io_ptr, 2677 accb->ccb_h.target_lun, 2678 OCS_SCSI_TMF_ABORT_TASK, 2679 NULL, 0, 0, 2680 ocs_initiator_tmf_cb, NULL/*arg*/); 2681 2682 return rc; 2683 } 2684 2685 void 2686 ocs_scsi_ini_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj) 2687 { 2688 switch(type) { 2689 case OCS_SCSI_DDUMP_DEVICE: { 2690 //ocs_t *ocs = obj; 2691 break; 2692 } 2693 case OCS_SCSI_DDUMP_DOMAIN: { 2694 //ocs_domain_t *domain = obj; 2695 break; 2696 } 2697 case OCS_SCSI_DDUMP_SPORT: { 2698 //ocs_sport_t *sport = obj; 2699 break; 2700 } 2701 case OCS_SCSI_DDUMP_NODE: { 2702 //ocs_node_t *node = obj; 2703 break; 2704 } 2705 case OCS_SCSI_DDUMP_IO: { 2706 //ocs_io_t *io = obj; 2707 break; 2708 } 2709 default: { 2710 break; 2711 } 2712 } 2713 } 2714 2715 void 2716 ocs_scsi_tgt_ddump(ocs_textbuf_t *textbuf, ocs_scsi_ddump_type_e type, void *obj) 2717 { 2718 switch(type) { 2719 case OCS_SCSI_DDUMP_DEVICE: { 2720 //ocs_t *ocs = obj; 2721 break; 2722 } 2723 case OCS_SCSI_DDUMP_DOMAIN: { 2724 //ocs_domain_t *domain = obj; 2725 break; 2726 } 2727 case OCS_SCSI_DDUMP_SPORT: { 2728 //ocs_sport_t *sport = obj; 2729 break; 2730 } 2731 case OCS_SCSI_DDUMP_NODE: { 2732 //ocs_node_t *node = obj; 2733 break; 2734 } 2735 case OCS_SCSI_DDUMP_IO: { 2736 ocs_io_t *io = obj; 2737 char *state_str = NULL; 2738 2739 switch (io->tgt_io.state) { 2740 case OCS_CAM_IO_FREE: 2741 state_str = "FREE"; 2742 break; 2743 case OCS_CAM_IO_COMMAND: 2744 state_str = "COMMAND"; 2745 break; 2746 case OCS_CAM_IO_DATA: 2747 state_str = "DATA"; 2748 break; 2749 case OCS_CAM_IO_DATA_DONE: 2750 state_str = "DATA_DONE"; 2751 break; 2752 case OCS_CAM_IO_RESP: 2753 state_str = "RESP"; 2754 break; 2755 default: 2756 state_str = "xxx BAD xxx"; 2757 } 2758 ocs_ddump_value(textbuf, "cam_st", "%s", state_str); 2759 if (io->tgt_io.app) { 2760 ocs_ddump_value(textbuf, "cam_flags", "%#x", 2761 ((union ccb *)(io->tgt_io.app))->ccb_h.flags); 2762 ocs_ddump_value(textbuf, "cam_status", "%#x", 2763 ((union ccb *)(io->tgt_io.app))->ccb_h.status); 2764 } 2765 2766 break; 2767 } 2768 default: { 2769 break; 2770 } 2771 } 2772 } 2773 2774 int32_t ocs_scsi_get_block_vaddr(ocs_io_t *io, uint64_t blocknumber, 2775 ocs_scsi_vaddr_len_t addrlen[], 2776 uint32_t max_addrlen, void **dif_vaddr) 2777 { 2778 return -1; 2779 } 2780 2781 uint32_t 2782 ocs_get_crn(ocs_node_t *node, uint8_t *crn, uint64_t lun) 2783 { 2784 uint32_t idx; 2785 struct ocs_lun_crn *lcrn = NULL; 2786 idx = lun % OCS_MAX_LUN; 2787 2788 lcrn = node->ini_node.lun_crn[idx]; 2789 2790 if (lcrn == NULL) { 2791 lcrn = ocs_malloc(node->ocs, sizeof(struct ocs_lun_crn), 2792 M_ZERO|M_NOWAIT); 2793 if (lcrn == NULL) { 2794 return (1); 2795 } 2796 2797 lcrn->lun = lun; 2798 node->ini_node.lun_crn[idx] = lcrn; 2799 } 2800 2801 if (lcrn->lun != lun) { 2802 return (1); 2803 } 2804 2805 if (lcrn->crnseed == 0) 2806 lcrn->crnseed = 1; 2807 2808 *crn = lcrn->crnseed++; 2809 return (0); 2810 } 2811 2812 void 2813 ocs_del_crn(ocs_node_t *node) 2814 { 2815 uint32_t i; 2816 struct ocs_lun_crn *lcrn = NULL; 2817 2818 for(i = 0; i < OCS_MAX_LUN; i++) { 2819 lcrn = node->ini_node.lun_crn[i]; 2820 if (lcrn) { 2821 ocs_free(node->ocs, lcrn, sizeof(*lcrn)); 2822 } 2823 } 2824 2825 return; 2826 } 2827 2828 void 2829 ocs_reset_crn(ocs_node_t *node, uint64_t lun) 2830 { 2831 uint32_t idx; 2832 struct ocs_lun_crn *lcrn = NULL; 2833 idx = lun % OCS_MAX_LUN; 2834 2835 lcrn = node->ini_node.lun_crn[idx]; 2836 if (lcrn) 2837 lcrn->crnseed = 0; 2838 2839 return; 2840 } 2841