scsi_ctl.c revision 237601
1/*- 2 * Copyright (c) 2008, 2009 Silicon Graphics International Corp. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions, and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * substantially similar to the "NO WARRANTY" disclaimer below 13 * ("Disclaimer") and any redistribution must be conditioned upon 14 * including a substantially similar Disclaimer requirement for further 15 * binary redistribution. 16 * 17 * NO WARRANTY 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGES. 29 * 30 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/scsi_ctl.c#4 $ 31 */ 32/* 33 * Peripheral driver interface between CAM and CTL (CAM Target Layer). 34 * 35 * Author: Ken Merry <ken@FreeBSD.org> 36 */ 37 38#include <sys/cdefs.h> 39__FBSDID("$FreeBSD: head/sys/cam/ctl/scsi_ctl.c 237601 2012-06-26 14:51:35Z ken $"); 40 41#include <sys/param.h> 42#include <sys/queue.h> 43#include <sys/systm.h> 44#include <sys/kernel.h> 45#include <sys/lock.h> 46#include <sys/mutex.h> 47#include <sys/condvar.h> 48#include <sys/malloc.h> 49#include <sys/bus.h> 50#include <sys/endian.h> 51#include <sys/sbuf.h> 52#include <sys/sysctl.h> 53#include <sys/types.h> 54#include <sys/systm.h> 55#include <machine/bus.h> 56 57#include <cam/cam.h> 58#include <cam/cam_ccb.h> 59#include <cam/cam_periph.h> 60#include <cam/cam_queue.h> 61#include <cam/cam_xpt_periph.h> 62#include <cam/cam_debug.h> 63#include <cam/cam_sim.h> 64#include <cam/cam_xpt.h> 65 66#include <cam/scsi/scsi_all.h> 67#include <cam/scsi/scsi_message.h> 68 69#include <cam/ctl/ctl_io.h> 70#include <cam/ctl/ctl.h> 71#include <cam/ctl/ctl_frontend.h> 72#include <cam/ctl/ctl_util.h> 73#include <cam/ctl/ctl_error.h> 74 75typedef enum { 76 CTLFE_CCB_WAITING = 0x01 77} ctlfe_ccb_types; 78 79struct ctlfe_softc { 80 struct ctl_frontend fe; 81 path_id_t path_id; 82 struct cam_sim *sim; 83 char port_name[DEV_IDLEN]; 84 STAILQ_HEAD(, ctlfe_lun_softc) lun_softc_list; 85 STAILQ_ENTRY(ctlfe_softc) links; 86}; 87 88STAILQ_HEAD(, ctlfe_softc) ctlfe_softc_list; 89struct mtx ctlfe_list_mtx; 90static char ctlfe_mtx_desc[] = "ctlfelist"; 91static int ctlfe_dma_enabled = 1; 92#ifdef CTLFE_INIT_ENABLE 93static int ctlfe_max_targets = 1; 94static int ctlfe_num_targets = 0; 95#endif 96 97typedef enum { 98 CTLFE_LUN_NONE = 0x00, 99 CTLFE_LUN_WILDCARD = 0x01 100} ctlfe_lun_flags; 101 102struct ctlfe_lun_softc { 103 struct ctlfe_softc *parent_softc; 104 struct cam_periph *periph; 105 ctlfe_lun_flags flags; 106 struct callout dma_callout; 107 uint64_t ccbs_alloced; 108 uint64_t ccbs_freed; 109 uint64_t ctios_sent; 110 uint64_t ctios_returned; 111 uint64_t atios_sent; 112 uint64_t atios_returned; 113 uint64_t inots_sent; 114 uint64_t inots_returned; 115 /* bus_dma_tag_t dma_tag; */ 116 TAILQ_HEAD(, ccb_hdr) work_queue; 117 STAILQ_ENTRY(ctlfe_lun_softc) links; 118}; 119 120typedef enum { 121 CTLFE_CMD_NONE = 0x00, 122 CTLFE_CMD_PIECEWISE = 0x01 123} ctlfe_cmd_flags; 124 125/* 126 * The size limit of this structure is CTL_PORT_PRIV_SIZE, from ctl_io.h. 127 * Currently that is 600 bytes. 128 */ 129struct ctlfe_lun_cmd_info { 130 int cur_transfer_index; 131 ctlfe_cmd_flags flags; 132 /* 133 * XXX KDM struct bus_dma_segment is 8 bytes on i386, and 16 134 * bytes on amd64. So with 32 elements, this is 256 bytes on 135 * i386 and 512 bytes on amd64. 136 */ 137 bus_dma_segment_t cam_sglist[32]; 138}; 139 140/* 141 * When we register the adapter/bus, request that this many ctl_ios be 142 * allocated. This should be the maximum supported by the adapter, but we 143 * currently don't have a way to get that back from the path inquiry. 144 * XXX KDM add that to the path inquiry. 145 */ 146#define CTLFE_REQ_CTL_IO 4096 147/* 148 * Number of Accept Target I/O CCBs to allocate and queue down to the 149 * adapter per LUN. 150 * XXX KDM should this be controlled by CTL? 151 */ 152#define CTLFE_ATIO_PER_LUN 1024 153/* 154 * Number of Immediate Notify CCBs (used for aborts, resets, etc.) to 155 * allocate and queue down to the adapter per LUN. 156 * XXX KDM should this be controlled by CTL? 157 */ 158#define CTLFE_IN_PER_LUN 1024 159 160/* 161 * Timeout (in seconds) on CTIO CCB allocation for doing a DMA or sending 162 * status to the initiator. The SIM is expected to have its own timeouts, 163 * so we're not putting this timeout around the CCB execution time. The 164 * SIM should timeout and let us know if it has an issue. 165 */ 166#define CTLFE_DMA_TIMEOUT 60 167 168/* 169 * Turn this on to enable extra debugging prints. 170 */ 171#if 0 172#define CTLFE_DEBUG 173#endif 174 175/* 176 * Use randomly assigned WWNN/WWPN values. This is to work around an issue 177 * in the FreeBSD initiator that makes it unable to rescan the target if 178 * the target gets rebooted and the WWNN/WWPN stay the same. 179 */ 180#if 0 181#define RANDOM_WWNN 182#endif 183 184SYSCTL_INT(_kern_cam_ctl, OID_AUTO, dma_enabled, CTLFLAG_RW, 185 &ctlfe_dma_enabled, 0, "DMA enabled"); 186MALLOC_DEFINE(M_CTLFE, "CAM CTL FE", "CAM CTL FE interface"); 187 188#define ccb_type ppriv_field0 189/* This is only used in the ATIO */ 190#define io_ptr ppriv_ptr1 191 192/* This is only used in the CTIO */ 193#define ccb_atio ppriv_ptr1 194 195int ctlfeinitialize(void); 196void ctlfeshutdown(void); 197static periph_init_t ctlfeinit; 198static void ctlfeasync(void *callback_arg, uint32_t code, 199 struct cam_path *path, void *arg); 200static periph_ctor_t ctlferegister; 201static periph_oninv_t ctlfeoninvalidate; 202static periph_dtor_t ctlfecleanup; 203static periph_start_t ctlfestart; 204static void ctlfedone(struct cam_periph *periph, 205 union ccb *done_ccb); 206 207static void ctlfe_onoffline(void *arg, int online); 208static void ctlfe_online(void *arg); 209static void ctlfe_offline(void *arg); 210static int ctlfe_targ_enable(void *arg, struct ctl_id targ_id); 211static int ctlfe_targ_disable(void *arg, struct ctl_id targ_id); 212static int ctlfe_lun_enable(void *arg, struct ctl_id targ_id, 213 int lun_id); 214static int ctlfe_lun_disable(void *arg, struct ctl_id targ_id, 215 int lun_id); 216static void ctlfe_dump_sim(struct cam_sim *sim); 217static void ctlfe_dump_queue(struct ctlfe_lun_softc *softc); 218static void ctlfe_dma_timeout(void *arg); 219static void ctlfe_datamove_done(union ctl_io *io); 220static void ctlfe_dump(void); 221 222static struct periph_driver ctlfe_driver = 223{ 224 ctlfeinit, "ctl", 225 TAILQ_HEAD_INITIALIZER(ctlfe_driver.units), /*generation*/ 0 226}; 227PERIPHDRIVER_DECLARE(ctl, ctlfe_driver); 228 229extern struct ctl_softc *control_softc; 230 231int 232ctlfeinitialize(void) 233{ 234 cam_status status; 235 236 STAILQ_INIT(&ctlfe_softc_list); 237 238 mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF); 239 240 xpt_lock_buses(); 241 periphdriver_register(&ctlfe_driver); 242 xpt_unlock_buses(); 243 244 status = xpt_register_async(AC_PATH_REGISTERED | AC_PATH_DEREGISTERED | 245 AC_CONTRACT, ctlfeasync, NULL, NULL); 246 247 if (status != CAM_REQ_CMP) { 248 printf("ctl: Failed to attach async callback due to CAM " 249 "status 0x%x!\n", status); 250 } 251 252 return (0); 253} 254 255void 256ctlfeshutdown(void) 257{ 258 return; 259} 260 261void 262ctlfeinit(void) 263{ 264 cam_status status; 265 266 STAILQ_INIT(&ctlfe_softc_list); 267 268 mtx_init(&ctlfe_list_mtx, ctlfe_mtx_desc, NULL, MTX_DEF); 269 270 KASSERT(control_softc != NULL, ("CTL is not initialized!")); 271 272 status = xpt_register_async(AC_PATH_REGISTERED | AC_PATH_DEREGISTERED | 273 AC_CONTRACT, ctlfeasync, NULL, NULL); 274 275 if (status != CAM_REQ_CMP) { 276 printf("ctl: Failed to attach async callback due to CAM " 277 "status 0x%x!\n", status); 278 } 279} 280 281static void 282ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg) 283{ 284 285#ifdef CTLFEDEBUG 286 printf("%s: entered\n", __func__); 287#endif 288 289 /* 290 * When a new path gets registered, and it is capable of target 291 * mode, go ahead and attach. Later on, we may need to be more 292 * selective, but for now this will be sufficient. 293 */ 294 switch (code) { 295 case AC_PATH_REGISTERED: { 296 struct ctl_frontend *fe; 297 struct ctlfe_softc *bus_softc; 298 struct ctlfe_lun_softc *lun_softc; 299 struct cam_path *path; 300 struct ccb_pathinq *cpi; 301 cam_status status; 302 int retval; 303 304 cpi = (struct ccb_pathinq *)arg; 305 306 /* Don't attach if it doesn't support target mode */ 307 if ((cpi->target_sprt & PIT_PROCESSOR) == 0) { 308#ifdef CTLFEDEBUG 309 printf("%s: SIM %s%d doesn't support target mode\n", 310 __func__, cpi->dev_name, cpi->unit_number); 311#endif 312 break; 313 } 314 315#ifdef CTLFE_INIT_ENABLE 316 if (ctlfe_num_targets >= ctlfe_max_targets) { 317 union ccb *ccb; 318 struct cam_sim *sim; 319 320 ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, 321 M_NOWAIT | M_ZERO); 322 if (ccb == NULL) { 323 printf("%s: unable to malloc CCB!\n", __func__); 324 xpt_free_path(path); 325 return; 326 } 327 xpt_setup_ccb(&ccb->ccb_h, cpi->ccb_h.path, 328 /*priority*/ 1); 329 330 sim = xpt_path_sim(cpi->ccb_h.path); 331 332 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; 333 ccb->knob.xport_specific.valid = KNOB_VALID_ROLE; 334 ccb->knob.xport_specific.fc.role = KNOB_ROLE_INITIATOR; 335 336 /* We should hold the SIM lock here */ 337 mtx_assert(sim->mtx, MA_OWNED); 338 339 xpt_action(ccb); 340 341 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != 342 CAM_REQ_CMP) { 343 printf("%s: SIM %s%d (path id %d) initiator " 344 "enable failed with status %#x\n", 345 __func__, cpi->dev_name, 346 cpi->unit_number, cpi->ccb_h.path_id, 347 ccb->ccb_h.status); 348 } else { 349 printf("%s: SIM %s%d (path id %d) initiator " 350 "enable succeeded\n", 351 __func__, cpi->dev_name, 352 cpi->unit_number, cpi->ccb_h.path_id); 353 } 354 355 free(ccb, M_TEMP); 356 357 break; 358 } else { 359 ctlfe_num_targets++; 360 } 361 362 printf("%s: ctlfe_num_targets = %d\n", __func__, 363 ctlfe_num_targets); 364#endif /* CTLFE_INIT_ENABLE */ 365 366 /* 367 * We're in an interrupt context here, so we have to 368 * use M_NOWAIT. Of course this means trouble if we 369 * can't allocate memory. 370 */ 371 bus_softc = malloc(sizeof(*bus_softc), M_CTLFE, 372 M_NOWAIT | M_ZERO); 373 if (bus_softc == NULL) { 374 printf("%s: unable to malloc %zd bytes for softc\n", 375 __func__, sizeof(*bus_softc)); 376 return; 377 } 378 379 bus_softc->path_id = cpi->ccb_h.path_id; 380 bus_softc->sim = xpt_path_sim(cpi->ccb_h.path); 381 STAILQ_INIT(&bus_softc->lun_softc_list); 382 383 fe = &bus_softc->fe; 384 385 /* 386 * XXX KDM should we be more accurate here ? 387 */ 388 if (cpi->transport == XPORT_FC) 389 fe->port_type = CTL_PORT_FC; 390 else 391 fe->port_type = CTL_PORT_SCSI; 392 393 /* XXX KDM what should the real number be here? */ 394 fe->num_requested_ctl_io = 4096; 395 snprintf(bus_softc->port_name, sizeof(bus_softc->port_name), 396 "%s%d", cpi->dev_name, cpi->unit_number); 397 /* 398 * XXX KDM it would be nice to allocate storage in the 399 * frontend structure itself. 400 */ 401 fe->port_name = bus_softc->port_name; 402 fe->physical_port = cpi->unit_number; 403 fe->virtual_port = cpi->bus_id; 404 fe->port_online = ctlfe_online; 405 fe->port_offline = ctlfe_offline; 406 fe->onoff_arg = bus_softc; 407 fe->targ_enable = ctlfe_targ_enable; 408 fe->targ_disable = ctlfe_targ_disable; 409 fe->lun_enable = ctlfe_lun_enable; 410 fe->lun_disable = ctlfe_lun_disable; 411 fe->targ_lun_arg = bus_softc; 412 fe->fe_datamove = ctlfe_datamove_done; 413 fe->fe_done = ctlfe_datamove_done; 414 fe->fe_dump = ctlfe_dump; 415 /* 416 * XXX KDM the path inquiry doesn't give us the maximum 417 * number of targets supported. 418 */ 419 fe->max_targets = cpi->max_target; 420 fe->max_target_id = cpi->max_target; 421 422 /* 423 * XXX KDM need to figure out whether we're the master or 424 * slave. 425 */ 426#ifdef CTLFEDEBUG 427 printf("%s: calling ctl_frontend_register() for %s%d\n", 428 __func__, cpi->dev_name, cpi->unit_number); 429#endif 430 retval = ctl_frontend_register(fe, /*master_SC*/ 1); 431 if (retval != 0) { 432 printf("%s: ctl_frontend_register() failed with " 433 "error %d!\n", __func__, retval); 434 free(bus_softc, M_CTLFE); 435 break; 436 } else { 437 mtx_lock(&ctlfe_list_mtx); 438 STAILQ_INSERT_TAIL(&ctlfe_softc_list, bus_softc, links); 439 mtx_unlock(&ctlfe_list_mtx); 440 } 441 442 status = xpt_create_path(&path, /*periph*/ NULL, 443 bus_softc->path_id,CAM_TARGET_WILDCARD, 444 CAM_LUN_WILDCARD); 445 if (status != CAM_REQ_CMP) { 446 printf("%s: unable to create path for wildcard " 447 "periph\n", __func__); 448 break; 449 } 450 lun_softc = malloc(sizeof(*lun_softc), M_CTLFE, 451 M_NOWAIT | M_ZERO); 452 if (lun_softc == NULL) { 453 xpt_print(path, "%s: unable to allocate softc for " 454 "wildcard periph\n", __func__); 455 xpt_free_path(path); 456 break; 457 } 458 459 lun_softc->parent_softc = bus_softc; 460 lun_softc->flags |= CTLFE_LUN_WILDCARD; 461 462 status = cam_periph_alloc(ctlferegister, 463 ctlfeoninvalidate, 464 ctlfecleanup, 465 ctlfestart, 466 "ctl", 467 CAM_PERIPH_BIO, 468 path, 469 ctlfeasync, 470 0, 471 lun_softc); 472 473 xpt_free_path(path); 474 475 break; 476 } 477 case AC_PATH_DEREGISTERED: 478 /* ctl_frontend_deregister() */ 479 break; 480 case AC_CONTRACT: { 481 struct ac_contract *ac; 482 483 ac = (struct ac_contract *)arg; 484 485 switch (ac->contract_number) { 486 case AC_CONTRACT_DEV_CHG: { 487 struct ac_device_changed *dev_chg; 488 struct ctlfe_softc *softc; 489 int retval, found; 490 491 dev_chg = (struct ac_device_changed *)ac->contract_data; 492 493 printf("%s: WWPN %#jx port 0x%06x path %u target %u %s\n", 494 __func__, dev_chg->wwpn, dev_chg->port, 495 xpt_path_path_id(path), dev_chg->target, 496 (dev_chg->arrived == 0) ? "left" : "arrived"); 497 498 found = 0; 499 500 mtx_lock(&ctlfe_list_mtx); 501 STAILQ_FOREACH(softc, &ctlfe_softc_list, links) { 502 if (softc->path_id == xpt_path_path_id(path)) { 503 found = 1; 504 break; 505 } 506 } 507 mtx_unlock(&ctlfe_list_mtx); 508 509 if (found == 0) { 510 printf("%s: CTL port for CAM path %u not " 511 "found!\n", __func__, 512 xpt_path_path_id(path)); 513 break; 514 } 515 if (dev_chg->arrived != 0) { 516 retval = ctl_add_initiator(dev_chg->wwpn, 517 softc->fe.targ_port, dev_chg->target); 518 } else { 519 retval = ctl_remove_initiator( 520 softc->fe.targ_port, dev_chg->target); 521 } 522 523 if (retval != 0) { 524 printf("%s: could not %s port %d iid %u " 525 "WWPN %#jx!\n", __func__, 526 (dev_chg->arrived != 0) ? "add" : 527 "remove", softc->fe.targ_port, 528 dev_chg->target, 529 (uintmax_t)dev_chg->wwpn); 530 } 531 break; 532 } 533 default: 534 printf("%s: unsupported contract number %ju\n", 535 __func__, (uintmax_t)ac->contract_number); 536 break; 537 } 538 break; 539 } 540 default: 541 break; 542 } 543} 544 545static cam_status 546ctlferegister(struct cam_periph *periph, void *arg) 547{ 548 struct ctlfe_softc *bus_softc; 549 struct ctlfe_lun_softc *softc; 550 struct cam_sim *sim; 551 union ccb en_lun_ccb; 552 cam_status status; 553 int i; 554 555 softc = (struct ctlfe_lun_softc *)arg; 556 bus_softc = softc->parent_softc; 557 sim = xpt_path_sim(periph->path); 558 559 TAILQ_INIT(&softc->work_queue); 560 softc->periph = periph; 561 562 callout_init_mtx(&softc->dma_callout, sim->mtx, /*flags*/ 0); 563 periph->softc = softc; 564 565 xpt_setup_ccb(&en_lun_ccb.ccb_h, periph->path, /*priority*/ 1); 566 en_lun_ccb.ccb_h.func_code = XPT_EN_LUN; 567 en_lun_ccb.cel.grp6_len = 0; 568 en_lun_ccb.cel.grp7_len = 0; 569 en_lun_ccb.cel.enable = 1; 570 xpt_action(&en_lun_ccb); 571 status = (en_lun_ccb.ccb_h.status & CAM_STATUS_MASK); 572 if (status != CAM_REQ_CMP) { 573 xpt_print(periph->path, "%s: Enable LUN failed, status 0x%x\n", 574 __func__, en_lun_ccb.ccb_h.status); 575 return (status); 576 } 577 578 status = CAM_REQ_CMP; 579 580 for (i = 0; i < CTLFE_ATIO_PER_LUN; i++) { 581 union ccb *new_ccb; 582 583 new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE, 584 M_ZERO|M_NOWAIT); 585 if (new_ccb == NULL) { 586 status = CAM_RESRC_UNAVAIL; 587 break; 588 } 589 xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1); 590 new_ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 591 new_ccb->ccb_h.cbfcnp = ctlfedone; 592 xpt_action(new_ccb); 593 softc->atios_sent++; 594 status = new_ccb->ccb_h.status; 595 if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 596 free(new_ccb, M_CTLFE); 597 break; 598 } 599 } 600 601 status = cam_periph_acquire(periph); 602 if ((status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 603 xpt_print(periph->path, "%s: could not acquire reference " 604 "count, status = %#x\n", __func__, status); 605 return (status); 606 } 607 608 if (i == 0) { 609 xpt_print(periph->path, "%s: could not allocate ATIO CCBs, " 610 "status 0x%x\n", __func__, status); 611 return (CAM_REQ_CMP_ERR); 612 } 613 614 for (i = 0; i < CTLFE_IN_PER_LUN; i++) { 615 union ccb *new_ccb; 616 617 new_ccb = (union ccb *)malloc(sizeof(*new_ccb), M_CTLFE, 618 M_ZERO|M_NOWAIT); 619 if (new_ccb == NULL) { 620 status = CAM_RESRC_UNAVAIL; 621 break; 622 } 623 624 xpt_setup_ccb(&new_ccb->ccb_h, periph->path, /*priority*/ 1); 625 new_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; 626 new_ccb->ccb_h.cbfcnp = ctlfedone; 627 xpt_action(new_ccb); 628 softc->inots_sent++; 629 status = new_ccb->ccb_h.status; 630 if ((status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 631 /* 632 * Note that we don't free the CCB here. If the 633 * status is not CAM_REQ_INPROG, then we're 634 * probably talking to a SIM that says it is 635 * target-capable but doesn't support the 636 * XPT_IMMEDIATE_NOTIFY CCB. i.e. it supports the 637 * older API. In that case, it'll call xpt_done() 638 * on the CCB, and we need to free it in our done 639 * routine as a result. 640 */ 641 break; 642 } 643 } 644 if ((i == 0) 645 || (status != CAM_REQ_INPROG)) { 646 xpt_print(periph->path, "%s: could not allocate immediate " 647 "notify CCBs, status 0x%x\n", __func__, status); 648 return (CAM_REQ_CMP_ERR); 649 } 650 return (CAM_REQ_CMP); 651} 652 653static void 654ctlfeoninvalidate(struct cam_periph *periph) 655{ 656 union ccb en_lun_ccb; 657 cam_status status; 658 struct ctlfe_lun_softc *softc; 659 660 softc = (struct ctlfe_lun_softc *)periph->softc; 661 662 xpt_setup_ccb(&en_lun_ccb.ccb_h, periph->path, /*priority*/ 1); 663 en_lun_ccb.ccb_h.func_code = XPT_EN_LUN; 664 en_lun_ccb.cel.grp6_len = 0; 665 en_lun_ccb.cel.grp7_len = 0; 666 en_lun_ccb.cel.enable = 0; 667 xpt_action(&en_lun_ccb); 668 status = (en_lun_ccb.ccb_h.status & CAM_STATUS_MASK); 669 if (status != CAM_REQ_CMP) { 670 xpt_print(periph->path, "%s: Disable LUN failed, status 0x%x\n", 671 __func__, en_lun_ccb.ccb_h.status); 672 /* 673 * XXX KDM what do we do now? 674 */ 675 } 676 xpt_print(periph->path, "LUN removed, %ju ATIOs outstanding, %ju " 677 "INOTs outstanding, %d refs\n", softc->atios_sent - 678 softc->atios_returned, softc->inots_sent - 679 softc->inots_returned, periph->refcount); 680} 681 682static void 683ctlfecleanup(struct cam_periph *periph) 684{ 685 struct ctlfe_lun_softc *softc; 686 struct ctlfe_softc *bus_softc; 687 688 xpt_print(periph->path, "%s: Called\n", __func__); 689 690 softc = (struct ctlfe_lun_softc *)periph->softc; 691 bus_softc = softc->parent_softc; 692 693 STAILQ_REMOVE(&bus_softc->lun_softc_list, softc, ctlfe_lun_softc,links); 694 695 /* 696 * XXX KDM is there anything else that needs to be done here? 697 */ 698 free(softc, M_CTLFE); 699} 700 701static void 702ctlfestart(struct cam_periph *periph, union ccb *start_ccb) 703{ 704 struct ctlfe_lun_softc *softc; 705 struct ccb_hdr *ccb_h; 706 707 softc = (struct ctlfe_lun_softc *)periph->softc; 708 709 softc->ccbs_alloced++; 710 711 ccb_h = TAILQ_FIRST(&softc->work_queue); 712 if (periph->immediate_priority <= periph->pinfo.priority) { 713 panic("shouldn't get to the CCB waiting case!"); 714 start_ccb->ccb_h.ccb_type = CTLFE_CCB_WAITING; 715 SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, 716 periph_links.sle); 717 periph->immediate_priority = CAM_PRIORITY_NONE; 718 wakeup(&periph->ccb_list); 719 } else if (ccb_h == NULL) { 720 softc->ccbs_freed++; 721 xpt_release_ccb(start_ccb); 722 } else { 723 struct ccb_accept_tio *atio; 724 struct ccb_scsiio *csio; 725 uint8_t *data_ptr; 726 uint32_t dxfer_len; 727 ccb_flags flags; 728 union ctl_io *io; 729 uint8_t scsi_status; 730 731 /* Take the ATIO off the work queue */ 732 TAILQ_REMOVE(&softc->work_queue, ccb_h, periph_links.tqe); 733 atio = (struct ccb_accept_tio *)ccb_h; 734 io = (union ctl_io *)ccb_h->io_ptr; 735 csio = &start_ccb->csio; 736 737 flags = atio->ccb_h.flags & 738 (CAM_DIS_DISCONNECT|CAM_TAG_ACTION_VALID|CAM_DIR_MASK); 739 740 if ((io == NULL) 741 || (io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) { 742 /* 743 * We're done, send status back. 744 */ 745 flags |= CAM_SEND_STATUS; 746 if (io == NULL) { 747 scsi_status = SCSI_STATUS_BUSY; 748 csio->sense_len = 0; 749 } else if ((io->io_hdr.status & CTL_STATUS_MASK) == 750 CTL_CMD_ABORTED) { 751 io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED; 752 753 /* 754 * If this command was aborted, we don't 755 * need to send status back to the SIM. 756 * Just free the CTIO and ctl_io, and 757 * recycle the ATIO back to the SIM. 758 */ 759 xpt_print(periph->path, "%s: aborted " 760 "command 0x%04x discarded\n", 761 __func__, io->scsiio.tag_num); 762 ctl_free_io(io); 763 /* 764 * For a wildcard attachment, commands can 765 * come in with a specific target/lun. Reset 766 * the target and LUN fields back to the 767 * wildcard values before we send them back 768 * down to the SIM. The SIM has a wildcard 769 * LUN enabled, not whatever target/lun 770 * these happened to be. 771 */ 772 if (softc->flags & CTLFE_LUN_WILDCARD) { 773 atio->ccb_h.target_id = 774 CAM_TARGET_WILDCARD; 775 atio->ccb_h.target_lun = 776 CAM_LUN_WILDCARD; 777 } 778 779 if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) { 780 cam_release_devq(periph->path, 781 /*relsim_flags*/0, 782 /*reduction*/0, 783 /*timeout*/0, 784 /*getcount_only*/0); 785 atio->ccb_h.status &= ~CAM_DEV_QFRZN; 786 } 787 788 ccb_h = TAILQ_FIRST(&softc->work_queue); 789 790 if (atio->ccb_h.func_code != 791 XPT_ACCEPT_TARGET_IO) { 792 xpt_print(periph->path, "%s: func_code " 793 "is %#x\n", __func__, 794 atio->ccb_h.func_code); 795 } 796 start_ccb->ccb_h.func_code = XPT_ABORT; 797 start_ccb->cab.abort_ccb = (union ccb *)atio; 798 start_ccb->ccb_h.cbfcnp = ctlfedone; 799 800 /* Tell the SIM that we've aborted this ATIO */ 801 xpt_action(start_ccb); 802 softc->ccbs_freed++; 803 xpt_release_ccb(start_ccb); 804 805 /* 806 * Send the ATIO back down to the SIM. 807 */ 808 xpt_action((union ccb *)atio); 809 softc->atios_sent++; 810 811 /* 812 * If we still have work to do, ask for 813 * another CCB. Otherwise, deactivate our 814 * callout. 815 */ 816 if (ccb_h != NULL) 817 xpt_schedule(periph, /*priority*/ 1); 818 else 819 callout_stop(&softc->dma_callout); 820 821 return; 822 } else { 823 io->io_hdr.flags &= ~CTL_FLAG_STATUS_QUEUED; 824 scsi_status = io->scsiio.scsi_status; 825 csio->sense_len = io->scsiio.sense_len; 826 } 827 data_ptr = NULL; 828 dxfer_len = 0; 829 if (io == NULL) { 830 printf("%s: tag %04x io is NULL\n", __func__, 831 atio->tag_id); 832 } else { 833#ifdef CTLFEDEBUG 834 printf("%s: tag %04x status %x\n", __func__, 835 atio->tag_id, io->io_hdr.status); 836#endif 837 } 838 csio->sglist_cnt = 0; 839 if (csio->sense_len != 0) { 840 csio->sense_data = io->scsiio.sense_data; 841 flags |= CAM_SEND_SENSE; 842 } else if (scsi_status == SCSI_STATUS_CHECK_COND) { 843 xpt_print(periph->path, "%s: check condition " 844 "with no sense\n", __func__); 845 } 846 } else { 847 struct ctlfe_lun_cmd_info *cmd_info; 848 849 /* 850 * Datamove call, we need to setup the S/G list. 851 * If we pass in a S/G list, the isp(4) driver at 852 * least expects physical/bus addresses. 853 */ 854 855 cmd_info = (struct ctlfe_lun_cmd_info *) 856 io->io_hdr.port_priv; 857 858 KASSERT(sizeof(*cmd_info) < CTL_PORT_PRIV_SIZE, 859 ("%s: sizeof(struct ctlfe_lun_cmd_info) %zd < " 860 "CTL_PORT_PRIV_SIZE %d", __func__, 861 sizeof(*cmd_info), CTL_PORT_PRIV_SIZE)); 862 io->io_hdr.flags &= ~CTL_FLAG_DMA_QUEUED; 863 864 /* 865 * Need to zero this, in case it has been used for 866 * a previous datamove for this particular I/O. 867 */ 868 bzero(cmd_info, sizeof(*cmd_info)); 869 scsi_status = 0; 870 871 /* 872 * Set the direction, relative to the initiator. 873 */ 874 flags &= ~CAM_DIR_MASK; 875 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == 876 CTL_FLAG_DATA_IN) 877 flags |= CAM_DIR_IN; 878 else 879 flags |= CAM_DIR_OUT; 880 881 csio->cdb_len = atio->cdb_len; 882 883 if (io->scsiio.kern_sg_entries == 0) { 884 /* No S/G list */ 885 data_ptr = io->scsiio.kern_data_ptr; 886 dxfer_len = io->scsiio.kern_data_len; 887 csio->sglist_cnt = 0; 888 889 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) 890 flags |= CAM_DATA_PHYS; 891 } else if (io->scsiio.kern_sg_entries <= 892 (sizeof(cmd_info->cam_sglist)/ 893 sizeof(cmd_info->cam_sglist[0]))) { 894 /* 895 * S/G list with physical or virtual pointers. 896 * Just populate the CAM S/G list with the 897 * pointers. 898 */ 899 int i; 900 struct ctl_sg_entry *ctl_sglist; 901 bus_dma_segment_t *cam_sglist; 902 903 ctl_sglist = (struct ctl_sg_entry *) 904 io->scsiio.kern_data_ptr; 905 cam_sglist = cmd_info->cam_sglist; 906 907 for (i = 0; i < io->scsiio.kern_sg_entries;i++){ 908 cam_sglist[i].ds_addr = 909 (bus_addr_t)ctl_sglist[i].addr; 910 cam_sglist[i].ds_len = 911 ctl_sglist[i].len; 912 } 913 csio->sglist_cnt = io->scsiio.kern_sg_entries; 914 flags |= CAM_SCATTER_VALID; 915 if (io->io_hdr.flags & CTL_FLAG_BUS_ADDR) 916 flags |= CAM_SG_LIST_PHYS; 917 else 918 flags &= ~CAM_SG_LIST_PHYS; 919 data_ptr = (uint8_t *)cam_sglist; 920 dxfer_len = io->scsiio.kern_data_len; 921 } else { 922 /* S/G list with virtual pointers */ 923 struct ctl_sg_entry *sglist; 924 int *ti; 925 926 /* 927 * XXX KDM this is a temporary hack. The 928 * isp(4) driver can't deal with S/G lists 929 * with virtual pointers, so we need to 930 * go through and send down one virtual 931 * pointer at a time. 932 */ 933 sglist = (struct ctl_sg_entry *) 934 io->scsiio.kern_data_ptr; 935 ti = &cmd_info->cur_transfer_index; 936 data_ptr = sglist[*ti].addr; 937 dxfer_len = sglist[*ti].len; 938 csio->sglist_cnt = 0; 939 cmd_info->flags |= CTLFE_CMD_PIECEWISE; 940 (*ti)++; 941 } 942 943 io->scsiio.ext_data_filled += dxfer_len; 944 945 if (io->scsiio.ext_data_filled > 946 io->scsiio.kern_total_len) { 947 xpt_print(periph->path, "%s: tag 0x%04x " 948 "fill len %u > total %u\n", 949 __func__, io->scsiio.tag_num, 950 io->scsiio.ext_data_filled, 951 io->scsiio.kern_total_len); 952 } 953 } 954 955#ifdef CTLFEDEBUG 956 printf("%s: %s: tag %04x flags %x ptr %p len %u\n", __func__, 957 (flags & CAM_SEND_STATUS) ? "done" : "datamove", 958 atio->tag_id, flags, data_ptr, dxfer_len); 959#endif 960 961 /* 962 * Valid combinations: 963 * - CAM_SEND_STATUS, SCATTER_VALID = 0, dxfer_len = 0, 964 * sglist_cnt = 0 965 * - CAM_SEND_STATUS = 0, SCATTER_VALID = 0, dxfer_len != 0, 966 * sglist_cnt = 0 967 * - CAM_SEND_STATUS = 0, SCATTER_VALID, dxfer_len != 0, 968 * sglist_cnt != 0 969 */ 970#ifdef CTLFEDEBUG 971 if (((flags & CAM_SEND_STATUS) 972 && (((flags & CAM_SCATTER_VALID) != 0) 973 || (dxfer_len != 0) 974 || (csio->sglist_cnt != 0))) 975 || (((flags & CAM_SEND_STATUS) == 0) 976 && (dxfer_len == 0)) 977 || ((flags & CAM_SCATTER_VALID) 978 && (csio->sglist_cnt == 0)) 979 || (((flags & CAM_SCATTER_VALID) == 0) 980 && (csio->sglist_cnt != 0))) { 981 printf("%s: tag %04x cdb %02x flags %#x dxfer_len " 982 "%d sg %u\n", __func__, atio->tag_id, 983 atio->cdb_io.cdb_bytes[0], flags, dxfer_len, 984 csio->sglist_cnt); 985 if (io != NULL) { 986 printf("%s: tag %04x io status %#x\n", __func__, 987 atio->tag_id, io->io_hdr.status); 988 } else { 989 printf("%s: tag %04x no associated io\n", 990 __func__, atio->tag_id); 991 } 992 } 993#endif 994 cam_fill_ctio(csio, 995 /*retries*/ 2, 996 ctlfedone, 997 flags, 998 (flags & CAM_TAG_ACTION_VALID) ? 999 MSG_SIMPLE_Q_TAG : 0, 1000 atio->tag_id, 1001 atio->init_id, 1002 scsi_status, 1003 /*data_ptr*/ data_ptr, 1004 /*dxfer_len*/ dxfer_len, 1005 /*timeout*/ 5 * 1000); 1006 start_ccb->ccb_h.ccb_atio = atio; 1007 if (((flags & CAM_SEND_STATUS) == 0) 1008 && (io != NULL)) 1009 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG; 1010 1011 softc->ctios_sent++; 1012 1013 xpt_action(start_ccb); 1014 1015 if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) { 1016 cam_release_devq(periph->path, 1017 /*relsim_flags*/0, 1018 /*reduction*/0, 1019 /*timeout*/0, 1020 /*getcount_only*/0); 1021 atio->ccb_h.status &= ~CAM_DEV_QFRZN; 1022 } 1023 1024 ccb_h = TAILQ_FIRST(&softc->work_queue); 1025 } 1026 /* 1027 * If we still have work to do, ask for another CCB. Otherwise, 1028 * deactivate our callout. 1029 */ 1030 if (ccb_h != NULL) 1031 xpt_schedule(periph, /*priority*/ 1); 1032 else 1033 callout_stop(&softc->dma_callout); 1034} 1035 1036static void 1037ctlfe_free_ccb(struct cam_periph *periph, union ccb *ccb) 1038{ 1039 struct ctlfe_lun_softc *softc; 1040 1041 softc = (struct ctlfe_lun_softc *)periph->softc; 1042 1043 switch (ccb->ccb_h.func_code) { 1044 case XPT_ACCEPT_TARGET_IO: 1045 softc->atios_returned++; 1046 break; 1047 case XPT_IMMEDIATE_NOTIFY: 1048 case XPT_NOTIFY_ACKNOWLEDGE: 1049 softc->inots_returned++; 1050 break; 1051 default: 1052 break; 1053 } 1054 1055 free(ccb, M_CTLFE); 1056 1057 KASSERT(softc->atios_returned <= softc->atios_sent, ("%s: " 1058 "atios_returned %ju > atios_sent %ju", __func__, 1059 softc->atios_returned, softc->atios_sent)); 1060 KASSERT(softc->inots_returned <= softc->inots_sent, ("%s: " 1061 "inots_returned %ju > inots_sent %ju", __func__, 1062 softc->inots_returned, softc->inots_sent)); 1063 1064 /* 1065 * If we have received all of our CCBs, we can release our 1066 * reference on the peripheral driver. It will probably go away 1067 * now. 1068 */ 1069 if ((softc->atios_returned == softc->atios_sent) 1070 && (softc->inots_returned == softc->inots_sent)) { 1071 cam_periph_release_locked(periph); 1072 } 1073} 1074 1075static void 1076ctlfedone(struct cam_periph *periph, union ccb *done_ccb) 1077{ 1078 struct ctlfe_lun_softc *softc; 1079 struct ctlfe_softc *bus_softc; 1080 1081#ifdef CTLFE_DEBUG 1082 printf("%s: entered, func_code = %#x, type = %#lx\n", __func__, 1083 done_ccb->ccb_h.func_code, done_ccb->ccb_h.ccb_type); 1084#endif 1085 1086 softc = (struct ctlfe_lun_softc *)periph->softc; 1087 bus_softc = softc->parent_softc; 1088 1089 if (done_ccb->ccb_h.ccb_type == CTLFE_CCB_WAITING) { 1090 panic("shouldn't get to the CCB waiting case!"); 1091 wakeup(&done_ccb->ccb_h.cbfcnp); 1092 return; 1093 } 1094 1095 /* 1096 * If the peripheral is invalid, ATIOs and immediate notify CCBs 1097 * need to be freed. Most of the ATIOs and INOTs that come back 1098 * will be CCBs that are being returned from the SIM as a result of 1099 * our disabling the LUN. 1100 * 1101 * Other CCB types are handled in their respective cases below. 1102 */ 1103 if (periph->flags & CAM_PERIPH_INVALID) { 1104 switch (done_ccb->ccb_h.func_code) { 1105 case XPT_ACCEPT_TARGET_IO: 1106 case XPT_IMMEDIATE_NOTIFY: 1107 case XPT_NOTIFY_ACKNOWLEDGE: 1108 ctlfe_free_ccb(periph, done_ccb); 1109 return; 1110 default: 1111 break; 1112 } 1113 1114 } 1115 switch (done_ccb->ccb_h.func_code) { 1116 case XPT_ACCEPT_TARGET_IO: { 1117 union ctl_io *io; 1118 struct ccb_accept_tio *atio; 1119 1120 atio = &done_ccb->atio; 1121 1122 softc->atios_returned++; 1123 1124 /* 1125 * Allocate a ctl_io, pass it to CTL, and wait for the 1126 * datamove or done. 1127 */ 1128 io = ctl_alloc_io(bus_softc->fe.ctl_pool_ref); 1129 if (io == NULL) { 1130 atio->ccb_h.flags &= ~CAM_DIR_MASK; 1131 atio->ccb_h.flags |= CAM_DIR_NONE; 1132 1133 printf("%s: ctl_alloc_io failed!\n", __func__); 1134 1135 /* 1136 * XXX KDM need to set SCSI_STATUS_BUSY, but there 1137 * is no field in the ATIO structure to do that, 1138 * and we aren't able to allocate a ctl_io here. 1139 * What to do? 1140 */ 1141 atio->sense_len = 0; 1142 done_ccb->ccb_h.io_ptr = NULL; 1143 TAILQ_INSERT_TAIL(&softc->work_queue, &atio->ccb_h, 1144 periph_links.tqe); 1145 xpt_schedule(periph, /*priority*/ 1); 1146 break; 1147 } 1148 ctl_zero_io(io); 1149 1150 /* Save pointers on both sides */ 1151 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr = done_ccb; 1152 done_ccb->ccb_h.io_ptr = io; 1153 1154 /* 1155 * Only SCSI I/O comes down this path, resets, etc. come 1156 * down the immediate notify path below. 1157 */ 1158 io->io_hdr.io_type = CTL_IO_SCSI; 1159 io->io_hdr.nexus.initid.id = atio->init_id; 1160 io->io_hdr.nexus.targ_port = bus_softc->fe.targ_port; 1161 io->io_hdr.nexus.targ_target.id = atio->ccb_h.target_id; 1162 io->io_hdr.nexus.targ_lun = atio->ccb_h.target_lun; 1163 io->scsiio.tag_num = atio->tag_id; 1164 switch (atio->tag_action) { 1165 case CAM_TAG_ACTION_NONE: 1166 io->scsiio.tag_type = CTL_TAG_UNTAGGED; 1167 break; 1168 case MSG_SIMPLE_TASK: 1169 io->scsiio.tag_type = CTL_TAG_SIMPLE; 1170 break; 1171 case MSG_HEAD_OF_QUEUE_TASK: 1172 io->scsiio.tag_type = CTL_TAG_HEAD_OF_QUEUE; 1173 break; 1174 case MSG_ORDERED_TASK: 1175 io->scsiio.tag_type = CTL_TAG_ORDERED; 1176 break; 1177 case MSG_ACA_TASK: 1178 io->scsiio.tag_type = CTL_TAG_ACA; 1179 break; 1180 default: 1181 io->scsiio.tag_type = CTL_TAG_UNTAGGED; 1182 printf("%s: unhandled tag type %#x!!\n", __func__, 1183 atio->tag_action); 1184 break; 1185 } 1186 if (atio->cdb_len > sizeof(io->scsiio.cdb)) { 1187 printf("%s: WARNING: CDB len %d > ctl_io space %zd\n", 1188 __func__, atio->cdb_len, sizeof(io->scsiio.cdb)); 1189 } 1190 io->scsiio.cdb_len = min(atio->cdb_len, sizeof(io->scsiio.cdb)); 1191 bcopy(atio->cdb_io.cdb_bytes, io->scsiio.cdb, 1192 io->scsiio.cdb_len); 1193 1194#ifdef CTLFEDEBUG 1195 printf("%s: %ju:%d:%ju:%d: tag %04x CDB %02x\n", __func__, 1196 (uintmax_t)io->io_hdr.nexus.initid.id, 1197 io->io_hdr.nexus.targ_port, 1198 (uintmax_t)io->io_hdr.nexus.targ_target.id, 1199 io->io_hdr.nexus.targ_lun, 1200 io->scsiio.tag_num, io->scsiio.cdb[0]); 1201#endif 1202 1203 ctl_queue(io); 1204 break; 1205 } 1206 case XPT_CONT_TARGET_IO: { 1207 struct ccb_accept_tio *atio; 1208 union ctl_io *io; 1209 1210 atio = (struct ccb_accept_tio *)done_ccb->ccb_h.ccb_atio; 1211 io = (union ctl_io *)atio->ccb_h.io_ptr; 1212 1213 softc->ctios_returned++; 1214#ifdef CTLFEDEBUG 1215 printf("%s: got XPT_CONT_TARGET_IO tag %#x flags %#x\n", 1216 __func__, atio->tag_id, done_ccb->ccb_h.flags); 1217#endif 1218 /* 1219 * If we were sending status back to the initiator, free up 1220 * resources. If we were doing a datamove, call the 1221 * datamove done routine. 1222 */ 1223 if (done_ccb->ccb_h.flags & CAM_SEND_STATUS) { 1224 softc->ccbs_freed++; 1225 xpt_release_ccb(done_ccb); 1226 ctl_free_io(io); 1227 /* 1228 * For a wildcard attachment, commands can come in 1229 * with a specific target/lun. Reset the target 1230 * and LUN fields back to the wildcard values before 1231 * we send them back down to the SIM. The SIM has 1232 * a wildcard LUN enabled, not whatever target/lun 1233 * these happened to be. 1234 */ 1235 if (softc->flags & CTLFE_LUN_WILDCARD) { 1236 atio->ccb_h.target_id = CAM_TARGET_WILDCARD; 1237 atio->ccb_h.target_lun = CAM_LUN_WILDCARD; 1238 } 1239 if (periph->flags & CAM_PERIPH_INVALID) { 1240 ctlfe_free_ccb(periph, (union ccb *)atio); 1241 return; 1242 } else { 1243 xpt_action((union ccb *)atio); 1244 softc->atios_sent++; 1245 } 1246 } else { 1247 struct ctlfe_lun_cmd_info *cmd_info; 1248 struct ccb_scsiio *csio; 1249 1250 csio = &done_ccb->csio; 1251 cmd_info = (struct ctlfe_lun_cmd_info *) 1252 io->io_hdr.port_priv; 1253 1254 io->io_hdr.flags &= ~CTL_FLAG_DMA_INPROG; 1255 1256 io->scsiio.ext_data_len += csio->dxfer_len; 1257 if (io->scsiio.ext_data_len > 1258 io->scsiio.kern_total_len) { 1259 xpt_print(periph->path, "%s: tag 0x%04x " 1260 "done len %u > total %u sent %u\n", 1261 __func__, io->scsiio.tag_num, 1262 io->scsiio.ext_data_len, 1263 io->scsiio.kern_total_len, 1264 io->scsiio.ext_data_filled); 1265 } 1266 /* 1267 * Translate CAM status to CTL status. Success 1268 * does not change the overall, ctl_io status. In 1269 * that case we just set port_status to 0. If we 1270 * have a failure, though, set a data phase error 1271 * for the overall ctl_io. 1272 */ 1273 switch (done_ccb->ccb_h.status & CAM_STATUS_MASK) { 1274 case CAM_REQ_CMP: 1275 io->io_hdr.port_status = 0; 1276 break; 1277 default: 1278 /* 1279 * XXX KDM the isp(4) driver doesn't really 1280 * seem to send errors back for data 1281 * transfers that I can tell. There is one 1282 * case where it'll send CAM_REQ_CMP_ERR, 1283 * but probably not that many more cases. 1284 * So set a generic data phase error here, 1285 * like the SXP driver sets. 1286 */ 1287 io->io_hdr.port_status = 0xbad1; 1288 ctl_set_data_phase_error(&io->scsiio); 1289 /* 1290 * XXX KDM figure out residual. 1291 */ 1292 break; 1293 } 1294 /* 1295 * If we had to break this S/G list into multiple 1296 * pieces, figure out where we are in the list, and 1297 * continue sending pieces if necessary. 1298 */ 1299 if ((cmd_info->flags & CTLFE_CMD_PIECEWISE) 1300 && (io->io_hdr.port_status == 0) 1301 && (cmd_info->cur_transfer_index < 1302 io->scsiio.kern_sg_entries)) { 1303 struct ctl_sg_entry *sglist; 1304 ccb_flags flags; 1305 uint8_t scsi_status; 1306 uint8_t *data_ptr; 1307 uint32_t dxfer_len; 1308 int *ti; 1309 1310 sglist = (struct ctl_sg_entry *) 1311 io->scsiio.kern_data_ptr; 1312 ti = &cmd_info->cur_transfer_index; 1313 flags = atio->ccb_h.flags & 1314 (CAM_DIS_DISCONNECT| 1315 CAM_TAG_ACTION_VALID| 1316 CAM_DIR_MASK); 1317 1318 /* 1319 * Set the direction, relative to the initiator. 1320 */ 1321 flags &= ~CAM_DIR_MASK; 1322 if ((io->io_hdr.flags & CTL_FLAG_DATA_MASK) == 1323 CTL_FLAG_DATA_IN) 1324 flags |= CAM_DIR_IN; 1325 else 1326 flags |= CAM_DIR_OUT; 1327 1328 data_ptr = sglist[*ti].addr; 1329 dxfer_len = sglist[*ti].len; 1330 (*ti)++; 1331 1332 scsi_status = 0; 1333 1334 if (((flags & CAM_SEND_STATUS) == 0) 1335 && (dxfer_len == 0)) { 1336 printf("%s: tag %04x no status or " 1337 "len cdb = %02x\n", __func__, 1338 atio->tag_id, 1339 atio->cdb_io.cdb_bytes[0]); 1340 printf("%s: tag %04x io status %#x\n", 1341 __func__, atio->tag_id, 1342 io->io_hdr.status); 1343 } 1344 1345 cam_fill_ctio(csio, 1346 /*retries*/ 2, 1347 ctlfedone, 1348 flags, 1349 (flags & CAM_TAG_ACTION_VALID) ? 1350 MSG_SIMPLE_Q_TAG : 0, 1351 atio->tag_id, 1352 atio->init_id, 1353 scsi_status, 1354 /*data_ptr*/ data_ptr, 1355 /*dxfer_len*/ dxfer_len, 1356 /*timeout*/ 5 * 1000); 1357 1358 csio->resid = 0; 1359 csio->ccb_h.ccb_atio = atio; 1360 io->io_hdr.flags |= CTL_FLAG_DMA_INPROG; 1361 softc->ctios_sent++; 1362 xpt_action((union ccb *)csio); 1363 } else { 1364 /* 1365 * Release the CTIO. The ATIO will be sent back 1366 * down to the SIM once we send status. 1367 */ 1368 softc->ccbs_freed++; 1369 xpt_release_ccb(done_ccb); 1370 1371 /* Call the backend move done callback */ 1372 io->scsiio.be_move_done(io); 1373 } 1374 } 1375 break; 1376 } 1377 case XPT_IMMEDIATE_NOTIFY: { 1378 union ctl_io *io; 1379 struct ccb_immediate_notify *inot; 1380 cam_status status; 1381 int frozen; 1382 1383 inot = &done_ccb->cin1; 1384 1385 softc->inots_returned++; 1386 1387 frozen = (done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0; 1388 1389 printf("%s: got XPT_IMMEDIATE_NOTIFY status %#x tag %#x " 1390 "seq %#x\n", __func__, inot->ccb_h.status, 1391 inot->tag_id, inot->seq_id); 1392 1393 io = ctl_alloc_io(bus_softc->fe.ctl_pool_ref); 1394 if (io != NULL) { 1395 int send_ctl_io; 1396 1397 send_ctl_io = 1; 1398 1399 ctl_zero_io(io); 1400 io->io_hdr.io_type = CTL_IO_TASK; 1401 io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr =done_ccb; 1402 inot->ccb_h.io_ptr = io; 1403 io->io_hdr.nexus.initid.id = inot->initiator_id; 1404 io->io_hdr.nexus.targ_port = bus_softc->fe.targ_port; 1405 io->io_hdr.nexus.targ_target.id = inot->ccb_h.target_id; 1406 io->io_hdr.nexus.targ_lun = inot->ccb_h.target_lun; 1407 /* XXX KDM should this be the tag_id? */ 1408 io->taskio.tag_num = inot->seq_id; 1409 1410 status = inot->ccb_h.status & CAM_STATUS_MASK; 1411 switch (status) { 1412 case CAM_SCSI_BUS_RESET: 1413 io->taskio.task_action = CTL_TASK_BUS_RESET; 1414 break; 1415 case CAM_BDR_SENT: 1416 io->taskio.task_action = CTL_TASK_TARGET_RESET; 1417 break; 1418 case CAM_MESSAGE_RECV: 1419 switch (inot->arg) { 1420 case MSG_ABORT_TASK_SET: 1421 /* 1422 * XXX KDM this isn't currently 1423 * supported by CTL. It ends up 1424 * being a no-op. 1425 */ 1426 io->taskio.task_action = 1427 CTL_TASK_ABORT_TASK_SET; 1428 break; 1429 case MSG_TARGET_RESET: 1430 io->taskio.task_action = 1431 CTL_TASK_TARGET_RESET; 1432 break; 1433 case MSG_ABORT_TASK: 1434 io->taskio.task_action = 1435 CTL_TASK_ABORT_TASK; 1436 break; 1437 case MSG_LOGICAL_UNIT_RESET: 1438 io->taskio.task_action = 1439 CTL_TASK_LUN_RESET; 1440 break; 1441 case MSG_CLEAR_TASK_SET: 1442 /* 1443 * XXX KDM this isn't currently 1444 * supported by CTL. It ends up 1445 * being a no-op. 1446 */ 1447 io->taskio.task_action = 1448 CTL_TASK_CLEAR_TASK_SET; 1449 break; 1450 case MSG_CLEAR_ACA: 1451 io->taskio.task_action = 1452 CTL_TASK_CLEAR_ACA; 1453 break; 1454 case MSG_NOOP: 1455 send_ctl_io = 0; 1456 break; 1457 default: 1458 xpt_print(periph->path, "%s: " 1459 "unsupported message 0x%x\n", 1460 __func__, inot->arg); 1461 send_ctl_io = 0; 1462 break; 1463 } 1464 break; 1465 case CAM_REQ_ABORTED: 1466 /* 1467 * This request was sent back by the driver. 1468 * XXX KDM what do we do here? 1469 */ 1470 send_ctl_io = 0; 1471 break; 1472 case CAM_REQ_INVALID: 1473 case CAM_PROVIDE_FAIL: 1474 default: 1475 /* 1476 * We should only get here if we're talking 1477 * to a talking to a SIM that is target 1478 * capable but supports the old API. In 1479 * that case, we need to just free the CCB. 1480 * If we actually send a notify acknowledge, 1481 * it will send that back with an error as 1482 * well. 1483 */ 1484 1485 if ((status != CAM_REQ_INVALID) 1486 && (status != CAM_PROVIDE_FAIL)) 1487 xpt_print(periph->path, "%s: " 1488 "unsupported CAM status " 1489 "0x%x\n", __func__, status); 1490 1491 ctl_free_io(io); 1492 ctlfe_free_ccb(periph, done_ccb); 1493 1494 return; 1495 } 1496 if (send_ctl_io != 0) { 1497 ctl_queue(io); 1498 } else { 1499 ctl_free_io(io); 1500 done_ccb->ccb_h.status = CAM_REQ_INPROG; 1501 done_ccb->ccb_h.func_code = 1502 XPT_NOTIFY_ACKNOWLEDGE; 1503 xpt_action(done_ccb); 1504 } 1505 } else { 1506 xpt_print(periph->path, "%s: could not allocate " 1507 "ctl_io for immediate notify!\n", __func__); 1508 /* requeue this to the adapter */ 1509 done_ccb->ccb_h.status = CAM_REQ_INPROG; 1510 done_ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE; 1511 xpt_action(done_ccb); 1512 } 1513 1514 if (frozen != 0) { 1515 cam_release_devq(periph->path, 1516 /*relsim_flags*/ 0, 1517 /*opening reduction*/ 0, 1518 /*timeout*/ 0, 1519 /*getcount_only*/ 0); 1520 } 1521 break; 1522 } 1523 case XPT_NOTIFY_ACKNOWLEDGE: 1524 /* 1525 * Queue this back down to the SIM as an immediate notify. 1526 */ 1527 done_ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; 1528 xpt_action(done_ccb); 1529 softc->inots_sent++; 1530 break; 1531 case XPT_ABORT: 1532 /* 1533 * XPT_ABORT is an immediate CCB, we shouldn't get here. 1534 */ 1535 panic("%s: XPT_ABORT CCB returned!", __func__); 1536 break; 1537 case XPT_SET_SIM_KNOB: 1538 case XPT_GET_SIM_KNOB: 1539 break; 1540 default: 1541 panic("%s: unexpected CCB type %#x", __func__, 1542 done_ccb->ccb_h.func_code); 1543 break; 1544 } 1545} 1546 1547static void 1548ctlfe_onoffline(void *arg, int online) 1549{ 1550 struct ctlfe_softc *bus_softc; 1551 union ccb *ccb; 1552 cam_status status; 1553 struct cam_path *path; 1554 struct cam_sim *sim; 1555 int set_wwnn; 1556 1557 bus_softc = (struct ctlfe_softc *)arg; 1558 1559 set_wwnn = 0; 1560 1561 status = xpt_create_path(&path, /*periph*/ NULL, bus_softc->path_id, 1562 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 1563 if (status != CAM_REQ_CMP) { 1564 printf("%s: unable to create path!\n", __func__); 1565 return; 1566 } 1567 ccb = (union ccb *)malloc(sizeof(*ccb), M_TEMP, M_WAITOK | M_ZERO); 1568 if (ccb == NULL) { 1569 printf("%s: unable to malloc CCB!\n", __func__); 1570 xpt_free_path(path); 1571 return; 1572 } 1573 xpt_setup_ccb(&ccb->ccb_h, path, /*priority*/ 1); 1574 1575 sim = xpt_path_sim(path); 1576 1577 /* 1578 * Copan WWN format: 1579 * 1580 * Bits 63-60: 0x5 NAA, IEEE registered name 1581 * Bits 59-36: 0x000ED5 IEEE Company name assigned to Copan 1582 * Bits 35-12: Copan SSN (Sequential Serial Number) 1583 * Bits 11-8: Type of port: 1584 * 1 == N-Port 1585 * 2 == F-Port 1586 * 3 == NL-Port 1587 * Bits 7-0: 0 == Node Name, >0 == Port Number 1588 */ 1589 1590 if (online != 0) { 1591 1592 ccb->ccb_h.func_code = XPT_GET_SIM_KNOB; 1593 1594 CAM_SIM_LOCK(sim); 1595 1596 xpt_action(ccb); 1597 1598 CAM_SIM_UNLOCK(sim); 1599 1600 if ((ccb->knob.xport_specific.valid & KNOB_VALID_ADDRESS) != 0){ 1601#ifdef RANDOM_WWNN 1602 uint64_t random_bits; 1603#endif 1604 1605 printf("%s: %s current WWNN %#jx\n", __func__, 1606 bus_softc->port_name, 1607 ccb->knob.xport_specific.fc.wwnn); 1608 printf("%s: %s current WWPN %#jx\n", __func__, 1609 bus_softc->port_name, 1610 ccb->knob.xport_specific.fc.wwpn); 1611 1612#ifdef RANDOM_WWNN 1613 arc4rand(&random_bits, sizeof(random_bits), 0); 1614#endif 1615 1616 /* 1617 * XXX KDM this is a bit of a kludge for now. We 1618 * take the current WWNN/WWPN from the card, and 1619 * replace the company identifier and the NL-Port 1620 * indicator and the port number (for the WWPN). 1621 * This should be replaced later with ddb_GetWWNN, 1622 * or possibly a more centralized scheme. (It 1623 * would be nice to have the WWNN/WWPN for each 1624 * port stored in the ctl_frontend structure.) 1625 */ 1626#ifdef RANDOM_WWNN 1627 ccb->knob.xport_specific.fc.wwnn = 1628 (random_bits & 1629 0x0000000fffffff00ULL) | 1630 /* Company ID */ 0x5000ED5000000000ULL | 1631 /* NL-Port */ 0x0300; 1632 ccb->knob.xport_specific.fc.wwpn = 1633 (random_bits & 1634 0x0000000fffffff00ULL) | 1635 /* Company ID */ 0x5000ED5000000000ULL | 1636 /* NL-Port */ 0x3000 | 1637 /* Port Num */ (bus_softc->fe.targ_port & 0xff); 1638 1639 /* 1640 * This is a bit of an API break/reversal, but if 1641 * we're doing the random WWNN that's a little 1642 * different anyway. So record what we're actually 1643 * using with the frontend code so it's reported 1644 * accurately. 1645 */ 1646 bus_softc->fe.wwnn = 1647 ccb->knob.xport_specific.fc.wwnn; 1648 bus_softc->fe.wwpn = 1649 ccb->knob.xport_specific.fc.wwpn; 1650 set_wwnn = 1; 1651#else /* RANDOM_WWNN */ 1652 /* 1653 * If the user has specified a WWNN/WWPN, send them 1654 * down to the SIM. Otherwise, record what the SIM 1655 * has reported. 1656 */ 1657 if ((bus_softc->fe.wwnn != 0) 1658 && (bus_softc->fe.wwpn != 0)) { 1659 ccb->knob.xport_specific.fc.wwnn = 1660 bus_softc->fe.wwnn; 1661 ccb->knob.xport_specific.fc.wwpn = 1662 bus_softc->fe.wwpn; 1663 set_wwnn = 1; 1664 } else { 1665 bus_softc->fe.wwnn = 1666 ccb->knob.xport_specific.fc.wwnn; 1667 bus_softc->fe.wwpn = 1668 ccb->knob.xport_specific.fc.wwpn; 1669 } 1670#endif /* RANDOM_WWNN */ 1671 1672 1673 if (set_wwnn != 0) { 1674 printf("%s: %s new WWNN %#jx\n", __func__, 1675 bus_softc->port_name, 1676 ccb->knob.xport_specific.fc.wwnn); 1677 printf("%s: %s new WWPN %#jx\n", __func__, 1678 bus_softc->port_name, 1679 ccb->knob.xport_specific.fc.wwpn); 1680 } 1681 } else { 1682 printf("%s: %s has no valid WWNN/WWPN\n", __func__, 1683 bus_softc->port_name); 1684 } 1685 } 1686 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; 1687 ccb->knob.xport_specific.valid = KNOB_VALID_ROLE; 1688 if (set_wwnn != 0) 1689 ccb->knob.xport_specific.valid |= KNOB_VALID_ADDRESS; 1690 1691 if (online != 0) 1692 ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET; 1693 else 1694 ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE; 1695 1696 1697 CAM_SIM_LOCK(sim); 1698 1699 xpt_action(ccb); 1700 1701 CAM_SIM_UNLOCK(sim); 1702 1703 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1704 printf("%s: SIM %s (path id %d) target %s failed with " 1705 "status %#x\n", 1706 __func__, bus_softc->port_name, bus_softc->path_id, 1707 (online != 0) ? "enable" : "disable", 1708 ccb->ccb_h.status); 1709 } else { 1710 printf("%s: SIM %s (path id %d) target %s succeeded\n", 1711 __func__, bus_softc->port_name, bus_softc->path_id, 1712 (online != 0) ? "enable" : "disable"); 1713 } 1714 1715 free(ccb, M_TEMP); 1716 xpt_free_path(path); 1717 1718 return; 1719} 1720 1721static void 1722ctlfe_online(void *arg) 1723{ 1724 ctlfe_onoffline(arg, /*online*/ 1); 1725} 1726 1727static void 1728ctlfe_offline(void *arg) 1729{ 1730 ctlfe_onoffline(arg, /*online*/ 0); 1731} 1732 1733static int 1734ctlfe_targ_enable(void *arg, struct ctl_id targ_id) 1735{ 1736 return (0); 1737} 1738 1739static int 1740ctlfe_targ_disable(void *arg, struct ctl_id targ_id) 1741{ 1742 return (0); 1743} 1744 1745/* 1746 * This will get called to enable a LUN on every bus that is attached to 1747 * CTL. So we only need to create a path/periph for this particular bus. 1748 */ 1749static int 1750ctlfe_lun_enable(void *arg, struct ctl_id targ_id, int lun_id) 1751{ 1752 struct ctlfe_softc *bus_softc; 1753 struct ctlfe_lun_softc *softc; 1754 struct cam_path *path; 1755 struct cam_periph *periph; 1756 struct cam_sim *sim; 1757 cam_status status; 1758 1759 1760 bus_softc = (struct ctlfe_softc *)arg; 1761 1762 status = xpt_create_path_unlocked(&path, /*periph*/ NULL, 1763 bus_softc->path_id, 1764 targ_id.id, 1765 lun_id); 1766 /* XXX KDM need some way to return status to CTL here? */ 1767 if (status != CAM_REQ_CMP) { 1768 printf("%s: could not create path, status %#x\n", __func__, 1769 status); 1770 return (1); 1771 } 1772 1773 softc = malloc(sizeof(*softc), M_CTLFE, M_WAITOK | M_ZERO); 1774 if (softc == NULL) { 1775 printf("%s: could not allocate %zd bytes for softc\n", 1776 __func__, sizeof(*softc)); 1777 xpt_free_path(path); 1778 return (1); 1779 } 1780 sim = xpt_path_sim(path); 1781 mtx_lock(sim->mtx); 1782 periph = cam_periph_find(path, "ctl"); 1783 if (periph != NULL) { 1784 /* We've already got a periph, no need to alloc a new one. */ 1785 xpt_free_path(path); 1786 free(softc, M_CTLFE); 1787 mtx_unlock(sim->mtx); 1788 return (0); 1789 } 1790 1791 softc->parent_softc = bus_softc; 1792 STAILQ_INSERT_TAIL(&bus_softc->lun_softc_list, softc, links); 1793 1794 status = cam_periph_alloc(ctlferegister, 1795 ctlfeoninvalidate, 1796 ctlfecleanup, 1797 ctlfestart, 1798 "ctl", 1799 CAM_PERIPH_BIO, 1800 path, 1801 ctlfeasync, 1802 0, 1803 softc); 1804 1805 mtx_unlock(sim->mtx); 1806 1807 xpt_free_path(path); 1808 1809 return (0); 1810} 1811 1812/* 1813 * XXX KDM we disable LUN removal here. The problem is that the isp(4) 1814 * driver doesn't currently handle LUN removal properly. We need to keep 1815 * enough state here at the peripheral level even after LUNs have been 1816 * removed inside CTL. 1817 * 1818 * Once the isp(4) driver is fixed, this can be re-enabled. 1819 */ 1820static int 1821ctlfe_lun_disable(void *arg, struct ctl_id targ_id, int lun_id) 1822{ 1823#ifdef NOTYET 1824 struct ctlfe_softc *softc; 1825 struct ctlfe_lun_softc *lun_softc; 1826 1827 softc = (struct ctlfe_softc *)arg; 1828 1829 mtx_lock(softc->sim->mtx); 1830 STAILQ_FOREACH(lun_softc, &softc->lun_softc_list, links) { 1831 struct cam_path *path; 1832 1833 path = lun_softc->periph->path; 1834 1835 if ((xpt_path_target_id(path) == targ_id.id) 1836 && (xpt_path_lun_id(path) == lun_id)) { 1837 break; 1838 } 1839 } 1840 if (lun_softc == NULL) { 1841 mtx_unlock(softc->sim->mtx); 1842 printf("%s: can't find target %d lun %d\n", __func__, 1843 targ_id.id, lun_id); 1844 return (1); 1845 } 1846 1847 cam_periph_invalidate(lun_softc->periph); 1848 1849 mtx_unlock(softc->sim->mtx); 1850#endif 1851 1852 return (0); 1853} 1854 1855static void 1856ctlfe_dump_sim(struct cam_sim *sim) 1857{ 1858 int i; 1859 1860 printf("%s%d: max tagged openings: %d, max dev openings: %d\n", 1861 sim->sim_name, sim->unit_number, 1862 sim->max_tagged_dev_openings, sim->max_dev_openings); 1863 printf("%s%d: max_ccbs: %u, ccb_count: %u\n", 1864 sim->sim_name, sim->unit_number, 1865 sim->max_ccbs, sim->ccb_count); 1866 printf("%s%d: ccb_freeq is %sempty\n", 1867 sim->sim_name, sim->unit_number, 1868 (SLIST_FIRST(&sim->ccb_freeq) == NULL) ? "" : "NOT "); 1869 printf("%s%d: alloc_queue.entries %d, alloc_openings %d\n", 1870 sim->sim_name, sim->unit_number, 1871 sim->devq->alloc_queue.entries, sim->devq->alloc_openings); 1872 printf("%s%d: qfrozen_cnt:", sim->sim_name, sim->unit_number); 1873 for (i = 0; i < CAM_RL_VALUES; i++) { 1874 printf("%s%u", (i != 0) ? ":" : "", 1875 sim->devq->alloc_queue.qfrozen_cnt[i]); 1876 } 1877 printf("\n"); 1878} 1879 1880/* 1881 * Assumes that the SIM lock is held. 1882 */ 1883static void 1884ctlfe_dump_queue(struct ctlfe_lun_softc *softc) 1885{ 1886 struct ccb_hdr *hdr; 1887 struct cam_periph *periph; 1888 int num_items; 1889 1890 periph = softc->periph; 1891 num_items = 0; 1892 1893 TAILQ_FOREACH(hdr, &softc->work_queue, periph_links.tqe) { 1894 union ctl_io *io; 1895 1896 io = hdr->io_ptr; 1897 1898 num_items++; 1899 1900 /* 1901 * This can happen when we get an ATIO but can't allocate 1902 * a ctl_io. See the XPT_ACCEPT_TARGET_IO case in ctlfedone(). 1903 */ 1904 if (io == NULL) { 1905 struct ccb_scsiio *csio; 1906 1907 csio = (struct ccb_scsiio *)hdr; 1908 1909 xpt_print(periph->path, "CCB %#x ctl_io allocation " 1910 "failed\n", csio->tag_id); 1911 continue; 1912 } 1913 1914 /* 1915 * Only regular SCSI I/O is put on the work 1916 * queue, so we can print sense here. There may be no 1917 * sense if it's no the queue for a DMA, but this serves to 1918 * print out the CCB as well. 1919 * 1920 * XXX KDM switch this over to scsi_sense_print() when 1921 * CTL is merged in with CAM. 1922 */ 1923 ctl_io_error_print(io, NULL); 1924 1925 /* 1926 * We're sending status back to the 1927 * initiator, so we're on the queue waiting 1928 * for a CTIO to do that. 1929 */ 1930 if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) 1931 continue; 1932 1933 /* 1934 * Otherwise, we're on the queue waiting to 1935 * do a data transfer. 1936 */ 1937 xpt_print(periph->path, "Total %u, Current %u, Resid %u\n", 1938 io->scsiio.kern_total_len, io->scsiio.kern_data_len, 1939 io->scsiio.kern_data_resid); 1940 } 1941 1942 xpt_print(periph->path, "%d requests total waiting for CCBs\n", 1943 num_items); 1944 xpt_print(periph->path, "%ju CCBs oustanding (%ju allocated, %ju " 1945 "freed)\n", (uintmax_t)(softc->ccbs_alloced - 1946 softc->ccbs_freed), (uintmax_t)softc->ccbs_alloced, 1947 (uintmax_t)softc->ccbs_freed); 1948 xpt_print(periph->path, "%ju CTIOs outstanding (%ju sent, %ju " 1949 "returned\n", (uintmax_t)(softc->ctios_sent - 1950 softc->ctios_returned), softc->ctios_sent, 1951 softc->ctios_returned); 1952} 1953 1954/* 1955 * This function is called when we fail to get a CCB for a DMA or status return 1956 * to the initiator within the specified time period. 1957 * 1958 * The callout code should insure that we hold the sim mutex here. 1959 */ 1960static void 1961ctlfe_dma_timeout(void *arg) 1962{ 1963 struct ctlfe_lun_softc *softc; 1964 struct cam_periph *periph; 1965 struct cam_sim *sim; 1966 int num_queued; 1967 1968 softc = (struct ctlfe_lun_softc *)arg; 1969 periph = softc->periph; 1970 sim = xpt_path_sim(periph->path); 1971 num_queued = 0; 1972 1973 /* 1974 * Nothing to do... 1975 */ 1976 if (TAILQ_FIRST(&softc->work_queue) == NULL) { 1977 xpt_print(periph->path, "TIMEOUT triggered after %d " 1978 "seconds, but nothing on work queue??\n", 1979 CTLFE_DMA_TIMEOUT); 1980 return; 1981 } 1982 1983 xpt_print(periph->path, "TIMEOUT (%d seconds) waiting for DMA to " 1984 "start\n", CTLFE_DMA_TIMEOUT); 1985 1986 ctlfe_dump_queue(softc); 1987 1988 ctlfe_dump_sim(sim); 1989 1990 xpt_print(periph->path, "calling xpt_schedule() to attempt to " 1991 "unstick our queue\n"); 1992 1993 xpt_schedule(periph, /*priority*/ 1); 1994 1995 xpt_print(periph->path, "xpt_schedule() call complete\n"); 1996} 1997 1998/* 1999 * Datamove/done routine called by CTL. Put ourselves on the queue to 2000 * receive a CCB from CAM so we can queue the continue I/O request down 2001 * to the adapter. 2002 */ 2003static void 2004ctlfe_datamove_done(union ctl_io *io) 2005{ 2006 union ccb *ccb; 2007 struct cam_sim *sim; 2008 struct cam_periph *periph; 2009 struct ctlfe_lun_softc *softc; 2010 2011 ccb = io->io_hdr.ctl_private[CTL_PRIV_FRONTEND].ptr; 2012 2013 sim = xpt_path_sim(ccb->ccb_h.path); 2014 2015 mtx_lock(sim->mtx); 2016 2017 periph = xpt_path_periph(ccb->ccb_h.path); 2018 2019 softc = (struct ctlfe_lun_softc *)periph->softc; 2020 2021 if (io->io_hdr.io_type == CTL_IO_TASK) { 2022 /* 2023 * Task management commands don't require any further 2024 * communication back to the adapter. Requeue the CCB 2025 * to the adapter, and free the CTL I/O. 2026 */ 2027 xpt_print(ccb->ccb_h.path, "%s: returning task I/O " 2028 "tag %#x seq %#x\n", __func__, 2029 ccb->cin1.tag_id, ccb->cin1.seq_id); 2030 /* 2031 * Send the notify acknowledge down to the SIM, to let it 2032 * know we processed the task management command. 2033 */ 2034 ccb->ccb_h.status = CAM_REQ_INPROG; 2035 ccb->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE; 2036 xpt_action(ccb); 2037 ctl_free_io(io); 2038 } else { 2039 if ((io->io_hdr.status & CTL_STATUS_MASK) != CTL_STATUS_NONE) 2040 io->io_hdr.flags |= CTL_FLAG_STATUS_QUEUED; 2041 else 2042 io->io_hdr.flags |= CTL_FLAG_DMA_QUEUED; 2043 2044 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h, 2045 periph_links.tqe); 2046 2047 /* 2048 * Reset the timeout for our latest active DMA. 2049 */ 2050 callout_reset(&softc->dma_callout, 2051 CTLFE_DMA_TIMEOUT * hz, 2052 ctlfe_dma_timeout, softc); 2053 /* 2054 * Ask for the CAM transport layer to send us a CCB to do 2055 * the DMA or send status, unless ctlfe_dma_enabled is set 2056 * to 0. 2057 */ 2058 if (ctlfe_dma_enabled != 0) 2059 xpt_schedule(periph, /*priority*/ 1); 2060 } 2061 2062 mtx_unlock(sim->mtx); 2063} 2064 2065static void 2066ctlfe_dump(void) 2067{ 2068 struct ctlfe_softc *bus_softc; 2069 2070 STAILQ_FOREACH(bus_softc, &ctlfe_softc_list, links) { 2071 struct ctlfe_lun_softc *lun_softc; 2072 2073 ctlfe_dump_sim(bus_softc->sim); 2074 2075 STAILQ_FOREACH(lun_softc, &bus_softc->lun_softc_list, links) { 2076 ctlfe_dump_queue(lun_softc); 2077 } 2078 } 2079} 2080