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