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