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