1 /*- 2 * Copyright (c) 1997-2009 by Matthew Jacob 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 immediately at the beginning of the file, without modification, 10 * this list of conditions, and the following disclaimer. 11 * 2. The name of the author may not be used to endorse or promote products 12 * derived from this software without specific prior written permission. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 18 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 /* 28 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. 29 */ 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <dev/isp/isp_freebsd.h> 34 #include <sys/unistd.h> 35 #include <sys/kthread.h> 36 #include <sys/conf.h> 37 #include <sys/module.h> 38 #include <sys/ioccom.h> 39 #include <dev/isp/isp_ioctl.h> 40 #include <sys/devicestat.h> 41 #include <cam/cam_periph.h> 42 #include <cam/cam_xpt_periph.h> 43 44 #if __FreeBSD_version < 800002 45 #define THREAD_CREATE kthread_create 46 #else 47 #define THREAD_CREATE kproc_create 48 #endif 49 50 MODULE_VERSION(isp, 1); 51 MODULE_DEPEND(isp, cam, 1, 1, 1); 52 int isp_announced = 0; 53 int isp_fabric_hysteresis = 5; 54 int isp_loop_down_limit = 60; /* default loop down limit */ 55 int isp_change_is_bad = 0; /* "changed" devices are bad */ 56 int isp_quickboot_time = 7; /* don't wait more than N secs for loop up */ 57 int isp_gone_device_time = 30; /* grace time before reporting device lost */ 58 int isp_autoconfig = 1; /* automatically attach/detach devices */ 59 static const char prom3[] = "Chan %d PortID 0x%06x Departed from Target %u because of %s"; 60 61 static void isp_freeze_loopdown(ispsoftc_t *, int, char *); 62 static d_ioctl_t ispioctl; 63 static void isp_intr_enable(void *); 64 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *); 65 static void isp_poll(struct cam_sim *); 66 static timeout_t isp_watchdog; 67 static timeout_t isp_gdt; 68 static task_fn_t isp_gdt_task; 69 static timeout_t isp_ldt; 70 static task_fn_t isp_ldt_task; 71 static void isp_kthread(void *); 72 static void isp_action(struct cam_sim *, union ccb *); 73 #ifdef ISP_INTERNAL_TARGET 74 static void isp_target_thread_pi(void *); 75 static void isp_target_thread_fc(void *); 76 #endif 77 static int isp_timer_count; 78 static void isp_timer(void *); 79 80 static struct cdevsw isp_cdevsw = { 81 .d_version = D_VERSION, 82 .d_ioctl = ispioctl, 83 .d_name = "isp", 84 }; 85 86 static int 87 isp_role_sysctl(SYSCTL_HANDLER_ARGS) 88 { 89 ispsoftc_t *isp = (ispsoftc_t *)arg1; 90 int chan = arg2; 91 int error, old, value; 92 93 value = FCPARAM(isp, chan)->role; 94 95 error = sysctl_handle_int(oidp, &value, 0, req); 96 if ((error != 0) || (req->newptr == NULL)) 97 return (error); 98 99 if (value < ISP_ROLE_NONE || value > ISP_ROLE_BOTH) 100 return (EINVAL); 101 102 ISP_LOCK(isp); 103 old = FCPARAM(isp, chan)->role; 104 105 /* If nothing has changed -- we are done. */ 106 if (value == old) { 107 ISP_UNLOCK(isp); 108 return (0); 109 } 110 111 /* We don't allow target mode switch from here. */ 112 if ((value ^ old) & ISP_ROLE_TARGET) { 113 ISP_UNLOCK(isp); 114 return (EPERM); 115 } 116 117 /* Actually change the role. */ 118 error = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, value); 119 ISP_UNLOCK(isp); 120 return (error); 121 } 122 123 static int 124 isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) 125 { 126 struct ccb_setasync csa; 127 struct cam_sim *sim; 128 struct cam_path *path; 129 130 /* 131 * Construct our SIM entry. 132 */ 133 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, device_get_unit(isp->isp_dev), &isp->isp_osinfo.lock, isp->isp_maxcmds, isp->isp_maxcmds, devq); 134 135 if (sim == NULL) { 136 return (ENOMEM); 137 } 138 139 ISP_LOCK(isp); 140 if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) { 141 ISP_UNLOCK(isp); 142 cam_sim_free(sim, FALSE); 143 return (EIO); 144 } 145 ISP_UNLOCK(isp); 146 if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 147 ISP_LOCK(isp); 148 xpt_bus_deregister(cam_sim_path(sim)); 149 ISP_UNLOCK(isp); 150 cam_sim_free(sim, FALSE); 151 return (ENXIO); 152 } 153 xpt_setup_ccb(&csa.ccb_h, path, 5); 154 csa.ccb_h.func_code = XPT_SASYNC_CB; 155 csa.event_enable = AC_LOST_DEVICE; 156 csa.callback = isp_cam_async; 157 csa.callback_arg = sim; 158 159 ISP_LOCK(isp); 160 xpt_action((union ccb *)&csa); 161 ISP_UNLOCK(isp); 162 163 if (IS_SCSI(isp)) { 164 struct isp_spi *spi = ISP_SPI_PC(isp, chan); 165 spi->sim = sim; 166 spi->path = path; 167 #ifdef ISP_INTERNAL_TARGET 168 ISP_SET_PC(isp, chan, proc_active, 1); 169 if (THREAD_CREATE(isp_target_thread_pi, spi, &spi->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { 170 ISP_SET_PC(isp, chan, proc_active, 0); 171 isp_prt(isp, ISP_LOGERR, "cannot create test target thread"); 172 } 173 ISP_SPI_PC(isp, chan)->num_threads += 1; 174 #endif 175 } else { 176 fcparam *fcp = FCPARAM(isp, chan); 177 struct isp_fc *fc = ISP_FC_PC(isp, chan); 178 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev); 179 struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev); 180 char name[16]; 181 182 ISP_LOCK(isp); 183 fc->sim = sim; 184 fc->path = path; 185 fc->isp = isp; 186 fc->ready = 1; 187 188 callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0); 189 callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0); 190 TASK_INIT(&fc->ltask, 1, isp_ldt_task, fc); 191 TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc); 192 193 /* 194 * We start by being "loop down" if we have an initiator role 195 */ 196 if (fcp->role & ISP_ROLE_INITIATOR) { 197 isp_freeze_loopdown(isp, chan, "isp_attach"); 198 callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc); 199 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime); 200 } 201 ISP_UNLOCK(isp); 202 if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { 203 xpt_free_path(fc->path); 204 ISP_LOCK(isp); 205 if (callout_active(&fc->ldt)) 206 callout_stop(&fc->ldt); 207 xpt_bus_deregister(cam_sim_path(fc->sim)); 208 ISP_UNLOCK(isp); 209 cam_sim_free(fc->sim, FALSE); 210 return (ENOMEM); 211 } 212 ISP_FC_PC(isp, chan)->num_threads += 1; 213 #ifdef ISP_INTERNAL_TARGET 214 ISP_SET_PC(isp, chan, proc_active, 1); 215 if (THREAD_CREATE(isp_target_thread_fc, fc, &fc->target_proc, 0, 0, "%s: isp_test_tgt%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { 216 ISP_SET_PC(isp, chan, proc_active, 0); 217 isp_prt(isp, ISP_LOGERR, "cannot create test target thread"); 218 } 219 ISP_FC_PC(isp, chan)->num_threads += 1; 220 #endif 221 if (chan > 0) { 222 snprintf(name, sizeof(name), "chan%d", chan); 223 tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), 224 OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel"); 225 } 226 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwnn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwnn, "World Wide Node Name"); 227 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "wwpn", CTLFLAG_RD, &FCPARAM(isp, chan)->isp_wwpn, "World Wide Port Name"); 228 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "loop_down_limit", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->loop_down_limit, 0, "Loop Down Limit"); 229 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "gone_device_time", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->gone_device_time, 0, "Gone Device Time"); 230 #if defined(ISP_TARGET_MODE) && defined(DEBUG) 231 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "inject_lost_data_frame", CTLFLAG_RW, &ISP_FC_PC(isp, chan)->inject_lost_data_frame, 0, "Cause a Lost Frame on a Read"); 232 #endif 233 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 234 "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan, 235 isp_role_sysctl, "I", "Current role"); 236 } 237 return (0); 238 } 239 240 static void 241 isp_detach_internal_target(ispsoftc_t *isp, int chan) 242 { 243 #ifdef ISP_INTERNAL_TARGET 244 void *wchan; 245 246 ISP_GET_PC(isp, chan, target_proc, wchan); 247 ISP_SET_PC(isp, chan, proc_active, 0); 248 wakeup(wchan); 249 #endif 250 } 251 252 static void 253 isp_detach_chan(ispsoftc_t *isp, int chan) 254 { 255 struct cam_sim *sim; 256 struct cam_path *path; 257 struct ccb_setasync csa; 258 int *num_threads; 259 260 ISP_GET_PC(isp, chan, sim, sim); 261 ISP_GET_PC(isp, chan, path, path); 262 ISP_GET_PC_ADDR(isp, chan, num_threads, num_threads); 263 264 xpt_setup_ccb(&csa.ccb_h, path, 5); 265 csa.ccb_h.func_code = XPT_SASYNC_CB; 266 csa.event_enable = 0; 267 csa.callback = isp_cam_async; 268 csa.callback_arg = sim; 269 xpt_action((union ccb *)&csa); 270 xpt_free_path(path); 271 xpt_bus_deregister(cam_sim_path(sim)); 272 cam_sim_free(sim, FALSE); 273 274 /* Wait for the channel's spawned threads to exit. */ 275 wakeup(isp->isp_osinfo.pc.ptr); 276 isp_detach_internal_target(isp, chan); 277 while (*num_threads != 0) 278 mtx_sleep(isp, &isp->isp_osinfo.lock, PRIBIO, "isp_reap", 100); 279 } 280 281 int 282 isp_attach(ispsoftc_t *isp) 283 { 284 const char *nu = device_get_nameunit(isp->isp_osinfo.dev); 285 int du = device_get_unit(isp->isp_dev); 286 int chan; 287 288 isp->isp_osinfo.ehook.ich_func = isp_intr_enable; 289 isp->isp_osinfo.ehook.ich_arg = isp; 290 /* 291 * Haha. Set this first, because if we're loaded as a module isp_intr_enable 292 * will be called right awawy, which will clear isp_osinfo.ehook_active, 293 * which would be unwise to then set again later. 294 */ 295 isp->isp_osinfo.ehook_active = 1; 296 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) { 297 isp_prt(isp, ISP_LOGERR, "could not establish interrupt enable hook"); 298 return (-EIO); 299 } 300 301 /* 302 * Create the device queue for our SIM(s). 303 */ 304 isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds); 305 if (isp->isp_osinfo.devq == NULL) { 306 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 307 return (EIO); 308 } 309 310 for (chan = 0; chan < isp->isp_nchan; chan++) { 311 if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) { 312 goto unwind; 313 } 314 } 315 316 callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_osinfo.lock, 0); 317 isp_timer_count = hz >> 2; 318 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp); 319 isp->isp_osinfo.timer_active = 1; 320 321 isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu); 322 if (isp->isp_osinfo.cdev) { 323 isp->isp_osinfo.cdev->si_drv1 = isp; 324 } 325 return (0); 326 327 unwind: 328 while (--chan >= 0) { 329 struct cam_sim *sim; 330 struct cam_path *path; 331 332 ISP_GET_PC(isp, chan, sim, sim); 333 ISP_GET_PC(isp, chan, path, path); 334 xpt_free_path(path); 335 ISP_LOCK(isp); 336 xpt_bus_deregister(cam_sim_path(sim)); 337 ISP_UNLOCK(isp); 338 cam_sim_free(sim, FALSE); 339 } 340 if (isp->isp_osinfo.ehook_active) { 341 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 342 isp->isp_osinfo.ehook_active = 0; 343 } 344 if (isp->isp_osinfo.cdev) { 345 destroy_dev(isp->isp_osinfo.cdev); 346 isp->isp_osinfo.cdev = NULL; 347 } 348 cam_simq_free(isp->isp_osinfo.devq); 349 isp->isp_osinfo.devq = NULL; 350 return (-1); 351 } 352 353 int 354 isp_detach(ispsoftc_t *isp) 355 { 356 struct cam_sim *sim; 357 int chan; 358 359 ISP_LOCK(isp); 360 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) { 361 ISP_GET_PC(isp, chan, sim, sim); 362 if (sim->refcount > 2) { 363 ISP_UNLOCK(isp); 364 return (EBUSY); 365 } 366 } 367 /* Tell spawned threads that we're exiting. */ 368 isp->isp_osinfo.is_exiting = 1; 369 if (isp->isp_osinfo.timer_active) { 370 callout_stop(&isp->isp_osinfo.tmo); 371 isp->isp_osinfo.timer_active = 0; 372 } 373 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) 374 isp_detach_chan(isp, chan); 375 ISP_UNLOCK(isp); 376 377 if (isp->isp_osinfo.cdev) { 378 destroy_dev(isp->isp_osinfo.cdev); 379 isp->isp_osinfo.cdev = NULL; 380 } 381 if (isp->isp_osinfo.ehook_active) { 382 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 383 isp->isp_osinfo.ehook_active = 0; 384 } 385 if (isp->isp_osinfo.devq != NULL) { 386 cam_simq_free(isp->isp_osinfo.devq); 387 isp->isp_osinfo.devq = NULL; 388 } 389 return (0); 390 } 391 392 static void 393 isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg) 394 { 395 if (IS_FC(isp)) { 396 struct isp_fc *fc = ISP_FC_PC(isp, chan); 397 if (fc->simqfrozen == 0) { 398 isp_prt(isp, ISP_LOGDEBUG0, "%s: freeze simq (loopdown) chan %d", msg, chan); 399 fc->simqfrozen = SIMQFRZ_LOOPDOWN; 400 xpt_freeze_simq(fc->sim, 1); 401 } else { 402 isp_prt(isp, ISP_LOGDEBUG0, "%s: mark frozen (loopdown) chan %d", msg, chan); 403 fc->simqfrozen |= SIMQFRZ_LOOPDOWN; 404 } 405 } 406 } 407 408 static void 409 isp_unfreeze_loopdown(ispsoftc_t *isp, int chan) 410 { 411 if (IS_FC(isp)) { 412 struct isp_fc *fc = ISP_FC_PC(isp, chan); 413 int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN; 414 fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN; 415 if (wasfrozen && fc->simqfrozen == 0) { 416 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan); 417 xpt_release_simq(fc->sim, 1); 418 } 419 } 420 } 421 422 423 static int 424 ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td) 425 { 426 ispsoftc_t *isp; 427 int nr, chan, retval = ENOTTY; 428 429 isp = dev->si_drv1; 430 431 switch (c) { 432 case ISP_SDBLEV: 433 { 434 int olddblev = isp->isp_dblev; 435 isp->isp_dblev = *(int *)addr; 436 *(int *)addr = olddblev; 437 retval = 0; 438 break; 439 } 440 case ISP_GETROLE: 441 chan = *(int *)addr; 442 if (chan < 0 || chan >= isp->isp_nchan) { 443 retval = -ENXIO; 444 break; 445 } 446 if (IS_FC(isp)) { 447 *(int *)addr = FCPARAM(isp, chan)->role; 448 } else { 449 *(int *)addr = SDPARAM(isp, chan)->role; 450 } 451 retval = 0; 452 break; 453 case ISP_SETROLE: 454 nr = *(int *)addr; 455 chan = nr >> 8; 456 if (chan < 0 || chan >= isp->isp_nchan) { 457 retval = -ENXIO; 458 break; 459 } 460 nr &= 0xff; 461 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) { 462 retval = EINVAL; 463 break; 464 } 465 ISP_LOCK(isp); 466 if (IS_FC(isp)) 467 *(int *)addr = FCPARAM(isp, chan)->role; 468 else 469 *(int *)addr = SDPARAM(isp, chan)->role; 470 retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr); 471 ISP_UNLOCK(isp); 472 retval = 0; 473 break; 474 475 case ISP_RESETHBA: 476 ISP_LOCK(isp); 477 #ifdef ISP_TARGET_MODE 478 isp_del_all_wwn_entries(isp, ISP_NOCHAN); 479 #endif 480 isp_reinit(isp, 0); 481 ISP_UNLOCK(isp); 482 retval = 0; 483 break; 484 485 case ISP_RESCAN: 486 if (IS_FC(isp)) { 487 chan = *(int *)addr; 488 if (chan < 0 || chan >= isp->isp_nchan) { 489 retval = -ENXIO; 490 break; 491 } 492 ISP_LOCK(isp); 493 if (isp_fc_runstate(isp, chan, 5 * 1000000)) { 494 retval = EIO; 495 } else { 496 retval = 0; 497 } 498 ISP_UNLOCK(isp); 499 } 500 break; 501 502 case ISP_FC_LIP: 503 if (IS_FC(isp)) { 504 chan = *(int *)addr; 505 if (chan < 0 || chan >= isp->isp_nchan) { 506 retval = -ENXIO; 507 break; 508 } 509 ISP_LOCK(isp); 510 if (isp_control(isp, ISPCTL_SEND_LIP, chan)) { 511 retval = EIO; 512 } else { 513 retval = 0; 514 } 515 ISP_UNLOCK(isp); 516 } 517 break; 518 case ISP_FC_GETDINFO: 519 { 520 struct isp_fc_device *ifc = (struct isp_fc_device *) addr; 521 fcportdb_t *lp; 522 523 if (IS_SCSI(isp)) { 524 break; 525 } 526 if (ifc->loopid >= MAX_FC_TARG) { 527 retval = EINVAL; 528 break; 529 } 530 lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid]; 531 if (lp->state == FC_PORTDB_STATE_VALID || lp->target_mode) { 532 ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 533 ifc->loopid = lp->handle; 534 ifc->portid = lp->portid; 535 ifc->node_wwn = lp->node_wwn; 536 ifc->port_wwn = lp->port_wwn; 537 retval = 0; 538 } else { 539 retval = ENODEV; 540 } 541 break; 542 } 543 case ISP_GET_STATS: 544 { 545 isp_stats_t *sp = (isp_stats_t *) addr; 546 547 ISP_MEMZERO(sp, sizeof (*sp)); 548 sp->isp_stat_version = ISP_STATS_VERSION; 549 sp->isp_type = isp->isp_type; 550 sp->isp_revision = isp->isp_revision; 551 ISP_LOCK(isp); 552 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt; 553 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus; 554 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc; 555 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync; 556 sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt; 557 sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt; 558 sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater; 559 sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater; 560 ISP_UNLOCK(isp); 561 retval = 0; 562 break; 563 } 564 case ISP_CLR_STATS: 565 ISP_LOCK(isp); 566 isp->isp_intcnt = 0; 567 isp->isp_intbogus = 0; 568 isp->isp_intmboxc = 0; 569 isp->isp_intoasync = 0; 570 isp->isp_rsltccmplt = 0; 571 isp->isp_fphccmplt = 0; 572 isp->isp_rscchiwater = 0; 573 isp->isp_fpcchiwater = 0; 574 ISP_UNLOCK(isp); 575 retval = 0; 576 break; 577 case ISP_FC_GETHINFO: 578 { 579 struct isp_hba_device *hba = (struct isp_hba_device *) addr; 580 int chan = hba->fc_channel; 581 582 if (chan < 0 || chan >= isp->isp_nchan) { 583 retval = ENXIO; 584 break; 585 } 586 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev); 587 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev); 588 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev); 589 hba->fc_nchannels = isp->isp_nchan; 590 if (IS_FC(isp)) { 591 hba->fc_nports = MAX_FC_TARG; 592 hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed; 593 hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1; 594 hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid; 595 hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram; 596 hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram; 597 hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn; 598 hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn; 599 } else { 600 hba->fc_nports = MAX_TARGETS; 601 hba->fc_speed = 0; 602 hba->fc_topology = 0; 603 hba->nvram_node_wwn = 0ull; 604 hba->nvram_port_wwn = 0ull; 605 hba->active_node_wwn = 0ull; 606 hba->active_port_wwn = 0ull; 607 } 608 retval = 0; 609 break; 610 } 611 case ISP_TSK_MGMT: 612 { 613 int needmarker; 614 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr; 615 uint16_t loopid; 616 mbreg_t mbs; 617 618 if (IS_SCSI(isp)) { 619 break; 620 } 621 622 chan = fct->chan; 623 if (chan < 0 || chan >= isp->isp_nchan) { 624 retval = -ENXIO; 625 break; 626 } 627 628 needmarker = retval = 0; 629 loopid = fct->loopid; 630 ISP_LOCK(isp); 631 if (IS_24XX(isp)) { 632 uint8_t local[QENTRY_LEN]; 633 isp24xx_tmf_t *tmf; 634 isp24xx_statusreq_t *sp; 635 fcparam *fcp = FCPARAM(isp, chan); 636 fcportdb_t *lp; 637 int i; 638 639 for (i = 0; i < MAX_FC_TARG; i++) { 640 lp = &fcp->portdb[i]; 641 if (lp->handle == loopid) { 642 break; 643 } 644 } 645 if (i == MAX_FC_TARG) { 646 retval = ENXIO; 647 ISP_UNLOCK(isp); 648 break; 649 } 650 /* XXX VALIDATE LP XXX */ 651 tmf = (isp24xx_tmf_t *) local; 652 ISP_MEMZERO(tmf, QENTRY_LEN); 653 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT; 654 tmf->tmf_header.rqs_entry_count = 1; 655 tmf->tmf_nphdl = lp->handle; 656 tmf->tmf_delay = 2; 657 tmf->tmf_timeout = 2; 658 tmf->tmf_tidlo = lp->portid; 659 tmf->tmf_tidhi = lp->portid >> 16; 660 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan); 661 tmf->tmf_lun[1] = fct->lun & 0xff; 662 if (fct->lun >= 256) { 663 tmf->tmf_lun[0] = 0x40 | (fct->lun >> 8); 664 } 665 switch (fct->action) { 666 case IPT_CLEAR_ACA: 667 tmf->tmf_flags = ISP24XX_TMF_CLEAR_ACA; 668 break; 669 case IPT_TARGET_RESET: 670 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET; 671 needmarker = 1; 672 break; 673 case IPT_LUN_RESET: 674 tmf->tmf_flags = ISP24XX_TMF_LUN_RESET; 675 needmarker = 1; 676 break; 677 case IPT_CLEAR_TASK_SET: 678 tmf->tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET; 679 needmarker = 1; 680 break; 681 case IPT_ABORT_TASK_SET: 682 tmf->tmf_flags = ISP24XX_TMF_ABORT_TASK_SET; 683 needmarker = 1; 684 break; 685 default: 686 retval = EINVAL; 687 break; 688 } 689 if (retval) { 690 ISP_UNLOCK(isp); 691 break; 692 } 693 MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000); 694 mbs.param[1] = QENTRY_LEN; 695 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 696 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 697 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 698 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 699 700 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 701 ISP_UNLOCK(isp); 702 retval = ENOMEM; 703 break; 704 } 705 isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch); 706 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan); 707 sp = (isp24xx_statusreq_t *) local; 708 sp->req_completion_status = 1; 709 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 710 MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan); 711 isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp); 712 FC_SCRATCH_RELEASE(isp, chan); 713 if (retval || sp->req_completion_status != 0) { 714 FC_SCRATCH_RELEASE(isp, chan); 715 retval = EIO; 716 } 717 if (retval == 0) { 718 if (needmarker) { 719 fcp->sendmarker = 1; 720 } 721 } 722 } else { 723 MBSINIT(&mbs, 0, MBLOGALL, 0); 724 if (ISP_CAP_2KLOGIN(isp) == 0) { 725 loopid <<= 8; 726 } 727 switch (fct->action) { 728 case IPT_CLEAR_ACA: 729 mbs.param[0] = MBOX_CLEAR_ACA; 730 mbs.param[1] = loopid; 731 mbs.param[2] = fct->lun; 732 break; 733 case IPT_TARGET_RESET: 734 mbs.param[0] = MBOX_TARGET_RESET; 735 mbs.param[1] = loopid; 736 needmarker = 1; 737 break; 738 case IPT_LUN_RESET: 739 mbs.param[0] = MBOX_LUN_RESET; 740 mbs.param[1] = loopid; 741 mbs.param[2] = fct->lun; 742 needmarker = 1; 743 break; 744 case IPT_CLEAR_TASK_SET: 745 mbs.param[0] = MBOX_CLEAR_TASK_SET; 746 mbs.param[1] = loopid; 747 mbs.param[2] = fct->lun; 748 needmarker = 1; 749 break; 750 case IPT_ABORT_TASK_SET: 751 mbs.param[0] = MBOX_ABORT_TASK_SET; 752 mbs.param[1] = loopid; 753 mbs.param[2] = fct->lun; 754 needmarker = 1; 755 break; 756 default: 757 retval = EINVAL; 758 break; 759 } 760 if (retval == 0) { 761 if (needmarker) { 762 FCPARAM(isp, chan)->sendmarker = 1; 763 } 764 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 765 if (retval) { 766 retval = EIO; 767 } 768 } 769 } 770 ISP_UNLOCK(isp); 771 break; 772 } 773 default: 774 break; 775 } 776 return (retval); 777 } 778 779 static void 780 isp_intr_enable(void *arg) 781 { 782 int chan; 783 ispsoftc_t *isp = arg; 784 ISP_LOCK(isp); 785 for (chan = 0; chan < isp->isp_nchan; chan++) { 786 if (IS_FC(isp)) { 787 if (FCPARAM(isp, chan)->role != ISP_ROLE_NONE) { 788 ISP_ENABLE_INTS(isp); 789 break; 790 } 791 } else { 792 if (SDPARAM(isp, chan)->role != ISP_ROLE_NONE) { 793 ISP_ENABLE_INTS(isp); 794 break; 795 } 796 } 797 } 798 isp->isp_osinfo.ehook_active = 0; 799 ISP_UNLOCK(isp); 800 /* Release our hook so that the boot can continue. */ 801 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 802 } 803 804 /* 805 * Local Inlines 806 */ 807 808 static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *); 809 static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *); 810 811 static ISP_INLINE int 812 isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb) 813 { 814 ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free; 815 if (ISP_PCMD(ccb) == NULL) { 816 return (-1); 817 } 818 isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next; 819 return (0); 820 } 821 822 static ISP_INLINE void 823 isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb) 824 { 825 if (ISP_PCMD(ccb)) { 826 #ifdef ISP_TARGET_MODE 827 PISP_PCMD(ccb)->datalen = 0; 828 PISP_PCMD(ccb)->totslen = 0; 829 PISP_PCMD(ccb)->cumslen = 0; 830 PISP_PCMD(ccb)->crn = 0; 831 #endif 832 PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free; 833 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb); 834 ISP_PCMD(ccb) = NULL; 835 } 836 } 837 838 /* 839 * Put the target mode functions here, because some are inlines 840 */ 841 #ifdef ISP_TARGET_MODE 842 static ISP_INLINE void isp_tmlock(ispsoftc_t *, const char *); 843 static ISP_INLINE void isp_tmunlk(ispsoftc_t *); 844 static ISP_INLINE int is_any_lun_enabled(ispsoftc_t *, int); 845 static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t); 846 static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t); 847 static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t); 848 static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *); 849 static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **); 850 static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t); 851 static ISP_INLINE atio_private_data_t *isp_find_atpd(ispsoftc_t *, tstate_t *, uint32_t); 852 static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *); 853 static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *); 854 static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t); 855 static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *); 856 static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **); 857 static void destroy_lun_state(ispsoftc_t *, tstate_t *); 858 static void isp_enable_lun(ispsoftc_t *, union ccb *); 859 static cam_status isp_enable_deferred_luns(ispsoftc_t *, int); 860 static cam_status isp_enable_deferred(ispsoftc_t *, int, lun_id_t); 861 static void isp_disable_lun(ispsoftc_t *, union ccb *); 862 static int isp_enable_target_mode(ispsoftc_t *, int); 863 static int isp_disable_target_mode(ispsoftc_t *, int); 864 static void isp_ledone(ispsoftc_t *, lun_entry_t *); 865 static timeout_t isp_refire_putback_atio; 866 static timeout_t isp_refire_notify_ack; 867 static void isp_complete_ctio(union ccb *); 868 static void isp_target_putback_atio(union ccb *); 869 enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE }; 870 static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How); 871 static void isp_handle_platform_atio(ispsoftc_t *, at_entry_t *); 872 static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *); 873 static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *); 874 static void isp_handle_platform_ctio(ispsoftc_t *, void *); 875 static void isp_handle_platform_notify_scsi(ispsoftc_t *, in_entry_t *); 876 static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *); 877 static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *); 878 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *); 879 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *); 880 static void isp_target_mark_aborted(ispsoftc_t *, union ccb *); 881 static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t); 882 883 static ISP_INLINE void 884 isp_tmlock(ispsoftc_t *isp, const char *msg) 885 { 886 while (isp->isp_osinfo.tmbusy) { 887 isp->isp_osinfo.tmwanted = 1; 888 mtx_sleep(isp, &isp->isp_lock, PRIBIO, msg, 0); 889 } 890 isp->isp_osinfo.tmbusy = 1; 891 } 892 893 static ISP_INLINE void 894 isp_tmunlk(ispsoftc_t *isp) 895 { 896 isp->isp_osinfo.tmbusy = 0; 897 if (isp->isp_osinfo.tmwanted) { 898 isp->isp_osinfo.tmwanted = 0; 899 wakeup(isp); 900 } 901 } 902 903 static ISP_INLINE int 904 is_any_lun_enabled(ispsoftc_t *isp, int bus) 905 { 906 struct tslist *lhp; 907 int i; 908 909 for (i = 0; i < LUN_HASH_SIZE; i++) { 910 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 911 if (SLIST_FIRST(lhp)) 912 return (1); 913 } 914 return (0); 915 } 916 917 static ISP_INLINE int 918 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun) 919 { 920 tstate_t *tptr; 921 struct tslist *lhp; 922 923 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 924 SLIST_FOREACH(tptr, lhp, next) { 925 if (tptr->ts_lun == lun) { 926 return (1); 927 } 928 } 929 return (0); 930 } 931 932 static void 933 dump_tstates(ispsoftc_t *isp, int bus) 934 { 935 int i, j; 936 struct tslist *lhp; 937 tstate_t *tptr = NULL; 938 939 if (bus >= isp->isp_nchan) { 940 return; 941 } 942 for (i = 0; i < LUN_HASH_SIZE; i++) { 943 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 944 j = 0; 945 SLIST_FOREACH(tptr, lhp, next) { 946 xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count); 947 j++; 948 } 949 } 950 } 951 952 static ISP_INLINE tstate_t * 953 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun) 954 { 955 tstate_t *tptr = NULL; 956 struct tslist *lhp; 957 958 if (bus < isp->isp_nchan) { 959 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 960 SLIST_FOREACH(tptr, lhp, next) { 961 if (tptr->ts_lun == lun) { 962 tptr->hold++; 963 return (tptr); 964 } 965 } 966 } 967 return (NULL); 968 } 969 970 static ISP_INLINE tstate_t * 971 get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval) 972 { 973 tstate_t *tptr = NULL; 974 atio_private_data_t *atp; 975 struct tslist *lhp; 976 int i; 977 978 if (bus < isp->isp_nchan && tagval != 0) { 979 for (i = 0; i < LUN_HASH_SIZE; i++) { 980 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 981 SLIST_FOREACH(tptr, lhp, next) { 982 atp = isp_find_atpd(isp, tptr, tagval); 983 if (atp) { 984 tptr->hold++; 985 return (tptr); 986 } 987 } 988 } 989 } 990 return (NULL); 991 } 992 993 static ISP_INLINE inot_private_data_t * 994 get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt) 995 { 996 inot_private_data_t *ntp; 997 tstate_t *tptr; 998 struct tslist *lhp; 999 int bus, i; 1000 1001 for (bus = 0; bus < isp->isp_nchan; bus++) { 1002 for (i = 0; i < LUN_HASH_SIZE; i++) { 1003 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 1004 SLIST_FOREACH(tptr, lhp, next) { 1005 ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id); 1006 if (ntp) { 1007 *rslt = tptr; 1008 tptr->hold++; 1009 return (ntp); 1010 } 1011 } 1012 } 1013 } 1014 return (NULL); 1015 } 1016 1017 static ISP_INLINE void 1018 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr) 1019 { 1020 KASSERT((tptr->hold), ("tptr not held")); 1021 tptr->hold--; 1022 } 1023 1024 static void 1025 isp_tmcmd_restart(ispsoftc_t *isp) 1026 { 1027 inot_private_data_t *ntp; 1028 inot_private_data_t *restart_queue; 1029 tstate_t *tptr; 1030 union ccb *ccb; 1031 struct tslist *lhp; 1032 int bus, i; 1033 1034 for (bus = 0; bus < isp->isp_nchan; bus++) { 1035 for (i = 0; i < LUN_HASH_SIZE; i++) { 1036 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 1037 SLIST_FOREACH(tptr, lhp, next) { 1038 if ((restart_queue = tptr->restart_queue) != NULL) 1039 tptr->restart_queue = NULL; 1040 while (restart_queue) { 1041 ntp = restart_queue; 1042 restart_queue = ntp->rd.nt.nt_hba; 1043 if (IS_24XX(isp)) { 1044 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid); 1045 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data); 1046 } else { 1047 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid); 1048 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data); 1049 } 1050 isp_put_ntpd(isp, tptr, ntp); 1051 if (tptr->restart_queue && restart_queue != NULL) { 1052 ntp = tptr->restart_queue; 1053 tptr->restart_queue = restart_queue; 1054 while (restart_queue->rd.nt.nt_hba) { 1055 restart_queue = restart_queue->rd.nt.nt_hba; 1056 } 1057 restart_queue->rd.nt.nt_hba = ntp; 1058 break; 1059 } 1060 } 1061 /* 1062 * We only need to do this once per tptr 1063 */ 1064 if (!TAILQ_EMPTY(&tptr->waitq)) { 1065 ccb = (union ccb *)TAILQ_LAST(&tptr->waitq, isp_ccbq); 1066 TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1067 isp_target_start_ctio(isp, ccb, FROM_TIMER); 1068 } 1069 } 1070 } 1071 } 1072 } 1073 1074 static ISP_INLINE atio_private_data_t * 1075 isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag) 1076 { 1077 atio_private_data_t *atp; 1078 1079 atp = LIST_FIRST(&tptr->atfree); 1080 if (atp) { 1081 LIST_REMOVE(atp, next); 1082 atp->tag = tag; 1083 LIST_INSERT_HEAD(&tptr->atused[ATPDPHASH(tag)], atp, next); 1084 } 1085 return (atp); 1086 } 1087 1088 static ISP_INLINE atio_private_data_t * 1089 isp_find_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag) 1090 { 1091 atio_private_data_t *atp; 1092 1093 LIST_FOREACH(atp, &tptr->atused[ATPDPHASH(tag)], next) { 1094 if (atp->tag == tag) 1095 return (atp); 1096 } 1097 return (NULL); 1098 } 1099 1100 static ISP_INLINE void 1101 isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp) 1102 { 1103 if (atp->ests) { 1104 isp_put_ecmd(isp, atp->ests); 1105 } 1106 LIST_REMOVE(atp, next); 1107 memset(atp, 0, sizeof (*atp)); 1108 LIST_INSERT_HEAD(&tptr->atfree, atp, next); 1109 } 1110 1111 static void 1112 isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr) 1113 { 1114 atio_private_data_t *atp; 1115 const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" }; 1116 1117 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) { 1118 xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %u nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n", 1119 atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]); 1120 } 1121 } 1122 1123 1124 static ISP_INLINE inot_private_data_t * 1125 isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr) 1126 { 1127 inot_private_data_t *ntp; 1128 ntp = tptr->ntfree; 1129 if (ntp) { 1130 tptr->ntfree = ntp->next; 1131 } 1132 return (ntp); 1133 } 1134 1135 static ISP_INLINE inot_private_data_t * 1136 isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id) 1137 { 1138 inot_private_data_t *ntp; 1139 for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) { 1140 if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) { 1141 return (ntp); 1142 } 1143 } 1144 return (NULL); 1145 } 1146 1147 static ISP_INLINE void 1148 isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp) 1149 { 1150 ntp->rd.tag_id = ntp->rd.seq_id = 0; 1151 ntp->next = tptr->ntfree; 1152 tptr->ntfree = ntp; 1153 } 1154 1155 static cam_status 1156 create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt) 1157 { 1158 cam_status status; 1159 lun_id_t lun; 1160 struct tslist *lhp; 1161 tstate_t *tptr; 1162 int i; 1163 1164 lun = xpt_path_lun_id(path); 1165 if (lun != CAM_LUN_WILDCARD) { 1166 if (lun >= ISP_MAX_LUNS(isp)) { 1167 return (CAM_LUN_INVALID); 1168 } 1169 } 1170 if (is_lun_enabled(isp, bus, lun)) { 1171 return (CAM_LUN_ALRDY_ENA); 1172 } 1173 tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO); 1174 if (tptr == NULL) { 1175 return (CAM_RESRC_UNAVAIL); 1176 } 1177 tptr->ts_lun = lun; 1178 status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun); 1179 if (status != CAM_REQ_CMP) { 1180 free(tptr, M_DEVBUF); 1181 return (status); 1182 } 1183 SLIST_INIT(&tptr->atios); 1184 SLIST_INIT(&tptr->inots); 1185 TAILQ_INIT(&tptr->waitq); 1186 LIST_INIT(&tptr->atfree); 1187 for (i = ATPDPSIZE-1; i >= 0; i--) 1188 LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next); 1189 for (i = 0; i < ATPDPHASHSIZE; i++) 1190 LIST_INIT(&tptr->atused[i]); 1191 for (i = 0; i < ATPDPSIZE-1; i++) 1192 tptr->ntpool[i].next = &tptr->ntpool[i+1]; 1193 tptr->ntfree = tptr->ntpool; 1194 tptr->hold = 1; 1195 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 1196 SLIST_INSERT_HEAD(lhp, tptr, next); 1197 *rslt = tptr; 1198 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n"); 1199 return (CAM_REQ_CMP); 1200 } 1201 1202 static ISP_INLINE void 1203 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr) 1204 { 1205 union ccb *ccb; 1206 struct tslist *lhp; 1207 1208 KASSERT((tptr->hold != 0), ("tptr is not held")); 1209 KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold)); 1210 do { 1211 ccb = (union ccb *)SLIST_FIRST(&tptr->atios); 1212 if (ccb) { 1213 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1214 ccb->ccb_h.status = CAM_REQ_ABORTED; 1215 xpt_done(ccb); 1216 } 1217 } while (ccb); 1218 do { 1219 ccb = (union ccb *)SLIST_FIRST(&tptr->inots); 1220 if (ccb) { 1221 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 1222 ccb->ccb_h.status = CAM_REQ_ABORTED; 1223 xpt_done(ccb); 1224 } 1225 } while (ccb); 1226 ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp); 1227 SLIST_REMOVE(lhp, tptr, tstate, next); 1228 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n"); 1229 xpt_free_path(tptr->owner); 1230 free(tptr, M_DEVBUF); 1231 } 1232 1233 /* 1234 * Enable a lun. 1235 */ 1236 static void 1237 isp_enable_lun(ispsoftc_t *isp, union ccb *ccb) 1238 { 1239 tstate_t *tptr = NULL; 1240 int bus, tm_enabled, target_role; 1241 target_id_t target; 1242 lun_id_t lun; 1243 1244 1245 /* 1246 * We only support either a wildcard target/lun or a target ID of zero and a non-wildcard lun 1247 */ 1248 bus = XS_CHANNEL(ccb); 1249 target = ccb->ccb_h.target_id; 1250 lun = ccb->ccb_h.target_lun; 1251 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "enabling lun %u\n", lun); 1252 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) { 1253 ccb->ccb_h.status = CAM_LUN_INVALID; 1254 xpt_done(ccb); 1255 return; 1256 } 1257 1258 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) { 1259 ccb->ccb_h.status = CAM_LUN_INVALID; 1260 xpt_done(ccb); 1261 return; 1262 } 1263 if (isp->isp_dblev & ISP_LOGTDEBUG0) { 1264 xpt_print(ccb->ccb_h.path, "enabling lun 0x%x on channel %d\n", lun, bus); 1265 } 1266 1267 /* 1268 * Wait until we're not busy with the lun enables subsystem 1269 */ 1270 isp_tmlock(isp, "isp_enable_lun"); 1271 1272 /* 1273 * This is as a good a place as any to check f/w capabilities. 1274 */ 1275 1276 if (IS_FC(isp)) { 1277 if (ISP_CAP_TMODE(isp) == 0) { 1278 xpt_print(ccb->ccb_h.path, "firmware does not support target mode\n"); 1279 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1280 goto done; 1281 } 1282 /* 1283 * We *could* handle non-SCCLUN f/w, but we'd have to 1284 * dork with our already fragile enable/disable code. 1285 */ 1286 if (ISP_CAP_SCCFW(isp) == 0) { 1287 xpt_print(ccb->ccb_h.path, "firmware not SCCLUN capable\n"); 1288 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1289 goto done; 1290 } 1291 1292 target_role = (FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0; 1293 1294 } else { 1295 target_role = (SDPARAM(isp, bus)->role & ISP_ROLE_TARGET) != 0; 1296 } 1297 1298 /* 1299 * Create the state pointer. 1300 * It should not already exist. 1301 */ 1302 tptr = get_lun_statep(isp, bus, lun); 1303 if (tptr) { 1304 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 1305 goto done; 1306 } 1307 ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr); 1308 if (ccb->ccb_h.status != CAM_REQ_CMP) { 1309 goto done; 1310 } 1311 1312 /* 1313 * We have a tricky maneuver to perform here. 1314 * 1315 * If target mode isn't already enabled here, 1316 * *and* our current role includes target mode, 1317 * we enable target mode here. 1318 * 1319 */ 1320 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled); 1321 if (tm_enabled == 0 && target_role != 0) { 1322 if (isp_enable_target_mode(isp, bus)) { 1323 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1324 destroy_lun_state(isp, tptr); 1325 tptr = NULL; 1326 goto done; 1327 } 1328 tm_enabled = 1; 1329 } 1330 1331 /* 1332 * Now check to see whether this bus is in target mode already. 1333 * 1334 * If not, a later role change into target mode will finish the job. 1335 */ 1336 if (tm_enabled == 0) { 1337 ISP_SET_PC(isp, bus, tm_enable_defer, 1); 1338 ccb->ccb_h.status = CAM_REQ_CMP; 1339 xpt_print(ccb->ccb_h.path, "Target Mode not enabled yet- lun enable deferred\n"); 1340 goto done1; 1341 } 1342 1343 /* 1344 * Enable the lun. 1345 */ 1346 ccb->ccb_h.status = isp_enable_deferred(isp, bus, lun); 1347 1348 done: 1349 if (ccb->ccb_h.status != CAM_REQ_CMP) { 1350 if (tptr) { 1351 destroy_lun_state(isp, tptr); 1352 tptr = NULL; 1353 } 1354 } else { 1355 tptr->enabled = 1; 1356 } 1357 done1: 1358 if (tptr) { 1359 rls_lun_statep(isp, tptr); 1360 } 1361 1362 /* 1363 * And we're outta here.... 1364 */ 1365 isp_tmunlk(isp); 1366 xpt_done(ccb); 1367 } 1368 1369 static cam_status 1370 isp_enable_deferred_luns(ispsoftc_t *isp, int bus) 1371 { 1372 tstate_t *tptr = NULL; 1373 struct tslist *lhp; 1374 int i, n; 1375 1376 1377 ISP_GET_PC(isp, bus, tm_enabled, i); 1378 if (i == 1) { 1379 return (CAM_REQ_CMP); 1380 } 1381 ISP_GET_PC(isp, bus, tm_enable_defer, i); 1382 if (i == 0) { 1383 return (CAM_REQ_CMP); 1384 } 1385 /* 1386 * If this succeeds, it will set tm_enable 1387 */ 1388 if (isp_enable_target_mode(isp, bus)) { 1389 return (CAM_REQ_CMP_ERR); 1390 } 1391 isp_tmlock(isp, "isp_enable_deferred_luns"); 1392 for (n = i = 0; i < LUN_HASH_SIZE; i++) { 1393 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 1394 SLIST_FOREACH(tptr, lhp, next) { 1395 tptr->hold++; 1396 if (tptr->enabled == 0) { 1397 if (isp_enable_deferred(isp, bus, tptr->ts_lun) == CAM_REQ_CMP) { 1398 tptr->enabled = 1; 1399 n++; 1400 } 1401 } else { 1402 n++; 1403 } 1404 tptr->hold--; 1405 } 1406 } 1407 isp_tmunlk(isp); 1408 if (n == 0) { 1409 return (CAM_REQ_CMP_ERR); 1410 } 1411 ISP_SET_PC(isp, bus, tm_enable_defer, 0); 1412 return (CAM_REQ_CMP); 1413 } 1414 1415 static cam_status 1416 isp_enable_deferred(ispsoftc_t *isp, int bus, lun_id_t lun) 1417 { 1418 cam_status status; 1419 int luns_already_enabled; 1420 1421 ISP_GET_PC(isp, bus, tm_luns_enabled, luns_already_enabled); 1422 isp_prt(isp, ISP_LOGTINFO, "%s: bus %d lun %jx luns_enabled %d", __func__, bus, (uintmax_t)lun, luns_already_enabled); 1423 if (IS_24XX(isp) || (IS_FC(isp) && luns_already_enabled)) { 1424 status = CAM_REQ_CMP; 1425 } else { 1426 int cmd_cnt, not_cnt; 1427 1428 if (IS_23XX(isp)) { 1429 cmd_cnt = DFLT_CMND_CNT; 1430 not_cnt = DFLT_INOT_CNT; 1431 } else { 1432 cmd_cnt = 64; 1433 not_cnt = 8; 1434 } 1435 status = CAM_REQ_INPROG; 1436 isp->isp_osinfo.rptr = &status; 1437 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun == CAM_LUN_WILDCARD? 0 : lun, cmd_cnt, not_cnt)) { 1438 status = CAM_RESRC_UNAVAIL; 1439 } else { 1440 mtx_sleep(&status, &isp->isp_lock, PRIBIO, "isp_enable_deferred", 0); 1441 } 1442 isp->isp_osinfo.rptr = NULL; 1443 } 1444 if (status == CAM_REQ_CMP) { 1445 ISP_SET_PC(isp, bus, tm_luns_enabled, 1); 1446 isp_prt(isp, ISP_LOGCONFIG|ISP_LOGTINFO, "bus %d lun %jx now enabled for target mode", bus, (uintmax_t)lun); 1447 } 1448 return (status); 1449 } 1450 1451 static void 1452 isp_disable_lun(ispsoftc_t *isp, union ccb *ccb) 1453 { 1454 tstate_t *tptr = NULL; 1455 int bus; 1456 cam_status status; 1457 target_id_t target; 1458 lun_id_t lun; 1459 1460 bus = XS_CHANNEL(ccb); 1461 target = ccb->ccb_h.target_id; 1462 lun = ccb->ccb_h.target_lun; 1463 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, "disabling lun %u\n", lun); 1464 if (target == CAM_TARGET_WILDCARD && lun != CAM_LUN_WILDCARD) { 1465 ccb->ccb_h.status = CAM_LUN_INVALID; 1466 xpt_done(ccb); 1467 return; 1468 } 1469 1470 if (target != CAM_TARGET_WILDCARD && lun == CAM_LUN_WILDCARD) { 1471 ccb->ccb_h.status = CAM_LUN_INVALID; 1472 xpt_done(ccb); 1473 return; 1474 } 1475 1476 /* 1477 * See if we're busy disabling a lun now. 1478 */ 1479 isp_tmlock(isp, "isp_disable_lun"); 1480 status = CAM_REQ_INPROG; 1481 1482 /* 1483 * Find the state pointer. 1484 */ 1485 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) { 1486 status = CAM_PATH_INVALID; 1487 goto done; 1488 } 1489 1490 /* 1491 * If we're a 24XX card, we're done. 1492 */ 1493 if (IS_24XX(isp)) { 1494 status = CAM_REQ_CMP; 1495 goto done; 1496 } 1497 1498 /* 1499 * For SCC FW, we only deal with lun zero. 1500 */ 1501 if (IS_FC(isp) && lun > 0) { 1502 status = CAM_REQ_CMP; 1503 goto done; 1504 } 1505 isp->isp_osinfo.rptr = &status; 1506 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, lun, 0, 0)) { 1507 status = CAM_RESRC_UNAVAIL; 1508 } else { 1509 mtx_sleep(ccb, &isp->isp_lock, PRIBIO, "isp_disable_lun", 0); 1510 } 1511 isp->isp_osinfo.rptr = NULL; 1512 done: 1513 if (status == CAM_REQ_CMP) { 1514 tptr->enabled = 0; 1515 /* 1516 * If we have no more luns enabled for this bus, 1517 * delete all tracked wwns for it (if we are FC), 1518 * and disable target mode. 1519 */ 1520 if (is_any_lun_enabled(isp, bus) == 0) { 1521 isp_del_all_wwn_entries(isp, bus); 1522 if (isp_disable_target_mode(isp, bus)) { 1523 status = CAM_REQ_CMP_ERR; 1524 } 1525 } 1526 } 1527 ccb->ccb_h.status = status; 1528 if (status == CAM_REQ_CMP) { 1529 destroy_lun_state(isp, tptr); 1530 xpt_print(ccb->ccb_h.path, "lun now disabled for target mode\n"); 1531 } else { 1532 if (tptr) 1533 rls_lun_statep(isp, tptr); 1534 } 1535 isp_tmunlk(isp); 1536 xpt_done(ccb); 1537 } 1538 1539 static int 1540 isp_enable_target_mode(ispsoftc_t *isp, int bus) 1541 { 1542 int tm_enabled; 1543 1544 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled); 1545 if (tm_enabled != 0) { 1546 return (0); 1547 } 1548 if (IS_SCSI(isp)) { 1549 mbreg_t mbs; 1550 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0); 1551 mbs.param[0] = MBOX_ENABLE_TARGET_MODE; 1552 mbs.param[1] = ENABLE_TARGET_FLAG|ENABLE_TQING_FLAG; 1553 mbs.param[2] = bus << 7; 1554 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1555 isp_prt(isp, ISP_LOGERR, "Unable to enable Target Role on Bus %d", bus); 1556 return (EIO); 1557 } 1558 } 1559 ISP_SET_PC(isp, bus, tm_enabled, 1); 1560 isp_prt(isp, ISP_LOGINFO, "Target Role enabled on Bus %d", bus); 1561 return (0); 1562 } 1563 1564 static int 1565 isp_disable_target_mode(ispsoftc_t *isp, int bus) 1566 { 1567 int tm_enabled; 1568 1569 ISP_GET_PC(isp, bus, tm_enabled, tm_enabled); 1570 if (tm_enabled == 0) { 1571 return (0); 1572 } 1573 if (IS_SCSI(isp)) { 1574 mbreg_t mbs; 1575 MBSINIT(&mbs, MBOX_ENABLE_TARGET_MODE, MBLOGALL, 0); 1576 mbs.param[2] = bus << 7; 1577 if (isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs) < 0 || mbs.param[0] != MBOX_COMMAND_COMPLETE) { 1578 isp_prt(isp, ISP_LOGERR, "Unable to disable Target Role on Bus %d", bus); 1579 return (EIO); 1580 } 1581 } 1582 ISP_SET_PC(isp, bus, tm_enabled, 0); 1583 isp_prt(isp, ISP_LOGINFO, "Target Role disabled on Bus %d", bus); 1584 return (0); 1585 } 1586 1587 static void 1588 isp_ledone(ispsoftc_t *isp, lun_entry_t *lep) 1589 { 1590 uint32_t *rptr; 1591 1592 rptr = isp->isp_osinfo.rptr; 1593 if (lep->le_status != LUN_OK) { 1594 isp_prt(isp, ISP_LOGERR, "ENABLE/MODIFY LUN returned 0x%x", lep->le_status); 1595 if (rptr) { 1596 *rptr = CAM_REQ_CMP_ERR; 1597 wakeup_one(rptr); 1598 } 1599 } else { 1600 if (rptr) { 1601 *rptr = CAM_REQ_CMP; 1602 wakeup_one(rptr); 1603 } 1604 } 1605 } 1606 1607 static void 1608 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how) 1609 { 1610 int fctape, sendstatus, resid; 1611 tstate_t *tptr; 1612 fcparam *fcp; 1613 atio_private_data_t *atp; 1614 struct ccb_scsiio *cso; 1615 uint32_t dmaresult, handle, xfrlen, sense_length, tmp; 1616 uint8_t local[QENTRY_LEN]; 1617 1618 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb)); 1619 if (tptr == NULL) { 1620 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD); 1621 if (tptr == NULL) { 1622 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find tstate pointer", __func__, ccb->csio.tag_id); 1623 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1624 xpt_done(ccb); 1625 return; 1626 } 1627 } 1628 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ENTRY[0x%x] how %u xfrlen %u sendstatus %d sense_len %u", __func__, ccb->csio.tag_id, how, ccb->csio.dxfer_len, 1629 (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0)); 1630 1631 switch (how) { 1632 case FROM_TIMER: 1633 case FROM_CAM: 1634 /* 1635 * Insert at the tail of the list, if any, waiting CTIO CCBs 1636 */ 1637 TAILQ_INSERT_TAIL(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1638 break; 1639 case FROM_SRR: 1640 case FROM_CTIO_DONE: 1641 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1642 break; 1643 } 1644 1645 while (TAILQ_FIRST(&tptr->waitq) != NULL) { 1646 ccb = (union ccb *) TAILQ_FIRST(&tptr->waitq); 1647 TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1648 1649 cso = &ccb->csio; 1650 xfrlen = cso->dxfer_len; 1651 if (xfrlen == 0) { 1652 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) { 1653 ISP_PATH_PRT(isp, ISP_LOGERR, ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n"); 1654 ccb->ccb_h.status = CAM_REQ_INVALID; 1655 xpt_done(ccb); 1656 continue; 1657 } 1658 } 1659 1660 atp = isp_find_atpd(isp, tptr, cso->tag_id); 1661 if (atp == NULL) { 1662 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__); 1663 isp_dump_atpd(isp, tptr); 1664 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1665 xpt_done(ccb); 1666 continue; 1667 } 1668 1669 /* 1670 * Is this command a dead duck? 1671 */ 1672 if (atp->dead) { 1673 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id); 1674 ccb->ccb_h.status = CAM_REQ_ABORTED; 1675 xpt_done(ccb); 1676 continue; 1677 } 1678 1679 /* 1680 * Check to make sure we're still in target mode. 1681 */ 1682 fcp = FCPARAM(isp, XS_CHANNEL(ccb)); 1683 if ((fcp->role & ISP_ROLE_TARGET) == 0) { 1684 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode", __func__, cso->tag_id); 1685 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1686 xpt_done(ccb); 1687 continue; 1688 } 1689 1690 /* 1691 * We're only handling ATPD_CCB_OUTSTANDING outstanding CCB at a time (one of which 1692 * could be split into two CTIOs to split data and status). 1693 */ 1694 if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) { 1695 isp_prt(isp, ISP_LOGTINFO, "[0x%x] handling only %d CCBs at a time (flags for this ccb: 0x%x)", cso->tag_id, ATPD_CCB_OUTSTANDING, ccb->ccb_h.flags); 1696 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1697 break; 1698 } 1699 1700 /* 1701 * Does the initiator expect FC-Tape style responses? 1702 */ 1703 if ((atp->word3 & PRLI_WD3_RETRY) && fcp->fctape_enabled) { 1704 fctape = 1; 1705 } else { 1706 fctape = 0; 1707 } 1708 1709 /* 1710 * If we already did the data xfer portion of a CTIO that sends data 1711 * and status, don't do it again and do the status portion now. 1712 */ 1713 if (atp->sendst) { 1714 isp_prt(isp, ISP_LOGTINFO, "[0x%x] now sending synthesized status orig_dl=%u xfered=%u bit=%u", 1715 cso->tag_id, atp->orig_datalen, atp->bytes_xfered, atp->bytes_in_transit); 1716 xfrlen = 0; /* we already did the data transfer */ 1717 atp->sendst = 0; 1718 } 1719 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 1720 sendstatus = 1; 1721 } else { 1722 sendstatus = 0; 1723 } 1724 1725 if (ccb->ccb_h.flags & CAM_SEND_SENSE) { 1726 KASSERT((sendstatus != 0), ("how can you have CAM_SEND_SENSE w/o CAM_SEND_STATUS?")); 1727 /* 1728 * Sense length is not the entire sense data structure size. Periph 1729 * drivers don't seem to be setting sense_len to reflect the actual 1730 * size. We'll peek inside to get the right amount. 1731 */ 1732 sense_length = cso->sense_len; 1733 1734 /* 1735 * This 'cannot' happen 1736 */ 1737 if (sense_length > (XCMD_SIZE - MIN_FCP_RESPONSE_SIZE)) { 1738 sense_length = XCMD_SIZE - MIN_FCP_RESPONSE_SIZE; 1739 } 1740 } else { 1741 sense_length = 0; 1742 } 1743 1744 memset(local, 0, QENTRY_LEN); 1745 1746 /* 1747 * Check for overflow 1748 */ 1749 tmp = atp->bytes_xfered + atp->bytes_in_transit + xfrlen; 1750 if (tmp > atp->orig_datalen) { 1751 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] data overflow by %u bytes", __func__, cso->tag_id, tmp - atp->orig_datalen); 1752 ccb->ccb_h.status = CAM_DATA_RUN_ERR; 1753 xpt_done(ccb); 1754 continue; 1755 } 1756 1757 if (IS_24XX(isp)) { 1758 ct7_entry_t *cto = (ct7_entry_t *) local; 1759 1760 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 1761 cto->ct_header.rqs_entry_count = 1; 1762 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM; 1763 ATPD_SET_SEQNO(cto, atp); 1764 cto->ct_nphdl = atp->nphdl; 1765 cto->ct_rxid = atp->tag; 1766 cto->ct_iid_lo = atp->portid; 1767 cto->ct_iid_hi = atp->portid >> 16; 1768 cto->ct_oxid = atp->oxid; 1769 cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb)); 1770 cto->ct_timeout = 120; 1771 cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT; 1772 1773 /* 1774 * Mode 1, status, no data. Only possible when we are sending status, have 1775 * no data to transfer, and any sense data can fit into a ct7_entry_t. 1776 * 1777 * Mode 2, status, no data. We have to use this in the case that 1778 * the sense data won't fit into a ct7_entry_t. 1779 * 1780 */ 1781 if (sendstatus && xfrlen == 0) { 1782 cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA; 1783 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 1784 if (sense_length <= MAXRESPLEN_24XX) { 1785 if (resid < 0) { 1786 cto->ct_resid = -resid; 1787 } else if (resid > 0) { 1788 cto->ct_resid = resid; 1789 } 1790 cto->ct_flags |= CT7_FLAG_MODE1; 1791 cto->ct_scsi_status = cso->scsi_status; 1792 if (resid < 0) { 1793 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); 1794 } else if (resid > 0) { 1795 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); 1796 } 1797 if (fctape) { 1798 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1799 } 1800 if (sense_length) { 1801 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); 1802 cto->rsp.m1.ct_resplen = cto->ct_senselen = sense_length; 1803 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length); 1804 } 1805 } else { 1806 bus_addr_t addr; 1807 char buf[XCMD_SIZE]; 1808 fcp_rsp_iu_t *rp; 1809 1810 if (atp->ests == NULL) { 1811 atp->ests = isp_get_ecmd(isp); 1812 if (atp->ests == NULL) { 1813 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1814 break; 1815 } 1816 } 1817 memset(buf, 0, sizeof (buf)); 1818 rp = (fcp_rsp_iu_t *)buf; 1819 if (fctape) { 1820 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1821 rp->fcp_rsp_bits |= FCP_CONF_REQ; 1822 } 1823 cto->ct_flags |= CT7_FLAG_MODE2; 1824 rp->fcp_rsp_scsi_status = cso->scsi_status; 1825 if (resid < 0) { 1826 rp->fcp_rsp_resid = -resid; 1827 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW; 1828 } else if (resid > 0) { 1829 rp->fcp_rsp_resid = resid; 1830 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW; 1831 } 1832 if (sense_length) { 1833 rp->fcp_rsp_snslen = sense_length; 1834 cto->ct_senselen = sense_length; 1835 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID; 1836 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1837 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length); 1838 } else { 1839 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1840 } 1841 if (isp->isp_dblev & ISP_LOGTDEBUG1) { 1842 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); 1843 } 1844 addr = isp->isp_osinfo.ecmd_dma; 1845 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); 1846 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests, 1847 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length); 1848 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length; 1849 cto->rsp.m2.ct_fcp_rsp_iudata.ds_base = DMA_LO32(addr); 1850 cto->rsp.m2.ct_fcp_rsp_iudata.ds_basehi = DMA_HI32(addr); 1851 cto->rsp.m2.ct_fcp_rsp_iudata.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 1852 } 1853 if (sense_length) { 1854 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d slen %u sense: %x %x/%x/%x", __func__, 1855 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid, sense_length, 1856 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]); 1857 } else { 1858 isp_prt(isp, ISP_LOGDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__, 1859 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid); 1860 } 1861 atp->state = ATPD_STATE_LAST_CTIO; 1862 } 1863 1864 /* 1865 * Mode 0 data transfers, *possibly* with status. 1866 */ 1867 if (xfrlen != 0) { 1868 cto->ct_flags |= CT7_FLAG_MODE0; 1869 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1870 cto->ct_flags |= CT7_DATA_IN; 1871 } else { 1872 cto->ct_flags |= CT7_DATA_OUT; 1873 } 1874 1875 cto->rsp.m0.reloff = atp->bytes_xfered + atp->bytes_in_transit; 1876 cto->rsp.m0.ct_xfrlen = xfrlen; 1877 1878 #ifdef DEBUG 1879 if (ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame && xfrlen > ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame) { 1880 isp_prt(isp, ISP_LOGWARN, "%s: truncating data frame with xfrlen %d to %d", __func__, xfrlen, xfrlen - (xfrlen >> 2)); 1881 ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame = 0; 1882 cto->rsp.m0.ct_xfrlen -= xfrlen >> 2; 1883 } 1884 #endif 1885 if (sendstatus) { 1886 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen; 1887 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /* && fctape == 0 */) { 1888 cto->ct_flags |= CT7_SENDSTATUS; 1889 atp->state = ATPD_STATE_LAST_CTIO; 1890 if (fctape) { 1891 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1892 } 1893 } else { 1894 atp->sendst = 1; /* send status later */ 1895 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM; 1896 atp->state = ATPD_STATE_CTIO; 1897 } 1898 } else { 1899 atp->state = ATPD_STATE_CTIO; 1900 } 1901 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x xfrlen=%u off=%u", __func__, 1902 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered); 1903 } 1904 } else if (IS_FC(isp)) { 1905 ct2_entry_t *cto = (ct2_entry_t *) local; 1906 1907 if (isp->isp_osinfo.sixtyfourbit) 1908 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3; 1909 else 1910 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 1911 cto->ct_header.rqs_entry_count = 1; 1912 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM; 1913 ATPD_SET_SEQNO(cto, atp); 1914 if (ISP_CAP_2KLOGIN(isp) == 0) { 1915 ((ct2e_entry_t *)cto)->ct_iid = cso->init_id; 1916 } else { 1917 cto->ct_iid = cso->init_id; 1918 if (ISP_CAP_SCCFW(isp) == 0) { 1919 cto->ct_lun = ccb->ccb_h.target_lun; 1920 } 1921 } 1922 cto->ct_timeout = 10; 1923 cto->ct_rxid = cso->tag_id; 1924 1925 /* 1926 * Mode 1, status, no data. Only possible when we are sending status, have 1927 * no data to transfer, and the sense length can fit in the ct7_entry. 1928 * 1929 * Mode 2, status, no data. We have to use this in the case the response 1930 * length won't fit into a ct2_entry_t. 1931 * 1932 * We'll fill out this structure with information as if this were a 1933 * Mode 1. The hardware layer will create the Mode 2 FCP RSP IU as 1934 * needed based upon this. 1935 */ 1936 if (sendstatus && xfrlen == 0) { 1937 cto->ct_flags |= CT2_SENDSTATUS | CT2_NO_DATA; 1938 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 1939 if (sense_length <= MAXRESPLEN) { 1940 if (resid < 0) { 1941 cto->ct_resid = -resid; 1942 } else if (resid > 0) { 1943 cto->ct_resid = resid; 1944 } 1945 cto->ct_flags |= CT2_FLAG_MODE1; 1946 cto->rsp.m1.ct_scsi_status = cso->scsi_status; 1947 if (resid < 0) { 1948 cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER; 1949 } else if (resid > 0) { 1950 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 1951 } 1952 if (fctape) { 1953 cto->ct_flags |= CT2_CONFIRM; 1954 } 1955 if (sense_length) { 1956 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 1957 cto->rsp.m1.ct_resplen = cto->rsp.m1.ct_senselen = sense_length; 1958 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length); 1959 } 1960 } else { 1961 bus_addr_t addr; 1962 char buf[XCMD_SIZE]; 1963 fcp_rsp_iu_t *rp; 1964 1965 if (atp->ests == NULL) { 1966 atp->ests = isp_get_ecmd(isp); 1967 if (atp->ests == NULL) { 1968 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1969 break; 1970 } 1971 } 1972 memset(buf, 0, sizeof (buf)); 1973 rp = (fcp_rsp_iu_t *)buf; 1974 if (fctape) { 1975 cto->ct_flags |= CT2_CONFIRM; 1976 rp->fcp_rsp_bits |= FCP_CONF_REQ; 1977 } 1978 cto->ct_flags |= CT2_FLAG_MODE2; 1979 rp->fcp_rsp_scsi_status = cso->scsi_status; 1980 if (resid < 0) { 1981 rp->fcp_rsp_resid = -resid; 1982 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW; 1983 } else if (resid > 0) { 1984 rp->fcp_rsp_resid = resid; 1985 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW; 1986 } 1987 if (sense_length) { 1988 rp->fcp_rsp_snslen = sense_length; 1989 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID; 1990 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1991 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length); 1992 } else { 1993 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1994 } 1995 if (isp->isp_dblev & ISP_LOGTDEBUG1) { 1996 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); 1997 } 1998 addr = isp->isp_osinfo.ecmd_dma; 1999 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); 2000 isp_prt(isp, ISP_LOGTDEBUG0, "%s: ests base %p vaddr %p ecmd_dma %jx addr %jx len %u", __func__, isp->isp_osinfo.ecmd_base, atp->ests, 2001 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length); 2002 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length; 2003 if (isp->isp_osinfo.sixtyfourbit) { 2004 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_base = DMA_LO32(addr); 2005 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_basehi = DMA_HI32(addr); 2006 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 2007 } else { 2008 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_base = DMA_LO32(addr); 2009 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 2010 } 2011 } 2012 if (sense_length) { 2013 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d sense: %x %x/%x/%x", __func__, 2014 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, 2015 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]); 2016 } else { 2017 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__, cto->ct_rxid, 2018 ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid); 2019 } 2020 atp->state = ATPD_STATE_LAST_CTIO; 2021 } 2022 2023 if (xfrlen != 0) { 2024 cto->ct_flags |= CT2_FLAG_MODE0; 2025 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2026 cto->ct_flags |= CT2_DATA_IN; 2027 } else { 2028 cto->ct_flags |= CT2_DATA_OUT; 2029 } 2030 2031 cto->ct_reloff = atp->bytes_xfered + atp->bytes_in_transit; 2032 cto->rsp.m0.ct_xfrlen = xfrlen; 2033 2034 if (sendstatus) { 2035 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen; 2036 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /*&& fctape == 0*/) { 2037 cto->ct_flags |= CT2_SENDSTATUS; 2038 atp->state = ATPD_STATE_LAST_CTIO; 2039 if (fctape) { 2040 cto->ct_flags |= CT2_CONFIRM; 2041 } 2042 } else { 2043 atp->sendst = 1; /* send status later */ 2044 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM; 2045 atp->state = ATPD_STATE_CTIO; 2046 } 2047 } else { 2048 atp->state = ATPD_STATE_CTIO; 2049 } 2050 } 2051 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO2[%x] seq %u nc %d CDB0=%x scsi status %x flags %x resid %d xfrlen %u offset %u", __func__, cto->ct_rxid, 2052 ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, cso->dxfer_len, atp->bytes_xfered); 2053 } else { 2054 ct_entry_t *cto = (ct_entry_t *) local; 2055 2056 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 2057 cto->ct_header.rqs_entry_count = 1; 2058 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM; 2059 ATPD_SET_SEQNO(cto, atp); 2060 cto->ct_iid = cso->init_id; 2061 cto->ct_iid |= XS_CHANNEL(ccb) << 7; 2062 cto->ct_tgt = ccb->ccb_h.target_id; 2063 cto->ct_lun = ccb->ccb_h.target_lun; 2064 cto->ct_fwhandle = cso->tag_id; 2065 if (atp->rxid) { 2066 cto->ct_tag_val = atp->rxid; 2067 cto->ct_flags |= CT_TQAE; 2068 } 2069 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) { 2070 cto->ct_flags |= CT_NODISC; 2071 } 2072 if (cso->dxfer_len == 0) { 2073 cto->ct_flags |= CT_NO_DATA; 2074 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 2075 cto->ct_flags |= CT_DATA_IN; 2076 } else { 2077 cto->ct_flags |= CT_DATA_OUT; 2078 } 2079 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 2080 cto->ct_flags |= CT_SENDSTATUS|CT_CCINCR; 2081 cto->ct_scsi_status = cso->scsi_status; 2082 cto->ct_resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit - xfrlen; 2083 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d scsi status %x resid %d tag_id %x", __func__, 2084 cto->ct_fwhandle, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), cso->scsi_status, cso->resid, cso->tag_id); 2085 } 2086 ccb->ccb_h.flags &= ~CAM_SEND_SENSE; 2087 cto->ct_timeout = 10; 2088 } 2089 2090 if (isp_get_pcmd(isp, ccb)) { 2091 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n"); 2092 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 2093 break; 2094 } 2095 if (isp_allocate_xs_tgt(isp, ccb, &handle)) { 2096 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__); 2097 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 2098 isp_free_pcmd(isp, ccb); 2099 break; 2100 } 2101 atp->bytes_in_transit += xfrlen; 2102 PISP_PCMD(ccb)->datalen = xfrlen; 2103 2104 2105 /* 2106 * Call the dma setup routines for this entry (and any subsequent 2107 * CTIOs) if there's data to move, and then tell the f/w it's got 2108 * new things to play with. As with isp_start's usage of DMA setup, 2109 * any swizzling is done in the machine dependent layer. Because 2110 * of this, we put the request onto the queue area first in native 2111 * format. 2112 */ 2113 2114 if (IS_24XX(isp)) { 2115 ct7_entry_t *cto = (ct7_entry_t *) local; 2116 cto->ct_syshandle = handle; 2117 } else if (IS_FC(isp)) { 2118 ct2_entry_t *cto = (ct2_entry_t *) local; 2119 cto->ct_syshandle = handle; 2120 } else { 2121 ct_entry_t *cto = (ct_entry_t *) local; 2122 cto->ct_syshandle = handle; 2123 } 2124 2125 dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local); 2126 if (dmaresult != CMD_QUEUED) { 2127 isp_destroy_tgt_handle(isp, handle); 2128 isp_free_pcmd(isp, ccb); 2129 if (dmaresult == CMD_EAGAIN) { 2130 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 2131 break; 2132 } 2133 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 2134 xpt_done(ccb); 2135 continue; 2136 } 2137 isp->isp_nactive++; 2138 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED; 2139 if (xfrlen) { 2140 ccb->ccb_h.spriv_field0 = atp->bytes_xfered; 2141 } else { 2142 ccb->ccb_h.spriv_field0 = ~0; 2143 } 2144 atp->ctcnt++; 2145 atp->seqno++; 2146 } 2147 rls_lun_statep(isp, tptr); 2148 } 2149 2150 static void 2151 isp_refire_putback_atio(void *arg) 2152 { 2153 union ccb *ccb = arg; 2154 2155 ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb)); 2156 isp_target_putback_atio(ccb); 2157 } 2158 2159 static void 2160 isp_refire_notify_ack(void *arg) 2161 { 2162 isp_tna_t *tp = arg; 2163 ispsoftc_t *isp = tp->isp; 2164 2165 ISP_ASSERT_LOCKED(isp); 2166 if (isp_notify_ack(isp, tp->not)) { 2167 callout_schedule(&tp->timer, 5); 2168 } else { 2169 free(tp, M_DEVBUF); 2170 } 2171 } 2172 2173 2174 static void 2175 isp_target_putback_atio(union ccb *ccb) 2176 { 2177 ispsoftc_t *isp; 2178 struct ccb_scsiio *cso; 2179 void *qe; 2180 2181 isp = XS_ISP(ccb); 2182 2183 qe = isp_getrqentry(isp); 2184 if (qe == NULL) { 2185 xpt_print(ccb->ccb_h.path, 2186 "%s: Request Queue Overflow\n", __func__); 2187 callout_reset(&PISP_PCMD(ccb)->wdog, 10, 2188 isp_refire_putback_atio, ccb); 2189 return; 2190 } 2191 memset(qe, 0, QENTRY_LEN); 2192 cso = &ccb->csio; 2193 if (IS_FC(isp)) { 2194 at2_entry_t local, *at = &local; 2195 ISP_MEMZERO(at, sizeof (at2_entry_t)); 2196 at->at_header.rqs_entry_type = RQSTYPE_ATIO2; 2197 at->at_header.rqs_entry_count = 1; 2198 if (ISP_CAP_SCCFW(isp)) { 2199 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun; 2200 } else { 2201 at->at_lun = (uint8_t) ccb->ccb_h.target_lun; 2202 } 2203 at->at_status = CT_OK; 2204 at->at_rxid = cso->tag_id; 2205 at->at_iid = cso->ccb_h.target_id; 2206 isp_put_atio2(isp, at, qe); 2207 } else { 2208 at_entry_t local, *at = &local; 2209 ISP_MEMZERO(at, sizeof (at_entry_t)); 2210 at->at_header.rqs_entry_type = RQSTYPE_ATIO; 2211 at->at_header.rqs_entry_count = 1; 2212 at->at_iid = cso->init_id; 2213 at->at_iid |= XS_CHANNEL(ccb) << 7; 2214 at->at_tgt = cso->ccb_h.target_id; 2215 at->at_lun = cso->ccb_h.target_lun; 2216 at->at_status = CT_OK; 2217 at->at_tag_val = AT_GET_TAG(cso->tag_id); 2218 at->at_handle = AT_GET_HANDLE(cso->tag_id); 2219 isp_put_atio(isp, at, qe); 2220 } 2221 ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe); 2222 ISP_SYNC_REQUEST(isp); 2223 isp_complete_ctio(ccb); 2224 } 2225 2226 static void 2227 isp_complete_ctio(union ccb *ccb) 2228 { 2229 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 2230 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 2231 xpt_done(ccb); 2232 } 2233 } 2234 2235 /* 2236 * Handle ATIO stuff that the generic code can't. 2237 * This means handling CDBs. 2238 */ 2239 2240 static void 2241 isp_handle_platform_atio(ispsoftc_t *isp, at_entry_t *aep) 2242 { 2243 tstate_t *tptr; 2244 int status, bus; 2245 struct ccb_accept_tio *atiop; 2246 atio_private_data_t *atp; 2247 2248 /* 2249 * The firmware status (except for the QLTM_SVALID bit) 2250 * indicates why this ATIO was sent to us. 2251 * 2252 * If QLTM_SVALID is set, the firmware has recommended Sense Data. 2253 * 2254 * If the DISCONNECTS DISABLED bit is set in the flags field, 2255 * we're still connected on the SCSI bus. 2256 */ 2257 status = aep->at_status; 2258 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) { 2259 /* 2260 * Bus Phase Sequence error. We should have sense data 2261 * suggested by the f/w. I'm not sure quite yet what 2262 * to do about this for CAM. 2263 */ 2264 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR"); 2265 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2266 return; 2267 } 2268 if ((status & ~QLTM_SVALID) != AT_CDB) { 2269 isp_prt(isp, ISP_LOGWARN, "bad atio (0x%x) leaked to platform", status); 2270 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2271 return; 2272 } 2273 2274 bus = GET_BUS_VAL(aep->at_iid); 2275 tptr = get_lun_statep(isp, bus, aep->at_lun); 2276 if (tptr == NULL) { 2277 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD); 2278 if (tptr == NULL) { 2279 /* 2280 * Because we can't autofeed sense data back with 2281 * a command for parallel SCSI, we can't give back 2282 * a CHECK CONDITION. We'll give back a BUSY status 2283 * instead. This works out okay because the only 2284 * time we should, in fact, get this, is in the 2285 * case that somebody configured us without the 2286 * blackhole driver, so they get what they deserve. 2287 */ 2288 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2289 return; 2290 } 2291 } 2292 2293 atp = isp_get_atpd(isp, tptr, aep->at_handle); 2294 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 2295 if (atiop == NULL || atp == NULL) { 2296 /* 2297 * Because we can't autofeed sense data back with 2298 * a command for parallel SCSI, we can't give back 2299 * a CHECK CONDITION. We'll give back a QUEUE FULL status 2300 * instead. This works out okay because the only time we 2301 * should, in fact, get this, is in the case that we've 2302 * run out of ATIOS. 2303 */ 2304 xpt_print(tptr->owner, "no %s for lun %d from initiator %d\n", (atp == NULL && atiop == NULL)? "ATIOs *or* ATPS" : 2305 ((atp == NULL)? "ATPs" : "ATIOs"), aep->at_lun, aep->at_iid); 2306 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2307 if (atp) { 2308 isp_put_atpd(isp, tptr, atp); 2309 } 2310 rls_lun_statep(isp, tptr); 2311 return; 2312 } 2313 atp->rxid = aep->at_tag_val; 2314 atp->state = ATPD_STATE_ATIO; 2315 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 2316 tptr->atio_count--; 2317 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count); 2318 atiop->ccb_h.target_id = aep->at_tgt; 2319 atiop->ccb_h.target_lun = aep->at_lun; 2320 if (aep->at_flags & AT_NODISC) { 2321 atiop->ccb_h.flags |= CAM_DIS_DISCONNECT; 2322 } else { 2323 atiop->ccb_h.flags &= ~CAM_DIS_DISCONNECT; 2324 } 2325 2326 if (status & QLTM_SVALID) { 2327 size_t amt = ISP_MIN(QLTM_SENSELEN, sizeof (atiop->sense_data)); 2328 atiop->sense_len = amt; 2329 ISP_MEMCPY(&atiop->sense_data, aep->at_sense, amt); 2330 } else { 2331 atiop->sense_len = 0; 2332 } 2333 2334 atiop->init_id = GET_IID_VAL(aep->at_iid); 2335 atiop->cdb_len = aep->at_cdblen; 2336 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen); 2337 atiop->ccb_h.status = CAM_CDB_RECVD; 2338 /* 2339 * Construct a tag 'id' based upon tag value (which may be 0..255) 2340 * and the handle (which we have to preserve). 2341 */ 2342 atiop->tag_id = atp->tag; 2343 if (aep->at_flags & AT_TQAE) { 2344 atiop->tag_action = aep->at_tag_type; 2345 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; 2346 } 2347 atp->orig_datalen = 0; 2348 atp->bytes_xfered = 0; 2349 atp->lun = aep->at_lun; 2350 atp->nphdl = aep->at_iid; 2351 atp->portid = PORT_NONE; 2352 atp->oxid = 0; 2353 atp->cdb0 = atiop->cdb_io.cdb_bytes[0]; 2354 atp->tattr = aep->at_tag_type; 2355 atp->state = ATPD_STATE_CAM; 2356 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO[0x%x] CDB=0x%x lun %d", aep->at_tag_val, atp->cdb0, atp->lun); 2357 rls_lun_statep(isp, tptr); 2358 } 2359 2360 static void 2361 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) 2362 { 2363 lun_id_t lun; 2364 fcportdb_t *lp; 2365 tstate_t *tptr; 2366 struct ccb_accept_tio *atiop; 2367 uint16_t nphdl; 2368 atio_private_data_t *atp; 2369 inot_private_data_t *ntp; 2370 2371 /* 2372 * The firmware status (except for the QLTM_SVALID bit) 2373 * indicates why this ATIO was sent to us. 2374 * 2375 * If QLTM_SVALID is set, the firmware has recommended Sense Data. 2376 */ 2377 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) { 2378 isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status); 2379 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2380 return; 2381 } 2382 2383 if (ISP_CAP_SCCFW(isp)) { 2384 lun = aep->at_scclun; 2385 } else { 2386 lun = aep->at_lun; 2387 } 2388 if (ISP_CAP_2KLOGIN(isp)) { 2389 nphdl = ((at2e_entry_t *)aep)->at_iid; 2390 } else { 2391 nphdl = aep->at_iid; 2392 } 2393 tptr = get_lun_statep(isp, 0, lun); 2394 if (tptr == NULL) { 2395 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 2396 if (tptr == NULL) { 2397 isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %jx or wildcard", __func__, aep->at_rxid, (uintmax_t)lun); 2398 if (lun == 0) { 2399 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 2400 } else { 2401 isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0); 2402 } 2403 return; 2404 } 2405 } 2406 2407 /* 2408 * Start any commands pending resources first. 2409 */ 2410 if (tptr->restart_queue) { 2411 inot_private_data_t *restart_queue = tptr->restart_queue; 2412 tptr->restart_queue = NULL; 2413 while (restart_queue) { 2414 ntp = restart_queue; 2415 restart_queue = ntp->rd.nt.nt_hba; 2416 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid); 2417 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data); 2418 isp_put_ntpd(isp, tptr, ntp); 2419 /* 2420 * If a recursion caused the restart queue to start to fill again, 2421 * stop and splice the new list on top of the old list and restore 2422 * it and go to noresrc. 2423 */ 2424 if (tptr->restart_queue) { 2425 ntp = tptr->restart_queue; 2426 tptr->restart_queue = restart_queue; 2427 while (restart_queue->rd.nt.nt_hba) { 2428 restart_queue = restart_queue->rd.nt.nt_hba; 2429 } 2430 restart_queue->rd.nt.nt_hba = ntp; 2431 goto noresrc; 2432 } 2433 } 2434 } 2435 2436 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 2437 if (atiop == NULL) { 2438 goto noresrc; 2439 } 2440 2441 atp = isp_get_atpd(isp, tptr, aep->at_rxid); 2442 if (atp == NULL) { 2443 goto noresrc; 2444 } 2445 2446 atp->state = ATPD_STATE_ATIO; 2447 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 2448 tptr->atio_count--; 2449 isp_prt(isp, ISP_LOGTDEBUG2, "Take FREE ATIO count now %d", tptr->atio_count); 2450 atiop->ccb_h.target_id = FCPARAM(isp, 0)->isp_loopid; 2451 atiop->ccb_h.target_lun = lun; 2452 2453 /* 2454 * We don't get 'suggested' sense data as we do with SCSI cards. 2455 */ 2456 atiop->sense_len = 0; 2457 if (ISP_CAP_2KLOGIN(isp)) { 2458 /* 2459 * NB: We could not possibly have 2K logins if we 2460 * NB: also did not have SCC FW. 2461 */ 2462 atiop->init_id = ((at2e_entry_t *)aep)->at_iid; 2463 } else { 2464 atiop->init_id = aep->at_iid; 2465 } 2466 2467 /* 2468 * If we're not in the port database, add ourselves. 2469 */ 2470 if (!IS_2100(isp) && isp_find_pdb_by_loopid(isp, 0, atiop->init_id, &lp) == 0) { 2471 uint64_t iid = 2472 (((uint64_t) aep->at_wwpn[0]) << 48) | 2473 (((uint64_t) aep->at_wwpn[1]) << 32) | 2474 (((uint64_t) aep->at_wwpn[2]) << 16) | 2475 (((uint64_t) aep->at_wwpn[3]) << 0); 2476 isp_add_wwn_entry(isp, 0, iid, atiop->init_id, PORT_ANY, 0); 2477 } 2478 atiop->cdb_len = ATIO2_CDBLEN; 2479 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN); 2480 atiop->ccb_h.status = CAM_CDB_RECVD; 2481 atiop->tag_id = atp->tag; 2482 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) { 2483 case ATIO2_TC_ATTR_SIMPLEQ: 2484 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2485 atiop->tag_action = MSG_SIMPLE_Q_TAG; 2486 break; 2487 case ATIO2_TC_ATTR_HEADOFQ: 2488 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2489 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 2490 break; 2491 case ATIO2_TC_ATTR_ORDERED: 2492 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2493 atiop->tag_action = MSG_ORDERED_Q_TAG; 2494 break; 2495 case ATIO2_TC_ATTR_ACAQ: /* ?? */ 2496 case ATIO2_TC_ATTR_UNTAGGED: 2497 default: 2498 atiop->tag_action = 0; 2499 break; 2500 } 2501 2502 atp->orig_datalen = aep->at_datalen; 2503 atp->bytes_xfered = 0; 2504 atp->lun = lun; 2505 atp->nphdl = atiop->init_id; 2506 atp->sid = PORT_ANY; 2507 atp->oxid = aep->at_oxid; 2508 atp->cdb0 = aep->at_cdb[0]; 2509 atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK; 2510 atp->state = ATPD_STATE_CAM; 2511 xpt_done((union ccb *)atiop); 2512 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO2[0x%x] CDB=0x%x lun %jx datalen %u", aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen); 2513 rls_lun_statep(isp, tptr); 2514 return; 2515 noresrc: 2516 ntp = isp_get_ntpd(isp, tptr); 2517 if (ntp == NULL) { 2518 rls_lun_statep(isp, tptr); 2519 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0); 2520 return; 2521 } 2522 memcpy(ntp->rd.data, aep, QENTRY_LEN); 2523 ntp->rd.nt.nt_hba = tptr->restart_queue; 2524 tptr->restart_queue = ntp; 2525 rls_lun_statep(isp, tptr); 2526 } 2527 2528 static void 2529 isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) 2530 { 2531 int cdbxlen; 2532 uint16_t lun, chan, nphdl = NIL_HANDLE; 2533 uint32_t did, sid; 2534 uint64_t wwn = INI_NONE; 2535 fcportdb_t *lp; 2536 tstate_t *tptr; 2537 struct ccb_accept_tio *atiop; 2538 atio_private_data_t *atp = NULL; 2539 atio_private_data_t *oatp; 2540 inot_private_data_t *ntp; 2541 2542 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; 2543 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 2544 lun = (aep->at_cmnd.fcp_cmnd_lun[0] << 8) | aep->at_cmnd.fcp_cmnd_lun[1]; 2545 2546 /* 2547 * Find the N-port handle, and Virtual Port Index for this command. 2548 * 2549 * If we can't, we're somewhat in trouble because we can't actually respond w/o that information. 2550 * We also, as a matter of course, need to know the WWN of the initiator too. 2551 */ 2552 if (ISP_CAP_MULTI_ID(isp)) { 2553 /* 2554 * Find the right channel based upon D_ID 2555 */ 2556 isp_find_chan_by_did(isp, did, &chan); 2557 2558 if (chan == ISP_NOCHAN) { 2559 NANOTIME_T now; 2560 2561 /* 2562 * If we don't recognizer our own D_DID, terminate the exchange, unless we're within 2 seconds of startup 2563 * It's a bit tricky here as we need to stash this command *somewhere*. 2564 */ 2565 GET_NANOTIME(&now); 2566 if (NANOTIME_SUB(&isp->isp_init_time, &now) > 2000000000ULL) { 2567 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __func__, aep->at_rxid, did); 2568 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0); 2569 return; 2570 } 2571 tptr = get_lun_statep(isp, 0, 0); 2572 if (tptr == NULL) { 2573 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 2574 if (tptr == NULL) { 2575 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel and no tptr- dropping", __func__, aep->at_rxid, did); 2576 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0); 2577 return; 2578 } 2579 } 2580 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- deferring", __func__, aep->at_rxid, did); 2581 goto noresrc; 2582 } 2583 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x", __func__, aep->at_rxid, did, chan, sid); 2584 } else { 2585 chan = 0; 2586 } 2587 2588 /* 2589 * Find the PDB entry for this initiator 2590 */ 2591 if (isp_find_pdb_by_sid(isp, chan, sid, &lp) == 0) { 2592 /* 2593 * If we're not in the port database terminate the exchange. 2594 */ 2595 isp_prt(isp, ISP_LOGTINFO, "%s: [RX_ID 0x%x] D_ID 0x%06x found on Chan %d for S_ID 0x%06x wasn't in PDB already", 2596 __func__, aep->at_rxid, did, chan, sid); 2597 isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0); 2598 return; 2599 } 2600 nphdl = lp->handle; 2601 wwn = lp->port_wwn; 2602 2603 /* 2604 * Get the tstate pointer 2605 */ 2606 tptr = get_lun_statep(isp, chan, lun); 2607 if (tptr == NULL) { 2608 tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD); 2609 if (tptr == NULL) { 2610 isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %d or wildcard", __func__, aep->at_rxid, lun); 2611 if (lun == 0) { 2612 isp_endcmd(isp, aep, nphdl, SCSI_STATUS_BUSY, 0); 2613 } else { 2614 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0); 2615 } 2616 return; 2617 } 2618 } 2619 2620 /* 2621 * Start any commands pending resources first. 2622 */ 2623 if (tptr->restart_queue) { 2624 inot_private_data_t *restart_queue = tptr->restart_queue; 2625 tptr->restart_queue = NULL; 2626 while (restart_queue) { 2627 ntp = restart_queue; 2628 restart_queue = ntp->rd.nt.nt_hba; 2629 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid); 2630 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data); 2631 isp_put_ntpd(isp, tptr, ntp); 2632 /* 2633 * If a recursion caused the restart queue to start to fill again, 2634 * stop and splice the new list on top of the old list and restore 2635 * it and go to noresrc. 2636 */ 2637 if (tptr->restart_queue) { 2638 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restart queue refilling", __func__); 2639 if (restart_queue) { 2640 ntp = tptr->restart_queue; 2641 tptr->restart_queue = restart_queue; 2642 while (restart_queue->rd.nt.nt_hba) { 2643 restart_queue = restart_queue->rd.nt.nt_hba; 2644 } 2645 restart_queue->rd.nt.nt_hba = ntp; 2646 } 2647 goto noresrc; 2648 } 2649 } 2650 } 2651 2652 /* 2653 * If the f/w is out of resources, just send a BUSY status back. 2654 */ 2655 if (aep->at_rxid == AT7_NORESRC_RXID) { 2656 rls_lun_statep(isp, tptr); 2657 isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0); 2658 return; 2659 } 2660 2661 /* 2662 * If we're out of resources, just send a BUSY status back. 2663 */ 2664 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 2665 if (atiop == NULL) { 2666 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid); 2667 goto noresrc; 2668 } 2669 2670 oatp = isp_find_atpd(isp, tptr, aep->at_rxid); 2671 if (oatp) { 2672 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] tag wraparound in isp_handle_platforms_atio7 (N-Port Handle 0x%04x S_ID 0x%04x OX_ID 0x%04x) oatp state %d", 2673 aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state); 2674 /* 2675 * It's not a "no resource" condition- but we can treat it like one 2676 */ 2677 goto noresrc; 2678 } 2679 atp = isp_get_atpd(isp, tptr, aep->at_rxid); 2680 if (atp == NULL) { 2681 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid); 2682 goto noresrc; 2683 } 2684 atp->word3 = lp->prli_word3; 2685 atp->state = ATPD_STATE_ATIO; 2686 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 2687 tptr->atio_count--; 2688 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count); 2689 atiop->init_id = nphdl; 2690 atiop->ccb_h.target_id = FCPARAM(isp, chan)->isp_loopid; 2691 atiop->ccb_h.target_lun = lun; 2692 atiop->sense_len = 0; 2693 cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT; 2694 if (cdbxlen) { 2695 isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored"); 2696 } 2697 cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb); 2698 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen); 2699 atiop->cdb_len = cdbxlen; 2700 atiop->ccb_h.status = CAM_CDB_RECVD; 2701 atiop->tag_id = atp->tag; 2702 switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) { 2703 case FCP_CMND_TASK_ATTR_SIMPLE: 2704 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2705 atiop->tag_action = MSG_SIMPLE_Q_TAG; 2706 break; 2707 case FCP_CMND_TASK_ATTR_HEAD: 2708 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2709 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 2710 break; 2711 case FCP_CMND_TASK_ATTR_ORDERED: 2712 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2713 atiop->tag_action = MSG_ORDERED_Q_TAG; 2714 break; 2715 default: 2716 /* FALLTHROUGH */ 2717 case FCP_CMND_TASK_ATTR_ACA: 2718 case FCP_CMND_TASK_ATTR_UNTAGGED: 2719 atiop->tag_action = 0; 2720 break; 2721 } 2722 atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 2723 atp->bytes_xfered = 0; 2724 atp->lun = lun; 2725 atp->nphdl = nphdl; 2726 atp->portid = sid; 2727 atp->oxid = aep->at_hdr.ox_id; 2728 atp->rxid = aep->at_hdr.rx_id; 2729 atp->cdb0 = atiop->cdb_io.cdb_bytes[0]; 2730 atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK; 2731 atp->state = ATPD_STATE_CAM; 2732 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %d datalen %u", aep->at_rxid, atp->cdb0, lun, atp->orig_datalen); 2733 xpt_done((union ccb *)atiop); 2734 rls_lun_statep(isp, tptr); 2735 return; 2736 noresrc: 2737 if (atp) { 2738 isp_put_atpd(isp, tptr, atp); 2739 } 2740 ntp = isp_get_ntpd(isp, tptr); 2741 if (ntp == NULL) { 2742 rls_lun_statep(isp, tptr); 2743 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0); 2744 return; 2745 } 2746 memcpy(ntp->rd.data, aep, QENTRY_LEN); 2747 ntp->rd.nt.nt_hba = tptr->restart_queue; 2748 tptr->restart_queue = ntp; 2749 rls_lun_statep(isp, tptr); 2750 } 2751 2752 2753 /* 2754 * Handle starting an SRR (sequence retransmit request) 2755 * We get here when we've gotten the immediate notify 2756 * and the return of all outstanding CTIOs for this 2757 * transaction. 2758 */ 2759 static void 2760 isp_handle_srr_start(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp) 2761 { 2762 in_fcentry_24xx_t *inot; 2763 uint32_t srr_off, ccb_off, ccb_len, ccb_end; 2764 union ccb *ccb; 2765 2766 inot = (in_fcentry_24xx_t *)atp->srr; 2767 srr_off = inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16); 2768 ccb = atp->srr_ccb; 2769 atp->srr_ccb = NULL; 2770 atp->nsrr++; 2771 if (ccb == NULL) { 2772 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] null ccb", atp->tag); 2773 goto fail; 2774 } 2775 2776 ccb_off = ccb->ccb_h.spriv_field0; 2777 ccb_len = ccb->csio.dxfer_len; 2778 ccb_end = (ccb_off == ~0)? ~0 : ccb_off + ccb_len; 2779 2780 switch (inot->in_srr_iu) { 2781 case R_CTL_INFO_SOLICITED_DATA: 2782 /* 2783 * We have to restart a FCP_DATA data out transaction 2784 */ 2785 atp->sendst = 0; 2786 atp->bytes_xfered = srr_off; 2787 if (ccb_len == 0) { 2788 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x but current CCB doesn't transfer data", atp->tag, srr_off); 2789 goto mdp; 2790 } 2791 if (srr_off < ccb_off || ccb_off > srr_off + ccb_len) { 2792 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x not covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end); 2793 goto mdp; 2794 } 2795 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x covered by current CCB data range [0x%x..0x%x]", atp->tag, srr_off, ccb_off, ccb_end); 2796 break; 2797 case R_CTL_INFO_COMMAND_STATUS: 2798 isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] Got an FCP RSP SRR- resending status", atp->tag); 2799 atp->sendst = 1; 2800 /* 2801 * We have to restart a FCP_RSP IU transaction 2802 */ 2803 break; 2804 case R_CTL_INFO_DATA_DESCRIPTOR: 2805 /* 2806 * We have to restart an FCP DATA in transaction 2807 */ 2808 isp_prt(isp, ISP_LOGWARN, "Got an FCP DATA IN SRR- dropping"); 2809 goto fail; 2810 2811 default: 2812 isp_prt(isp, ISP_LOGWARN, "Got an unknown information (%x) SRR- dropping", inot->in_srr_iu); 2813 goto fail; 2814 } 2815 2816 /* 2817 * We can't do anything until this is acked, so we might as well start it now. 2818 * We aren't going to do the usual asynchronous ack issue because we need 2819 * to make sure this gets on the wire first. 2820 */ 2821 if (isp_notify_ack(isp, inot)) { 2822 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose"); 2823 goto fail; 2824 } 2825 isp_target_start_ctio(isp, ccb, FROM_SRR); 2826 return; 2827 fail: 2828 inot->in_reserved = 1; 2829 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2830 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2831 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 2832 isp_complete_ctio(ccb); 2833 return; 2834 mdp: 2835 if (isp_notify_ack(isp, inot)) { 2836 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose"); 2837 goto fail; 2838 } 2839 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2840 ccb->ccb_h.status = CAM_MESSAGE_RECV; 2841 /* 2842 * This is not a strict interpretation of MDP, but it's close 2843 */ 2844 ccb->csio.msg_ptr = &ccb->csio.sense_data.sense_buf[SSD_FULL_SIZE - 16]; 2845 ccb->csio.msg_len = 7; 2846 ccb->csio.msg_ptr[0] = MSG_EXTENDED; 2847 ccb->csio.msg_ptr[1] = 5; 2848 ccb->csio.msg_ptr[2] = 0; /* modify data pointer */ 2849 ccb->csio.msg_ptr[3] = srr_off >> 24; 2850 ccb->csio.msg_ptr[4] = srr_off >> 16; 2851 ccb->csio.msg_ptr[5] = srr_off >> 8; 2852 ccb->csio.msg_ptr[6] = srr_off; 2853 isp_complete_ctio(ccb); 2854 } 2855 2856 2857 static void 2858 isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw) 2859 { 2860 tstate_t *tptr; 2861 in_fcentry_24xx_t *inot = inot_raw; 2862 atio_private_data_t *atp; 2863 uint32_t tag = inot->in_rxid; 2864 uint32_t bus = inot->in_vpidx; 2865 2866 if (!IS_24XX(isp)) { 2867 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_raw); 2868 return; 2869 } 2870 2871 tptr = get_lun_statep_from_tag(isp, bus, tag); 2872 if (tptr == NULL) { 2873 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x in SRR Notify", __func__, tag); 2874 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2875 return; 2876 } 2877 atp = isp_find_atpd(isp, tptr, tag); 2878 if (atp == NULL) { 2879 rls_lun_statep(isp, tptr); 2880 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag); 2881 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2882 return; 2883 } 2884 atp->srr_notify_rcvd = 1; 2885 memcpy(atp->srr, inot, sizeof (atp->srr)); 2886 isp_prt(isp, ISP_LOGTINFO /* ISP_LOGTDEBUG0 */, "SRR[0x%x] inot->in_rxid flags 0x%x srr_iu=%x reloff 0x%x", inot->in_rxid, inot->in_flags, inot->in_srr_iu, 2887 inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16)); 2888 if (atp->srr_ccb) 2889 isp_handle_srr_start(isp, tptr, atp); 2890 rls_lun_statep(isp, tptr); 2891 } 2892 2893 static void 2894 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) 2895 { 2896 union ccb *ccb; 2897 int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0; 2898 tstate_t *tptr = NULL; 2899 atio_private_data_t *atp = NULL; 2900 int bus; 2901 uint32_t handle, moved_data = 0, data_requested; 2902 2903 /* 2904 * CTIO handles are 16 bits. 2905 * CTIO2 and CTIO7 are 32 bits. 2906 */ 2907 2908 if (IS_SCSI(isp)) { 2909 handle = ((ct_entry_t *)arg)->ct_syshandle; 2910 } else { 2911 handle = ((ct2_entry_t *)arg)->ct_syshandle; 2912 } 2913 ccb = isp_find_xs_tgt(isp, handle); 2914 if (ccb == NULL) { 2915 isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg); 2916 return; 2917 } 2918 isp_destroy_tgt_handle(isp, handle); 2919 data_requested = PISP_PCMD(ccb)->datalen; 2920 isp_free_pcmd(isp, ccb); 2921 if (isp->isp_nactive) { 2922 isp->isp_nactive--; 2923 } 2924 2925 bus = XS_CHANNEL(ccb); 2926 tptr = get_lun_statep(isp, bus, XS_LUN(ccb)); 2927 if (tptr == NULL) { 2928 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD); 2929 } 2930 if (tptr == NULL) { 2931 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x after I/O", __func__, ccb->csio.tag_id); 2932 return; 2933 } 2934 2935 if (IS_24XX(isp)) { 2936 atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid); 2937 } else if (IS_FC(isp)) { 2938 atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid); 2939 } else { 2940 atp = isp_find_atpd(isp, tptr, ((ct_entry_t *)arg)->ct_fwhandle); 2941 } 2942 if (atp == NULL) { 2943 /* 2944 * XXX: isp_clear_commands() generates fake CTIO with zero 2945 * ct_rxid value, filling only ct_syshandle. Workaround 2946 * that using tag_id from the CCB, pointed by ct_syshandle. 2947 */ 2948 atp = isp_find_atpd(isp, tptr, ccb->csio.tag_id); 2949 } 2950 if (atp == NULL) { 2951 rls_lun_statep(isp, tptr); 2952 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id); 2953 return; 2954 } 2955 KASSERT((atp->ctcnt > 0), ("ctio count not greater than zero")); 2956 atp->bytes_in_transit -= data_requested; 2957 atp->ctcnt -= 1; 2958 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2959 2960 if (IS_24XX(isp)) { 2961 ct7_entry_t *ct = arg; 2962 2963 if (ct->ct_nphdl == CT7_SRR) { 2964 atp->srr_ccb = ccb; 2965 if (atp->srr_notify_rcvd) 2966 isp_handle_srr_start(isp, tptr, atp); 2967 rls_lun_statep(isp, tptr); 2968 return; 2969 } 2970 if (ct->ct_nphdl == CT_HBA_RESET) { 2971 failure = CAM_UNREC_HBA_ERROR; 2972 } else { 2973 sentstatus = ct->ct_flags & CT7_SENDSTATUS; 2974 ok = (ct->ct_nphdl == CT7_OK); 2975 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; 2976 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { 2977 resid = ct->ct_resid; 2978 moved_data = data_requested - resid; 2979 } 2980 } 2981 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO7[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct), 2982 notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); 2983 } else if (IS_FC(isp)) { 2984 ct2_entry_t *ct = arg; 2985 if (ct->ct_status == CT_SRR) { 2986 atp->srr_ccb = ccb; 2987 if (atp->srr_notify_rcvd) 2988 isp_handle_srr_start(isp, tptr, atp); 2989 rls_lun_statep(isp, tptr); 2990 isp_target_putback_atio(ccb); 2991 return; 2992 } 2993 if (ct->ct_status == CT_HBA_RESET) { 2994 failure = CAM_UNREC_HBA_ERROR; 2995 } else { 2996 sentstatus = ct->ct_flags & CT2_SENDSTATUS; 2997 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 2998 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; 2999 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 3000 resid = ct->ct_resid; 3001 moved_data = data_requested - resid; 3002 } 3003 } 3004 isp_prt(isp, ok? ISP_LOGTDEBUG0 : ISP_LOGWARN, "%s: CTIO2[%x] seq %u nc %d sts 0x%x flg 0x%x sns %d resid %d %s", __func__, ct->ct_rxid, ATPD_GET_SEQNO(ct), 3005 notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); 3006 } else { 3007 ct_entry_t *ct = arg; 3008 3009 if (ct->ct_status == (CT_HBA_RESET & 0xff)) { 3010 failure = CAM_UNREC_HBA_ERROR; 3011 } else { 3012 sentstatus = ct->ct_flags & CT_SENDSTATUS; 3013 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 3014 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; 3015 } 3016 if ((ct->ct_flags & CT_DATAMASK) != CT_NO_DATA) { 3017 resid = ct->ct_resid; 3018 moved_data = data_requested - resid; 3019 } 3020 isp_prt(isp, ISP_LOGTDEBUG0, "%s: CTIO[%x] seq %u nc %d tag %x S_ID 0x%x lun %d sts %x flg %x resid %d %s", __func__, ct->ct_fwhandle, ATPD_GET_SEQNO(ct), 3021 notify_cam, ct->ct_tag_val, ct->ct_iid, ct->ct_lun, ct->ct_status, ct->ct_flags, resid, sentstatus? "FIN" : "MID"); 3022 } 3023 if (ok) { 3024 if (moved_data) { 3025 atp->bytes_xfered += moved_data; 3026 ccb->csio.resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 3027 } 3028 if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) { 3029 ccb->ccb_h.status |= CAM_SENT_SENSE; 3030 } 3031 ccb->ccb_h.status |= CAM_REQ_CMP; 3032 } else { 3033 notify_cam = 1; 3034 if (failure == CAM_UNREC_HBA_ERROR) 3035 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR; 3036 else 3037 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 3038 } 3039 atp->state = ATPD_STATE_PDON; 3040 rls_lun_statep(isp, tptr); 3041 3042 /* 3043 * We never *not* notify CAM when there has been any error (ok == 0), 3044 * so we never need to do an ATIO putback if we're not notifying CAM. 3045 */ 3046 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done (ok=%d nc=%d nowsendstatus=%d ccb ss=%d)", 3047 (sentstatus)? " FINAL " : "MIDTERM ", atp->tag, ok, notify_cam, atp->sendst, (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0); 3048 if (notify_cam == 0) { 3049 if (atp->sendst) { 3050 isp_target_start_ctio(isp, ccb, FROM_CTIO_DONE); 3051 } 3052 return; 3053 } 3054 3055 /* 3056 * We're telling CAM we're done with this CTIO transaction. 3057 * 3058 * 24XX cards never need an ATIO put back. 3059 * 3060 * Other cards need one put back only on error. 3061 * In the latter case, a timeout will re-fire 3062 * and try again in case we didn't have 3063 * queue resources to do so at first. In any case, 3064 * once the putback is done we do the completion 3065 * call. 3066 */ 3067 if (ok || IS_24XX(isp)) { 3068 isp_complete_ctio(ccb); 3069 } else { 3070 isp_target_putback_atio(ccb); 3071 } 3072 } 3073 3074 static void 3075 isp_handle_platform_notify_scsi(ispsoftc_t *isp, in_entry_t *inot) 3076 { 3077 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 3078 } 3079 3080 static void 3081 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp) 3082 { 3083 int needack = 1; 3084 switch (inp->in_status) { 3085 case IN_PORT_LOGOUT: 3086 /* 3087 * XXX: Need to delete this initiator's WWN from the database 3088 * XXX: Need to send this LOGOUT upstream 3089 */ 3090 isp_prt(isp, ISP_LOGWARN, "port logout of S_ID 0x%x", inp->in_iid); 3091 break; 3092 case IN_PORT_CHANGED: 3093 isp_prt(isp, ISP_LOGWARN, "port changed for S_ID 0x%x", inp->in_iid); 3094 break; 3095 case IN_GLOBAL_LOGO: 3096 isp_del_all_wwn_entries(isp, 0); 3097 isp_prt(isp, ISP_LOGINFO, "all ports logged out"); 3098 break; 3099 case IN_ABORT_TASK: 3100 { 3101 tstate_t *tptr; 3102 uint16_t lun; 3103 uint32_t loopid; 3104 uint64_t wwn; 3105 atio_private_data_t *atp; 3106 fcportdb_t *lp; 3107 struct ccb_immediate_notify *inot = NULL; 3108 3109 if (ISP_CAP_SCCFW(isp)) { 3110 lun = inp->in_scclun; 3111 } else { 3112 lun = inp->in_lun; 3113 } 3114 if (ISP_CAP_2KLOGIN(isp)) { 3115 loopid = ((in_fcentry_e_t *)inp)->in_iid; 3116 } else { 3117 loopid = inp->in_iid; 3118 } 3119 if (isp_find_pdb_by_loopid(isp, 0, loopid, &lp)) { 3120 wwn = lp->port_wwn; 3121 } else { 3122 wwn = INI_ANY; 3123 } 3124 tptr = get_lun_statep(isp, 0, lun); 3125 if (tptr == NULL) { 3126 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 3127 if (tptr == NULL) { 3128 isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %u- but no tstate", lun); 3129 return; 3130 } 3131 } 3132 atp = isp_find_atpd(isp, tptr, inp->in_seqid); 3133 3134 if (atp) { 3135 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots); 3136 isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx state %d", inp->in_seqid, (unsigned long long) wwn, atp->state); 3137 if (inot) { 3138 tptr->inot_count--; 3139 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 3140 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count); 3141 } else { 3142 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "out of INOT structures\n"); 3143 } 3144 } else { 3145 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "abort task RX_ID %x from wwn 0x%016llx, state unknown\n", inp->in_seqid, wwn); 3146 } 3147 if (inot) { 3148 isp_notify_t tmp, *nt = &tmp; 3149 ISP_MEMZERO(nt, sizeof (isp_notify_t)); 3150 nt->nt_hba = isp; 3151 nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn; 3152 nt->nt_wwn = wwn; 3153 nt->nt_nphdl = loopid; 3154 nt->nt_sid = PORT_ANY; 3155 nt->nt_did = PORT_ANY; 3156 nt->nt_lun = lun; 3157 nt->nt_need_ack = 1; 3158 nt->nt_channel = 0; 3159 nt->nt_ncode = NT_ABORT_TASK; 3160 nt->nt_lreserved = inot; 3161 isp_handle_platform_target_tmf(isp, nt); 3162 needack = 0; 3163 } 3164 rls_lun_statep(isp, tptr); 3165 break; 3166 } 3167 default: 3168 break; 3169 } 3170 if (needack) { 3171 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); 3172 } 3173 } 3174 3175 static void 3176 isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) 3177 { 3178 uint16_t nphdl; 3179 uint16_t prli_options = 0; 3180 uint32_t portid; 3181 fcportdb_t *lp; 3182 uint8_t *ptr = NULL; 3183 uint64_t wwn; 3184 3185 nphdl = inot->in_nphdl; 3186 if (nphdl != NIL_HANDLE) { 3187 portid = inot->in_portid_hi << 16 | inot->in_portid_lo; 3188 } else { 3189 portid = PORT_ANY; 3190 } 3191 3192 switch (inot->in_status) { 3193 case IN24XX_ELS_RCVD: 3194 { 3195 char buf[16], *msg; 3196 int chan = ISP_GET_VPIDX(isp, inot->in_vpidx); 3197 3198 /* 3199 * Note that we're just getting notification that an ELS was received 3200 * (possibly with some associated information sent upstream). This is 3201 * *not* the same as being given the ELS frame to accept or reject. 3202 */ 3203 switch (inot->in_status_subcode) { 3204 case LOGO: 3205 msg = "LOGO"; 3206 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { 3207 ptr = (uint8_t *)inot; /* point to unswizzled entry! */ 3208 wwn = (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF]) << 56) | 3209 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+1]) << 48) | 3210 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+2]) << 40) | 3211 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+3]) << 32) | 3212 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+4]) << 24) | 3213 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+5]) << 16) | 3214 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+6]) << 8) | 3215 (((uint64_t) ptr[IN24XX_LOGO_WWPN_OFF+7])); 3216 } else { 3217 wwn = INI_ANY; 3218 } 3219 isp_del_wwn_entry(isp, chan, wwn, nphdl, portid); 3220 break; 3221 case PRLO: 3222 msg = "PRLO"; 3223 break; 3224 case PLOGI: 3225 case PRLI: 3226 /* 3227 * Treat PRLI the same as PLOGI and make a database entry for it. 3228 */ 3229 if (inot->in_status_subcode == PLOGI) { 3230 msg = "PLOGI"; 3231 } else { 3232 prli_options = inot->in_prli_options; 3233 msg = "PRLI"; 3234 } 3235 if (ISP_FW_NEWER_THAN(isp, 4, 0, 25)) { 3236 ptr = (uint8_t *)inot; /* point to unswizzled entry! */ 3237 wwn = (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF]) << 56) | 3238 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+1]) << 48) | 3239 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+2]) << 40) | 3240 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+3]) << 32) | 3241 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+4]) << 24) | 3242 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+5]) << 16) | 3243 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+6]) << 8) | 3244 (((uint64_t) ptr[IN24XX_PLOGI_WWPN_OFF+7])); 3245 } else { 3246 wwn = INI_NONE; 3247 } 3248 isp_add_wwn_entry(isp, chan, wwn, nphdl, portid, prli_options); 3249 break; 3250 case PDISC: 3251 msg = "PDISC"; 3252 break; 3253 case ADISC: 3254 msg = "ADISC"; 3255 break; 3256 default: 3257 ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode); 3258 msg = buf; 3259 break; 3260 } 3261 if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) { 3262 isp_prt(isp, ISP_LOGERR, "%s Chan %d ELS N-port handle %x PortID 0x%06x marked as needing a PUREX response", msg, chan, nphdl, portid); 3263 break; 3264 } 3265 isp_prt(isp, ISP_LOGTDEBUG0, "%s Chan %d ELS N-port handle %x PortID 0x%06x RX_ID 0x%x OX_ID 0x%x", msg, chan, nphdl, portid, 3266 inot->in_rxid, inot->in_oxid); 3267 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 3268 break; 3269 } 3270 3271 case IN24XX_PORT_LOGOUT: 3272 ptr = "PORT LOGOUT"; 3273 if (isp_find_pdb_by_loopid(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) { 3274 isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid); 3275 } 3276 /* FALLTHROUGH */ 3277 case IN24XX_PORT_CHANGED: 3278 if (ptr == NULL) { 3279 ptr = "PORT CHANGED"; 3280 } 3281 /* FALLTHROUGH */ 3282 case IN24XX_LIP_RESET: 3283 if (ptr == NULL) { 3284 ptr = "LIP RESET"; 3285 } 3286 isp_prt(isp, ISP_LOGINFO, "Chan %d %s (sub-status 0x%x) for N-port handle 0x%x", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr, inot->in_status_subcode, nphdl); 3287 3288 /* 3289 * All subcodes here are irrelevant. What is relevant 3290 * is that we need to terminate all active commands from 3291 * this initiator (known by N-port handle). 3292 */ 3293 /* XXX IMPLEMENT XXX */ 3294 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 3295 break; 3296 3297 case IN24XX_SRR_RCVD: 3298 #ifdef ISP_TARGET_MODE 3299 isp_handle_srr_notify(isp, inot); 3300 break; 3301 #else 3302 if (ptr == NULL) { 3303 ptr = "SRR RCVD"; 3304 } 3305 /* FALLTHROUGH */ 3306 #endif 3307 case IN24XX_LINK_RESET: 3308 if (ptr == NULL) { 3309 ptr = "LINK RESET"; 3310 } 3311 case IN24XX_LINK_FAILED: 3312 if (ptr == NULL) { 3313 ptr = "LINK FAILED"; 3314 } 3315 default: 3316 isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), ptr); 3317 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 3318 break; 3319 } 3320 } 3321 3322 static int 3323 isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp) 3324 { 3325 3326 if (isp->isp_state != ISP_RUNSTATE) { 3327 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL); 3328 return (0); 3329 } 3330 3331 /* 3332 * This case is for a Task Management Function, which shows up as an ATIO7 entry. 3333 */ 3334 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) { 3335 ct7_entry_t local, *cto = &local; 3336 at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved; 3337 fcportdb_t *lp; 3338 uint32_t sid; 3339 uint16_t nphdl; 3340 3341 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 3342 if (isp_find_pdb_by_sid(isp, mp->nt_channel, sid, &lp)) { 3343 nphdl = lp->handle; 3344 } else { 3345 nphdl = NIL_HANDLE; 3346 } 3347 ISP_MEMZERO(&local, sizeof (local)); 3348 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 3349 cto->ct_header.rqs_entry_count = 1; 3350 cto->ct_nphdl = nphdl; 3351 cto->ct_rxid = aep->at_rxid; 3352 cto->ct_vpidx = mp->nt_channel; 3353 cto->ct_iid_lo = sid; 3354 cto->ct_iid_hi = sid >> 16; 3355 cto->ct_oxid = aep->at_hdr.ox_id; 3356 cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1; 3357 cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT; 3358 return (isp_target_put_entry(isp, &local)); 3359 } 3360 3361 /* 3362 * This case is for a responding to an ABTS frame 3363 */ 3364 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { 3365 3366 /* 3367 * Overload nt_need_ack here to mark whether we've terminated the associated command. 3368 */ 3369 if (mp->nt_need_ack) { 3370 uint8_t storage[QENTRY_LEN]; 3371 ct7_entry_t *cto = (ct7_entry_t *) storage; 3372 abts_t *abts = (abts_t *)mp->nt_lreserved; 3373 3374 ISP_MEMZERO(cto, sizeof (ct7_entry_t)); 3375 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task); 3376 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 3377 cto->ct_header.rqs_entry_count = 1; 3378 cto->ct_nphdl = mp->nt_nphdl; 3379 cto->ct_rxid = abts->abts_rxid_task; 3380 cto->ct_iid_lo = mp->nt_sid; 3381 cto->ct_iid_hi = mp->nt_sid >> 16; 3382 cto->ct_oxid = abts->abts_ox_id; 3383 cto->ct_vpidx = mp->nt_channel; 3384 cto->ct_flags = CT7_NOACK|CT7_TERMINATE; 3385 if (isp_target_put_entry(isp, cto)) { 3386 return (ENOMEM); 3387 } 3388 mp->nt_need_ack = 0; 3389 } 3390 if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) { 3391 return (ENOMEM); 3392 } else { 3393 return (0); 3394 } 3395 } 3396 3397 /* 3398 * Handle logout cases here 3399 */ 3400 if (mp->nt_ncode == NT_GLOBAL_LOGOUT) { 3401 isp_del_all_wwn_entries(isp, mp->nt_channel); 3402 } 3403 3404 if (mp->nt_ncode == NT_LOGOUT) { 3405 if (!IS_2100(isp) && IS_FC(isp)) { 3406 isp_del_wwn_entries(isp, mp); 3407 } 3408 } 3409 3410 /* 3411 * General purpose acknowledgement 3412 */ 3413 if (mp->nt_need_ack) { 3414 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL); 3415 /* 3416 * Don't need to use the guaranteed send because the caller can retry 3417 */ 3418 return (isp_notify_ack(isp, mp->nt_lreserved)); 3419 } 3420 return (0); 3421 } 3422 3423 /* 3424 * Handle task management functions. 3425 * 3426 * We show up here with a notify structure filled out. 3427 * 3428 * The nt_lreserved tag points to the original queue entry 3429 */ 3430 static void 3431 isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify) 3432 { 3433 tstate_t *tptr; 3434 fcportdb_t *lp; 3435 struct ccb_immediate_notify *inot; 3436 inot_private_data_t *ntp = NULL; 3437 lun_id_t lun; 3438 3439 isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun 0x%x", __func__, notify->nt_ncode, 3440 notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun); 3441 /* 3442 * NB: This assignment is necessary because of tricky type conversion. 3443 * XXX: This is tricky and I need to check this. If the lun isn't known 3444 * XXX: for the task management function, it does not of necessity follow 3445 * XXX: that it should go up stream to the wildcard listener. 3446 */ 3447 if (notify->nt_lun == LUN_ANY) { 3448 lun = CAM_LUN_WILDCARD; 3449 } else { 3450 lun = notify->nt_lun; 3451 } 3452 tptr = get_lun_statep(isp, notify->nt_channel, lun); 3453 if (tptr == NULL) { 3454 tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD); 3455 if (tptr == NULL) { 3456 isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun); 3457 goto bad; 3458 } 3459 } 3460 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots); 3461 if (inot == NULL) { 3462 isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun); 3463 goto bad; 3464 } 3465 3466 if (isp_find_pdb_by_sid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0) { 3467 inot->initiator_id = CAM_TARGET_WILDCARD; 3468 } else { 3469 inot->initiator_id = lp->handle; 3470 } 3471 inot->seq_id = notify->nt_tagval; 3472 inot->tag_id = notify->nt_tagval >> 32; 3473 3474 switch (notify->nt_ncode) { 3475 case NT_ABORT_TASK: 3476 isp_target_mark_aborted_early(isp, tptr, inot->tag_id); 3477 inot->arg = MSG_ABORT_TASK; 3478 break; 3479 case NT_ABORT_TASK_SET: 3480 isp_target_mark_aborted_early(isp, tptr, TAG_ANY); 3481 inot->arg = MSG_ABORT_TASK_SET; 3482 break; 3483 case NT_CLEAR_ACA: 3484 inot->arg = MSG_CLEAR_ACA; 3485 break; 3486 case NT_CLEAR_TASK_SET: 3487 inot->arg = MSG_CLEAR_TASK_SET; 3488 break; 3489 case NT_LUN_RESET: 3490 inot->arg = MSG_LOGICAL_UNIT_RESET; 3491 break; 3492 case NT_TARGET_RESET: 3493 inot->arg = MSG_TARGET_RESET; 3494 break; 3495 default: 3496 isp_prt(isp, ISP_LOGWARN, "%s: unknown TMF code 0x%x for chan %d lun %#jx", __func__, notify->nt_ncode, notify->nt_channel, (uintmax_t)lun); 3497 goto bad; 3498 } 3499 3500 ntp = isp_get_ntpd(isp, tptr); 3501 if (ntp == NULL) { 3502 isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__); 3503 goto bad; 3504 } 3505 ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t)); 3506 if (notify->nt_lreserved) { 3507 ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN); 3508 ntp->rd.nt.nt_lreserved = &ntp->rd.data; 3509 } 3510 ntp->rd.seq_id = notify->nt_tagval; 3511 ntp->rd.tag_id = notify->nt_tagval >> 32; 3512 3513 tptr->inot_count--; 3514 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 3515 rls_lun_statep(isp, tptr); 3516 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count); 3517 inot->ccb_h.status = CAM_MESSAGE_RECV; 3518 xpt_done((union ccb *)inot); 3519 return; 3520 bad: 3521 if (tptr) { 3522 rls_lun_statep(isp, tptr); 3523 } 3524 if (notify->nt_need_ack && notify->nt_lreserved) { 3525 if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { 3526 if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) { 3527 isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK"); 3528 } 3529 } else { 3530 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, notify->nt_lreserved); 3531 } 3532 } 3533 } 3534 3535 /* 3536 * Find the associated private data and mark it as dead so 3537 * we don't try to work on it any further. 3538 */ 3539 static void 3540 isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb) 3541 { 3542 tstate_t *tptr; 3543 atio_private_data_t *atp; 3544 union ccb *accb = ccb->cab.abort_ccb; 3545 3546 tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb)); 3547 if (tptr == NULL) { 3548 tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD); 3549 if (tptr == NULL) { 3550 ccb->ccb_h.status = CAM_REQ_INVALID; 3551 return; 3552 } 3553 } 3554 3555 atp = isp_find_atpd(isp, tptr, accb->atio.tag_id); 3556 if (atp == NULL) { 3557 ccb->ccb_h.status = CAM_REQ_INVALID; 3558 } else { 3559 atp->dead = 1; 3560 ccb->ccb_h.status = CAM_REQ_CMP; 3561 } 3562 rls_lun_statep(isp, tptr); 3563 } 3564 3565 static void 3566 isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id) 3567 { 3568 atio_private_data_t *atp; 3569 inot_private_data_t *restart_queue = tptr->restart_queue; 3570 3571 /* 3572 * First, clean any commands pending restart 3573 */ 3574 tptr->restart_queue = NULL; 3575 while (restart_queue) { 3576 uint32_t this_tag_id; 3577 inot_private_data_t *ntp = restart_queue; 3578 3579 restart_queue = ntp->rd.nt.nt_hba; 3580 3581 if (IS_24XX(isp)) { 3582 this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid; 3583 } else { 3584 this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid; 3585 } 3586 if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) { 3587 isp_put_ntpd(isp, tptr, ntp); 3588 } else { 3589 ntp->rd.nt.nt_hba = tptr->restart_queue; 3590 tptr->restart_queue = ntp; 3591 } 3592 } 3593 3594 /* 3595 * Now mark other ones dead as well. 3596 */ 3597 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) { 3598 if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) { 3599 atp->dead = 1; 3600 } 3601 } 3602 } 3603 3604 3605 #ifdef ISP_INTERNAL_TARGET 3606 //#define ISP_SEPARATE_STATUS 1 3607 #define ISP_MULTI_CCBS 1 3608 #if defined(ISP_MULTI_CCBS) && !defined(ISP_SEPARATE_STATUS) 3609 #define ISP_SEPARATE_STATUS 1 3610 #endif 3611 3612 typedef struct periph_private_data_t { 3613 union ccb *ccb; /* original ATIO or Immediate Notify */ 3614 unsigned long offset; /* current offset */ 3615 int sequence; /* current CTIO sequence */ 3616 int ctio_cnt; /* current # of ctio's outstanding */ 3617 int 3618 status_sent : 1, 3619 on_queue : 1; /* on restart queue */ 3620 } ppd_t; 3621 /* 3622 * Each ATIO we allocate will have periph private data associated with it 3623 * that maintains per-command state. This private to each ATIO. 3624 */ 3625 #define ATIO_PPD(ccb) ((ppd_t *)(((struct ccb_hdr *)ccb)->ppriv_ptr0)) 3626 /* 3627 * Each CTIO we send downstream will get a pointer to the ATIO itself 3628 * so that on completion we can retrieve that pointer. 3629 */ 3630 #define ccb_atio ppriv_ptr1 3631 #define ccb_inot ppriv_ptr1 3632 3633 /* 3634 * Each CTIO we send downstream will contain a sequence number 3635 */ 3636 #define CTIO_SEQ(ccb) ccb->ccb_h.ppriv_field0 3637 3638 #define MAX_ISP_TARG_TRANSFER (2 << 20) 3639 #define NISP_TARG_CMDS 64 3640 #define NISP_TARG_NOTIFIES 64 3641 #define DISK_SHIFT 9 3642 #define JUNK_SIZE 256 3643 #define MULTI_CCB_DATA_LIM 8192 3644 //#define MULTI_CCB_DATA_CNT 64 3645 #define MULTI_CCB_DATA_CNT 8 3646 3647 extern u_int vm_kmem_size; 3648 static int ca; 3649 static uint32_t disk_size; 3650 static uint8_t *disk_data = NULL; 3651 static uint8_t *junk_data; 3652 static MALLOC_DEFINE(M_ISPTARG, "ISPTARG", "ISP TARGET data"); 3653 struct isptarg_softc { 3654 /* CCBs (CTIOs, ATIOs, INOTs) pending on the controller */ 3655 struct isp_ccbq work_queue; 3656 struct isp_ccbq rework_queue; 3657 struct isp_ccbq running_queue; 3658 struct isp_ccbq inot_queue; 3659 struct cam_periph *periph; 3660 struct cam_path *path; 3661 ispsoftc_t *isp; 3662 }; 3663 static periph_ctor_t isptargctor; 3664 static periph_dtor_t isptargdtor; 3665 static periph_start_t isptargstart; 3666 static periph_init_t isptarginit; 3667 static void isptarg_done(struct cam_periph *, union ccb *); 3668 static void isptargasync(void *, u_int32_t, struct cam_path *, void *); 3669 3670 3671 static int isptarg_rwparm(uint8_t *, uint8_t *, uint64_t, uint32_t, uint8_t **, uint32_t *, int *); 3672 3673 static struct periph_driver isptargdriver = 3674 { 3675 isptarginit, "isptarg", TAILQ_HEAD_INITIALIZER(isptargdriver.units), 0 3676 }; 3677 3678 static void 3679 isptarginit(void) 3680 { 3681 } 3682 3683 static void 3684 isptargnotify(ispsoftc_t *isp, union ccb *iccb, struct ccb_immediate_notify *inot) 3685 { 3686 struct ccb_notify_acknowledge *ack = &iccb->cna2; 3687 3688 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, inot->ccb_h.path, "%s: [0x%x] immediate notify for 0x%x from 0x%x status 0x%x arg 0x%x\n", __func__, 3689 inot->tag_id, inot->initiator_id, inot->seq_id, inot->ccb_h.status, inot->arg); 3690 ack->ccb_h.func_code = XPT_NOTIFY_ACKNOWLEDGE; 3691 ack->ccb_h.flags = 0; 3692 ack->ccb_h.retry_count = 0; 3693 ack->ccb_h.cbfcnp = isptarg_done; 3694 ack->ccb_h.timeout = 0; 3695 ack->ccb_h.ccb_inot = inot; 3696 ack->tag_id = inot->tag_id; 3697 ack->seq_id = inot->seq_id; 3698 ack->initiator_id = inot->initiator_id; 3699 xpt_action(iccb); 3700 } 3701 3702 static void 3703 isptargstart(struct cam_periph *periph, union ccb *iccb) 3704 { 3705 const uint8_t niliqd[SHORT_INQUIRY_LENGTH] = { 3706 0x7f, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, 3707 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ', 3708 'S', 'C', 'S', 'I', ' ', 'N', 'U', 'L', 3709 'L', ' ', 'D', 'E', 'V', 'I', 'C', 'E', 3710 '0', '0', '0', '1' 3711 }; 3712 const uint8_t iqd[SHORT_INQUIRY_LENGTH] = { 3713 0, 0x0, 0x5, 0x2, 32, 0, 0, 0x32, 3714 'F', 'R', 'E', 'E', 'B', 'S', 'D', ' ', 3715 'S', 'C', 'S', 'I', ' ', 'M', 'E', 'M', 3716 'O', 'R', 'Y', ' ', 'D', 'I', 'S', 'K', 3717 '0', '0', '0', '1' 3718 }; 3719 int r, i, more = 0, last, is_data_cmd = 0, is_write; 3720 char *queue; 3721 struct isptarg_softc *softc = periph->softc; 3722 struct ccb_scsiio *csio; 3723 lun_id_t return_lun; 3724 struct ccb_accept_tio *atio; 3725 uint8_t *cdb, *ptr, status; 3726 uint8_t *data_ptr; 3727 uint32_t data_len, flags; 3728 struct ccb_hdr *ccbh; 3729 3730 mtx_assert(periph->sim->mtx, MA_OWNED); 3731 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, iccb->ccb_h.path, "%s: function code 0x%x INOTQ=%c WORKQ=%c REWORKQ=%c\n", __func__, iccb->ccb_h.func_code, 3732 TAILQ_FIRST(&softc->inot_queue)? 'y' : 'n', TAILQ_FIRST(&softc->work_queue)? 'y' : 'n', TAILQ_FIRST(&softc->rework_queue)? 'y' : 'n'); 3733 /* 3734 * Check for immediate notifies first 3735 */ 3736 ccbh = TAILQ_FIRST(&softc->inot_queue); 3737 if (ccbh) { 3738 TAILQ_REMOVE(&softc->inot_queue, ccbh, periph_links.tqe); 3739 if (TAILQ_FIRST(&softc->inot_queue) || TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue)) { 3740 xpt_schedule(periph, 1); 3741 } 3742 isptargnotify(softc->isp, iccb, (struct ccb_immediate_notify *)ccbh); 3743 return; 3744 } 3745 3746 /* 3747 * Check the rework (continuation) work queue first. 3748 */ 3749 ccbh = TAILQ_FIRST(&softc->rework_queue); 3750 if (ccbh) { 3751 atio = (struct ccb_accept_tio *)ccbh; 3752 TAILQ_REMOVE(&softc->rework_queue, ccbh, periph_links.tqe); 3753 more = TAILQ_FIRST(&softc->work_queue) || TAILQ_FIRST(&softc->rework_queue); 3754 queue = "rework"; 3755 } else { 3756 ccbh = TAILQ_FIRST(&softc->work_queue); 3757 if (ccbh == NULL) { 3758 xpt_release_ccb(iccb); 3759 return; 3760 } 3761 atio = (struct ccb_accept_tio *)ccbh; 3762 TAILQ_REMOVE(&softc->work_queue, ccbh, periph_links.tqe); 3763 more = TAILQ_FIRST(&softc->work_queue) != NULL; 3764 queue = "work"; 3765 } 3766 ATIO_PPD(atio)->on_queue = 0; 3767 3768 if (atio->tag_id == 0xffffffff || atio->ccb_h.func_code != XPT_ACCEPT_TARGET_IO) { 3769 panic("BAD ATIO"); 3770 } 3771 3772 data_len = is_write = 0; 3773 data_ptr = NULL; 3774 csio = &iccb->csio; 3775 status = SCSI_STATUS_OK; 3776 flags = CAM_SEND_STATUS; 3777 memset(&atio->sense_data, 0, sizeof (atio->sense_data)); 3778 cdb = atio->cdb_io.cdb_bytes; 3779 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, ccbh->path, "%s: [0x%x] processing ATIO from %s queue initiator 0x%x CDB=0x%x data_offset=%u\n", __func__, atio->tag_id, 3780 queue, atio->init_id, cdb[0], ATIO_PPD(atio)->offset); 3781 3782 return_lun = XS_LUN(atio); 3783 if (return_lun != 0) { 3784 xpt_print(atio->ccb_h.path, "[0x%x] Non-Zero Lun %d: cdb0=0x%x\n", atio->tag_id, return_lun, cdb[0]); 3785 if (cdb[0] != INQUIRY && cdb[0] != REPORT_LUNS && cdb[0] != REQUEST_SENSE) { 3786 status = SCSI_STATUS_CHECK_COND; 3787 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3788 SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; 3789 SDFIXED(atio->sense_data)->add_sense_code = 0x25; /* LOGICAL UNIT NOT SUPPORTED */ 3790 atio->sense_len = SSD_MIN_SIZE; 3791 } 3792 return_lun = CAM_LUN_WILDCARD; 3793 } 3794 3795 switch (cdb[0]) { 3796 case REQUEST_SENSE: 3797 flags |= CAM_DIR_IN; 3798 data_len = sizeof (atio->sense_data); 3799 junk_data[0] = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR|SSD_KEY_NO_SENSE; 3800 memset(junk_data+1, 0, data_len-1); 3801 if (data_len > cdb[4]) { 3802 data_len = cdb[4]; 3803 } 3804 if (data_len) { 3805 data_ptr = junk_data; 3806 } 3807 break; 3808 case WRITE_6: 3809 case WRITE_10: 3810 case WRITE_12: 3811 case WRITE_16: 3812 is_write = 1; 3813 /* FALLTHROUGH */ 3814 case READ_6: 3815 case READ_10: 3816 case READ_12: 3817 case READ_16: 3818 is_data_cmd = 1; 3819 r = isptarg_rwparm(cdb, disk_data, disk_size, ATIO_PPD(atio)->offset, &data_ptr, &data_len, &last); 3820 if (r != 0) { 3821 status = SCSI_STATUS_CHECK_COND; 3822 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3823 SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; 3824 if (r == -1) { 3825 SDFIXED(atio->sense_data)->add_sense_code = 0x21; /* LOGICAL BLOCK ADDRESS OUT OF RANGE */ 3826 } else { 3827 SDFIXED(atio->sense_data)->add_sense_code = 0x20; /* INVALID COMMAND OPERATION CODE */ 3828 } 3829 atio->sense_len = SSD_MIN_SIZE; 3830 } else { 3831 #ifdef ISP_SEPARATE_STATUS 3832 if (last && data_len) { 3833 last = 0; 3834 } 3835 #endif 3836 if (last == 0) { 3837 flags &= ~CAM_SEND_STATUS; 3838 } 3839 if (data_len) { 3840 ATIO_PPD(atio)->offset += data_len; 3841 if (is_write) 3842 flags |= CAM_DIR_OUT; 3843 else 3844 flags |= CAM_DIR_IN; 3845 } else { 3846 flags |= CAM_DIR_NONE; 3847 } 3848 } 3849 break; 3850 case INQUIRY: 3851 flags |= CAM_DIR_IN; 3852 if (cdb[1] || cdb[2] || cdb[3]) { 3853 status = SCSI_STATUS_CHECK_COND; 3854 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3855 SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION; 3856 SDFIXED(atio->sense_data)->add_sense_code = 0x24; /* INVALID FIELD IN CDB */ 3857 atio->sense_len = SSD_MIN_SIZE; 3858 break; 3859 } 3860 data_len = sizeof (iqd); 3861 if (data_len > cdb[4]) { 3862 data_len = cdb[4]; 3863 } 3864 if (data_len) { 3865 if (XS_LUN(iccb) != 0) { 3866 memcpy(junk_data, niliqd, sizeof (iqd)); 3867 } else { 3868 memcpy(junk_data, iqd, sizeof (iqd)); 3869 } 3870 data_ptr = junk_data; 3871 } 3872 break; 3873 case TEST_UNIT_READY: 3874 flags |= CAM_DIR_NONE; 3875 if (ca) { 3876 ca = 0; 3877 status = SCSI_STATUS_CHECK_COND; 3878 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3879 SDFIXED(atio->sense_data)->flags = SSD_KEY_UNIT_ATTENTION; 3880 SDFIXED(atio->sense_data)->add_sense_code = 0x29; /* POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */ 3881 atio->sense_len = SSD_MIN_SIZE; 3882 } 3883 break; 3884 case SYNCHRONIZE_CACHE: 3885 case START_STOP: 3886 case RESERVE: 3887 case RELEASE: 3888 case VERIFY_10: 3889 flags |= CAM_DIR_NONE; 3890 break; 3891 3892 case READ_CAPACITY: 3893 flags |= CAM_DIR_IN; 3894 if (cdb[2] || cdb[3] || cdb[4] || cdb[5]) { 3895 status = SCSI_STATUS_CHECK_COND; 3896 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3897 SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; 3898 SDFIXED(atio->sense_data)->add_sense_code = 0x24; /* INVALID FIELD IN CDB */ 3899 atio->sense_len = SSD_MIN_SIZE; 3900 break; 3901 } 3902 if (cdb[8] & 0x1) { /* PMI */ 3903 junk_data[0] = 0xff; 3904 junk_data[1] = 0xff; 3905 junk_data[2] = 0xff; 3906 junk_data[3] = 0xff; 3907 } else { 3908 uint64_t last_blk = (disk_size >> DISK_SHIFT) - 1; 3909 if (last_blk < 0xffffffffULL) { 3910 junk_data[0] = (last_blk >> 24) & 0xff; 3911 junk_data[1] = (last_blk >> 16) & 0xff; 3912 junk_data[2] = (last_blk >> 8) & 0xff; 3913 junk_data[3] = (last_blk) & 0xff; 3914 } else { 3915 junk_data[0] = 0xff; 3916 junk_data[1] = 0xff; 3917 junk_data[2] = 0xff; 3918 junk_data[3] = 0xff; 3919 } 3920 } 3921 junk_data[4] = ((1 << DISK_SHIFT) >> 24) & 0xff; 3922 junk_data[5] = ((1 << DISK_SHIFT) >> 16) & 0xff; 3923 junk_data[6] = ((1 << DISK_SHIFT) >> 8) & 0xff; 3924 junk_data[7] = ((1 << DISK_SHIFT)) & 0xff; 3925 data_ptr = junk_data; 3926 data_len = 8; 3927 break; 3928 case REPORT_LUNS: 3929 flags |= CAM_DIR_IN; 3930 memset(junk_data, 0, JUNK_SIZE); 3931 junk_data[0] = (1 << 3) >> 24; 3932 junk_data[1] = (1 << 3) >> 16; 3933 junk_data[2] = (1 << 3) >> 8; 3934 junk_data[3] = (1 << 3); 3935 ptr = NULL; 3936 for (i = 0; i < 1; i++) { 3937 ptr = &junk_data[8 + (i << 3)]; 3938 if (i >= 256) { 3939 ptr[0] = 0x40 | ((i >> 8) & 0x3f); 3940 } 3941 ptr[1] = i; 3942 } 3943 data_ptr = junk_data; 3944 data_len = (ptr + 8) - junk_data; 3945 break; 3946 3947 default: 3948 flags |= CAM_DIR_NONE; 3949 status = SCSI_STATUS_CHECK_COND; 3950 SDFIXED(atio->sense_data)->error_code = SSD_ERRCODE_VALID|SSD_CURRENT_ERROR; 3951 SDFIXED(atio->sense_data)->flags = SSD_KEY_ILLEGAL_REQUEST; 3952 SDFIXED(atio->sense_data)->add_sense_code = 0x20; /* INVALID COMMAND OPERATION CODE */ 3953 atio->sense_len = SSD_MIN_SIZE; 3954 break; 3955 } 3956 3957 /* 3958 * If we are done with the transaction, tell the 3959 * controller to send status and perform a CMD_CMPLT. 3960 * If we have associated sense data, see if we can 3961 * send that too. 3962 */ 3963 if (status == SCSI_STATUS_CHECK_COND) { 3964 flags |= CAM_SEND_SENSE; 3965 csio->sense_len = atio->sense_len; 3966 csio->sense_data = atio->sense_data; 3967 flags &= ~CAM_DIR_MASK; 3968 data_len = 0; 3969 data_ptr = NULL; 3970 } 3971 cam_fill_ctio(csio, 0, isptarg_done, flags, MSG_SIMPLE_Q_TAG, atio->tag_id, atio->init_id, status, data_ptr, data_len, 30 * hz); 3972 iccb->ccb_h.target_id = atio->ccb_h.target_id; 3973 iccb->ccb_h.target_lun = return_lun; 3974 iccb->ccb_h.ccb_atio = atio; 3975 CTIO_SEQ(iccb) = ATIO_PPD(atio)->sequence++; 3976 ATIO_PPD(atio)->ctio_cnt++; 3977 if (flags & CAM_SEND_STATUS) { 3978 KASSERT((ATIO_PPD(atio)->status_sent == 0), ("we have already sent status for 0x%x in %s", atio->tag_id, __func__)); 3979 ATIO_PPD(atio)->status_sent = 1; 3980 } 3981 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: sending downstream for 0x%x sequence %u len %u flags %x\n", __func__, atio->tag_id, CTIO_SEQ(iccb), data_len, flags); 3982 xpt_action(iccb); 3983 3984 if ((atio->ccb_h.status & CAM_DEV_QFRZN) != 0) { 3985 cam_release_devq(periph->path, 0, 0, 0, 0); 3986 atio->ccb_h.status &= ~CAM_DEV_QFRZN; 3987 } 3988 #ifdef ISP_MULTI_CCBS 3989 if (is_data_cmd && ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->ctio_cnt < MULTI_CCB_DATA_CNT && ATIO_PPD(atio)->on_queue == 0) { 3990 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG0, atio->ccb_h.path, "%s: more still to do for 0x%x\n", __func__, atio->tag_id); 3991 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 3992 ATIO_PPD(atio)->on_queue = 1; 3993 more = 1; 3994 } 3995 #endif 3996 if (more) { 3997 xpt_schedule(periph, 1); 3998 } 3999 } 4000 4001 static cam_status 4002 isptargctor(struct cam_periph *periph, void *arg) 4003 { 4004 struct isptarg_softc *softc; 4005 4006 softc = (struct isptarg_softc *)arg; 4007 periph->softc = softc; 4008 softc->periph = periph; 4009 softc->path = periph->path; 4010 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__); 4011 return (CAM_REQ_CMP); 4012 } 4013 4014 static void 4015 isptargdtor(struct cam_periph *periph) 4016 { 4017 struct isptarg_softc *softc; 4018 softc = (struct isptarg_softc *)periph->softc; 4019 ISP_PATH_PRT(softc->isp, ISP_LOGTDEBUG1, periph->path, "%s called\n", __func__); 4020 softc->periph = NULL; 4021 softc->path = NULL; 4022 periph->softc = NULL; 4023 } 4024 4025 static void 4026 isptarg_done(struct cam_periph *periph, union ccb *ccb) 4027 { 4028 struct isptarg_softc *softc; 4029 ispsoftc_t *isp; 4030 uint32_t newoff; 4031 struct ccb_accept_tio *atio; 4032 struct ccb_immediate_notify *inot; 4033 cam_status status; 4034 4035 softc = (struct isptarg_softc *)periph->softc; 4036 isp = softc->isp; 4037 status = ccb->ccb_h.status & CAM_STATUS_MASK; 4038 4039 switch (ccb->ccb_h.func_code) { 4040 case XPT_ACCEPT_TARGET_IO: 4041 atio = (struct ccb_accept_tio *) ccb; 4042 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] ATIO seen in %s\n", atio->tag_id, __func__); 4043 memset(ATIO_PPD(atio), 0, sizeof (ppd_t)); 4044 TAILQ_INSERT_TAIL(&softc->work_queue, &ccb->ccb_h, periph_links.tqe); 4045 ATIO_PPD(atio)->on_queue = 1; 4046 xpt_schedule(periph, 1); 4047 break; 4048 case XPT_IMMEDIATE_NOTIFY: 4049 inot = (struct ccb_immediate_notify *) ccb; 4050 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] INOT for 0x%x seen in %s\n", inot->tag_id, inot->seq_id, __func__); 4051 TAILQ_INSERT_TAIL(&softc->inot_queue, &ccb->ccb_h, periph_links.tqe); 4052 xpt_schedule(periph, 1); 4053 break; 4054 case XPT_CONT_TARGET_IO: 4055 atio = ccb->ccb_h.ccb_atio; 4056 KASSERT((ATIO_PPD(atio)->ctio_cnt != 0), ("ctio zero when finishing a CTIO")); 4057 ATIO_PPD(atio)->ctio_cnt--; 4058 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4059 switch (ccb->ccb_h.status & CAM_STATUS_MASK) { 4060 case CAM_MESSAGE_RECV: 4061 newoff = (ccb->csio.msg_ptr[3] << 24) | (ccb->csio.msg_ptr[4] << 16) | (ccb->csio.msg_ptr[5] << 8) | (ccb->csio.msg_ptr[6]); 4062 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "[0x%x] got message to return to reset offset to 0x%x at sequence %u\n", atio->tag_id, newoff, CTIO_SEQ(ccb)); 4063 ATIO_PPD(atio)->offset = newoff; 4064 ATIO_PPD(atio)->status_sent = 0; 4065 if (ATIO_PPD(atio)->on_queue == 0) { 4066 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 4067 ATIO_PPD(atio)->on_queue = 1; 4068 } 4069 xpt_schedule(periph, 1); 4070 break; 4071 default: 4072 cam_error_print(ccb, CAM_ESF_ALL, CAM_EPF_ALL); 4073 xpt_action((union ccb *)atio); 4074 break; 4075 } 4076 } else if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) { 4077 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] MID CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__); 4078 if (ATIO_PPD(atio)->status_sent == 0 && ATIO_PPD(atio)->on_queue == 0) { 4079 TAILQ_INSERT_TAIL(&softc->rework_queue, &atio->ccb_h, periph_links.tqe); 4080 ATIO_PPD(atio)->on_queue = 1; 4081 } 4082 xpt_schedule(periph, 1); 4083 } else { 4084 KASSERT((ATIO_PPD(atio)->ctio_cnt == 0), ("ctio count still %d when we think we've sent the STATUS ctio", ATIO_PPD(atio)->ctio_cnt)); 4085 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "[0x%x] FINAL CTIO sequence %u seen in %s\n", atio->tag_id, CTIO_SEQ(ccb), __func__); 4086 xpt_action((union ccb *)atio); 4087 } 4088 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { 4089 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 4090 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; 4091 } 4092 xpt_release_ccb(ccb); 4093 break; 4094 case XPT_NOTIFY_ACKNOWLEDGE: 4095 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) { 4096 cam_release_devq(ccb->ccb_h.path, 0, 0, 0, 0); 4097 ccb->ccb_h.status &= ~CAM_DEV_QFRZN; 4098 } 4099 inot = ccb->ccb_h.ccb_inot; 4100 ISP_PATH_PRT(isp, ISP_LOGTDEBUG1, inot->ccb_h.path, "[0x%x] recycle notify for tag 0x%x\n", inot->tag_id, inot->seq_id); 4101 xpt_release_ccb(ccb); 4102 xpt_action((union ccb *)inot); 4103 break; 4104 default: 4105 xpt_print(ccb->ccb_h.path, "unexpected code 0x%x\n", ccb->ccb_h.func_code); 4106 break; 4107 } 4108 } 4109 4110 static void 4111 isptargasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) 4112 { 4113 struct ac_contract *acp = arg; 4114 struct ac_device_changed *fc = (struct ac_device_changed *) acp->contract_data; 4115 4116 if (code != AC_CONTRACT) { 4117 return; 4118 } 4119 xpt_print(path, "0x%016llx Port ID 0x%06x %s\n", (unsigned long long) fc->wwpn, fc->port, fc->arrived? "arrived" : "departed"); 4120 } 4121 4122 static void 4123 isp_target_thread(ispsoftc_t *isp, int chan) 4124 { 4125 union ccb *ccb = NULL; 4126 int i; 4127 void *wchan; 4128 cam_status status; 4129 struct isptarg_softc *softc = NULL; 4130 struct cam_periph *periph = NULL, *wperiph = NULL; 4131 struct cam_path *path, *wpath; 4132 struct cam_sim *sim; 4133 4134 if (disk_data == NULL) { 4135 disk_size = roundup2(vm_kmem_size >> 1, (1ULL << 20)); 4136 if (disk_size < (50 << 20)) { 4137 disk_size = 50 << 20; 4138 } 4139 disk_data = malloc(disk_size, M_ISPTARG, M_WAITOK | M_ZERO); 4140 if (disk_data == NULL) { 4141 isp_prt(isp, ISP_LOGERR, "%s: could not allocate disk data", __func__); 4142 goto out; 4143 } 4144 isp_prt(isp, ISP_LOGINFO, "allocated a %ju MiB disk", (uintmax_t) (disk_size >> 20)); 4145 } 4146 junk_data = malloc(JUNK_SIZE, M_ISPTARG, M_WAITOK | M_ZERO); 4147 if (junk_data == NULL) { 4148 isp_prt(isp, ISP_LOGERR, "%s: could not allocate junk", __func__); 4149 goto out; 4150 } 4151 4152 4153 softc = malloc(sizeof (*softc), M_ISPTARG, M_WAITOK | M_ZERO); 4154 if (softc == NULL) { 4155 isp_prt(isp, ISP_LOGERR, "%s: could not allocate softc", __func__); 4156 goto out; 4157 } 4158 TAILQ_INIT(&softc->work_queue); 4159 TAILQ_INIT(&softc->rework_queue); 4160 TAILQ_INIT(&softc->running_queue); 4161 TAILQ_INIT(&softc->inot_queue); 4162 softc->isp = isp; 4163 4164 periphdriver_register(&isptargdriver); 4165 ISP_GET_PC(isp, chan, sim, sim); 4166 ISP_GET_PC(isp, chan, path, path); 4167 status = xpt_create_path(&wpath, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); 4168 if (status != CAM_REQ_CMP) { 4169 isp_prt(isp, ISP_LOGERR, "%s: could not allocate wildcard path", __func__); 4170 return; 4171 } 4172 status = xpt_create_path(&path, NULL, cam_sim_path(sim), 0, 0); 4173 if (status != CAM_REQ_CMP) { 4174 xpt_free_path(wpath); 4175 isp_prt(isp, ISP_LOGERR, "%s: could not allocate path", __func__); 4176 return; 4177 } 4178 4179 ISP_LOCK(isp); 4180 status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, wpath, NULL, 0, softc); 4181 if (status != CAM_REQ_CMP) { 4182 ISP_UNLOCK(isp); 4183 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc for wildcard failed", __func__); 4184 goto out; 4185 } 4186 wperiph = cam_periph_find(wpath, "isptarg"); 4187 if (wperiph == NULL) { 4188 ISP_UNLOCK(isp); 4189 isp_prt(isp, ISP_LOGERR, "%s: wildcard periph already allocated but doesn't exist", __func__); 4190 goto out; 4191 } 4192 4193 status = cam_periph_alloc(isptargctor, NULL, isptargdtor, isptargstart, "isptarg", CAM_PERIPH_BIO, path, NULL, 0, softc); 4194 if (status != CAM_REQ_CMP) { 4195 ISP_UNLOCK(isp); 4196 isp_prt(isp, ISP_LOGERR, "%s: cam_periph_alloc failed", __func__); 4197 goto out; 4198 } 4199 4200 periph = cam_periph_find(path, "isptarg"); 4201 if (periph == NULL) { 4202 ISP_UNLOCK(isp); 4203 isp_prt(isp, ISP_LOGERR, "%s: periph already allocated but doesn't exist", __func__); 4204 goto out; 4205 } 4206 4207 status = xpt_register_async(AC_CONTRACT, isptargasync, isp, wpath); 4208 if (status != CAM_REQ_CMP) { 4209 ISP_UNLOCK(isp); 4210 isp_prt(isp, ISP_LOGERR, "%s: xpt_register_async failed", __func__); 4211 goto out; 4212 } 4213 4214 ISP_UNLOCK(isp); 4215 4216 ccb = xpt_alloc_ccb(); 4217 4218 /* 4219 * Make sure role is none. 4220 */ 4221 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); 4222 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; 4223 ccb->knob.xport_specific.fc.role = KNOB_ROLE_NONE; 4224 ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE; 4225 4226 ISP_LOCK(isp); 4227 xpt_action(ccb); 4228 ISP_UNLOCK(isp); 4229 4230 /* 4231 * Now enable luns 4232 */ 4233 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); 4234 ccb->ccb_h.func_code = XPT_EN_LUN; 4235 ccb->cel.enable = 1; 4236 ISP_LOCK(isp); 4237 xpt_action(ccb); 4238 ISP_UNLOCK(isp); 4239 if (ccb->ccb_h.status != CAM_REQ_CMP) { 4240 xpt_free_ccb(ccb); 4241 xpt_print(periph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status); 4242 goto out; 4243 } 4244 4245 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 10); 4246 ccb->ccb_h.func_code = XPT_EN_LUN; 4247 ccb->cel.enable = 1; 4248 ISP_LOCK(isp); 4249 xpt_action(ccb); 4250 ISP_UNLOCK(isp); 4251 if (ccb->ccb_h.status != CAM_REQ_CMP) { 4252 xpt_free_ccb(ccb); 4253 xpt_print(wperiph->path, "failed to enable lun (0x%x)\n", ccb->ccb_h.status); 4254 goto out; 4255 } 4256 xpt_free_ccb(ccb); 4257 4258 /* 4259 * Add resources 4260 */ 4261 ISP_GET_PC(isp, chan, target_proc, wchan); 4262 for (i = 0; i < 4; i++) { 4263 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); 4264 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1); 4265 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 4266 ccb->ccb_h.cbfcnp = isptarg_done; 4267 ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO); 4268 ISP_LOCK(isp); 4269 xpt_action(ccb); 4270 ISP_UNLOCK(isp); 4271 } 4272 for (i = 0; i < NISP_TARG_CMDS; i++) { 4273 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); 4274 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1); 4275 ccb->ccb_h.func_code = XPT_ACCEPT_TARGET_IO; 4276 ccb->ccb_h.cbfcnp = isptarg_done; 4277 ccb->ccb_h.ppriv_ptr0 = malloc(sizeof (ppd_t), M_ISPTARG, M_WAITOK | M_ZERO); 4278 ISP_LOCK(isp); 4279 xpt_action(ccb); 4280 ISP_UNLOCK(isp); 4281 } 4282 for (i = 0; i < 4; i++) { 4283 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); 4284 xpt_setup_ccb(&ccb->ccb_h, wperiph->path, 1); 4285 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; 4286 ccb->ccb_h.cbfcnp = isptarg_done; 4287 ISP_LOCK(isp); 4288 xpt_action(ccb); 4289 ISP_UNLOCK(isp); 4290 } 4291 for (i = 0; i < NISP_TARG_NOTIFIES; i++) { 4292 ccb = malloc(sizeof (*ccb), M_ISPTARG, M_WAITOK | M_ZERO); 4293 xpt_setup_ccb(&ccb->ccb_h, periph->path, 1); 4294 ccb->ccb_h.func_code = XPT_IMMEDIATE_NOTIFY; 4295 ccb->ccb_h.cbfcnp = isptarg_done; 4296 ISP_LOCK(isp); 4297 xpt_action(ccb); 4298 ISP_UNLOCK(isp); 4299 } 4300 4301 /* 4302 * Now turn it all back on 4303 */ 4304 xpt_setup_ccb(&ccb->ccb_h, periph->path, 10); 4305 ccb->ccb_h.func_code = XPT_SET_SIM_KNOB; 4306 ccb->knob.xport_specific.fc.valid = KNOB_VALID_ROLE; 4307 ccb->knob.xport_specific.fc.role = KNOB_ROLE_TARGET; 4308 ISP_LOCK(isp); 4309 xpt_action(ccb); 4310 ISP_UNLOCK(isp); 4311 4312 /* 4313 * Okay, while things are still active, sleep... 4314 */ 4315 ISP_LOCK(isp); 4316 for (;;) { 4317 ISP_GET_PC(isp, chan, proc_active, i); 4318 if (i == 0) { 4319 break; 4320 } 4321 msleep(wchan, &isp->isp_lock, PUSER, "tsnooze", 0); 4322 } 4323 ISP_UNLOCK(isp); 4324 4325 out: 4326 if (wperiph) { 4327 cam_periph_invalidate(wperiph); 4328 } 4329 if (periph) { 4330 cam_periph_invalidate(periph); 4331 } 4332 if (junk_data) { 4333 free(junk_data, M_ISPTARG); 4334 } 4335 if (disk_data) { 4336 free(disk_data, M_ISPTARG); 4337 } 4338 if (softc) { 4339 free(softc, M_ISPTARG); 4340 } 4341 xpt_free_path(path); 4342 xpt_free_path(wpath); 4343 } 4344 4345 static void 4346 isp_target_thread_pi(void *arg) 4347 { 4348 struct isp_spi *pi = arg; 4349 ispsoftc_t *isp = cam_sim_softc(pi->sim); 4350 int chan = cam_sim_bus(pi->sim); 4351 4352 isp_target_thread(isp, chan); 4353 ISP_SPI_PC(isp, chan)->num_threads -= 1; 4354 kthread_exit(); 4355 } 4356 4357 static void 4358 isp_target_thread_fc(void *arg) 4359 { 4360 struct isp_fc *fc = arg; 4361 ispsoftc_t *isp = cam_sim_softc(pi->sim); 4362 int chan = cam_sim_bus(pi->sim); 4363 4364 isp_target_thread(isp, chan); 4365 ISP_FC_PC(isp, chan)->num_threads -= 1; 4366 kthread_exit(); 4367 } 4368 4369 static int 4370 isptarg_rwparm(uint8_t *cdb, uint8_t *dp, uint64_t dl, uint32_t offset, uint8_t **kp, uint32_t *tl, int *lp) 4371 { 4372 uint32_t cnt, curcnt; 4373 uint64_t lba; 4374 4375 switch (cdb[0]) { 4376 case WRITE_16: 4377 case READ_16: 4378 cnt = (((uint32_t)cdb[10]) << 24) | 4379 (((uint32_t)cdb[11]) << 16) | 4380 (((uint32_t)cdb[12]) << 8) | 4381 ((uint32_t)cdb[13]); 4382 4383 lba = (((uint64_t)cdb[2]) << 56) | 4384 (((uint64_t)cdb[3]) << 48) | 4385 (((uint64_t)cdb[4]) << 40) | 4386 (((uint64_t)cdb[5]) << 32) | 4387 (((uint64_t)cdb[6]) << 24) | 4388 (((uint64_t)cdb[7]) << 16) | 4389 (((uint64_t)cdb[8]) << 8) | 4390 ((uint64_t)cdb[9]); 4391 break; 4392 case WRITE_12: 4393 case READ_12: 4394 cnt = (((uint32_t)cdb[6]) << 16) | 4395 (((uint32_t)cdb[7]) << 8) | 4396 ((u_int32_t)cdb[8]); 4397 4398 lba = (((uint32_t)cdb[2]) << 24) | 4399 (((uint32_t)cdb[3]) << 16) | 4400 (((uint32_t)cdb[4]) << 8) | 4401 ((uint32_t)cdb[5]); 4402 break; 4403 case WRITE_10: 4404 case READ_10: 4405 cnt = (((uint32_t)cdb[7]) << 8) | 4406 ((u_int32_t)cdb[8]); 4407 4408 lba = (((uint32_t)cdb[2]) << 24) | 4409 (((uint32_t)cdb[3]) << 16) | 4410 (((uint32_t)cdb[4]) << 8) | 4411 ((uint32_t)cdb[5]); 4412 break; 4413 case WRITE_6: 4414 case READ_6: 4415 cnt = cdb[4]; 4416 if (cnt == 0) { 4417 cnt = 256; 4418 } 4419 lba = (((uint32_t)cdb[1] & 0x1f) << 16) | 4420 (((uint32_t)cdb[2]) << 8) | 4421 ((uint32_t)cdb[3]); 4422 break; 4423 default: 4424 return (-1); 4425 } 4426 4427 cnt <<= DISK_SHIFT; 4428 lba <<= DISK_SHIFT; 4429 4430 if (offset == cnt) { 4431 *lp = 1; 4432 return (0); 4433 } 4434 4435 if (lba + cnt > dl) { 4436 return (-2); 4437 } 4438 4439 curcnt = MAX_ISP_TARG_TRANSFER; 4440 if (offset + curcnt >= cnt) { 4441 curcnt = cnt - offset; 4442 *lp = 1; 4443 } else { 4444 *lp = 0; 4445 } 4446 #ifdef ISP_MULTI_CCBS 4447 if (curcnt > MULTI_CCB_DATA_LIM) 4448 curcnt = MULTI_CCB_DATA_LIM; 4449 #endif 4450 *tl = curcnt; 4451 *kp = &dp[lba + offset]; 4452 return (0); 4453 } 4454 4455 #endif 4456 #endif 4457 4458 static void 4459 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg) 4460 { 4461 struct cam_sim *sim; 4462 int bus, tgt; 4463 ispsoftc_t *isp; 4464 4465 sim = (struct cam_sim *)cbarg; 4466 isp = (ispsoftc_t *) cam_sim_softc(sim); 4467 bus = cam_sim_bus(sim); 4468 tgt = xpt_path_target_id(path); 4469 4470 switch (code) { 4471 case AC_LOST_DEVICE: 4472 if (IS_SCSI(isp)) { 4473 uint16_t oflags, nflags; 4474 sdparam *sdp = SDPARAM(isp, bus); 4475 4476 if (tgt >= 0) { 4477 nflags = sdp->isp_devparam[tgt].nvrm_flags; 4478 #ifndef ISP_TARGET_MODE 4479 nflags &= DPARM_SAFE_DFLT; 4480 if (isp->isp_loaded_fw) { 4481 nflags |= DPARM_NARROW | DPARM_ASYNC; 4482 } 4483 #else 4484 nflags = DPARM_DEFAULT; 4485 #endif 4486 oflags = sdp->isp_devparam[tgt].goal_flags; 4487 sdp->isp_devparam[tgt].goal_flags = nflags; 4488 sdp->isp_devparam[tgt].dev_update = 1; 4489 sdp->update = 1; 4490 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus); 4491 sdp->isp_devparam[tgt].goal_flags = oflags; 4492 } 4493 } 4494 break; 4495 default: 4496 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code); 4497 break; 4498 } 4499 } 4500 4501 static void 4502 isp_poll(struct cam_sim *sim) 4503 { 4504 ispsoftc_t *isp = cam_sim_softc(sim); 4505 uint32_t isr; 4506 uint16_t sema, mbox; 4507 4508 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { 4509 isp_intr(isp, isr, sema, mbox); 4510 } 4511 } 4512 4513 4514 static void 4515 isp_watchdog(void *arg) 4516 { 4517 struct ccb_scsiio *xs = arg; 4518 ispsoftc_t *isp; 4519 uint32_t ohandle = ISP_HANDLE_FREE, handle; 4520 4521 isp = XS_ISP(xs); 4522 4523 handle = isp_find_handle(isp, xs); 4524 4525 /* 4526 * Hand crank the interrupt code just to be sure the command isn't stuck somewhere. 4527 */ 4528 if (handle != ISP_HANDLE_FREE) { 4529 uint32_t isr; 4530 uint16_t sema, mbox; 4531 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) != 0) { 4532 isp_intr(isp, isr, sema, mbox); 4533 } 4534 ohandle = handle; 4535 handle = isp_find_handle(isp, xs); 4536 } 4537 if (handle != ISP_HANDLE_FREE) { 4538 /* 4539 * Try and make sure the command is really dead before 4540 * we release the handle (and DMA resources) for reuse. 4541 * 4542 * If we are successful in aborting the command then 4543 * we're done here because we'll get the command returned 4544 * back separately. 4545 */ 4546 if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) { 4547 return; 4548 } 4549 4550 /* 4551 * Note that after calling the above, the command may in 4552 * fact have been completed. 4553 */ 4554 xs = isp_find_xs(isp, handle); 4555 4556 /* 4557 * If the command no longer exists, then we won't 4558 * be able to find the xs again with this handle. 4559 */ 4560 if (xs == NULL) { 4561 return; 4562 } 4563 4564 /* 4565 * After this point, the command is really dead. 4566 */ 4567 if (XS_XFRLEN(xs)) { 4568 ISP_DMAFREE(isp, xs, handle); 4569 } 4570 isp_destroy_handle(isp, handle); 4571 isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle); 4572 xs->ccb_h.status &= ~CAM_STATUS_MASK; 4573 xs->ccb_h.status |= CAM_CMD_TIMEOUT; 4574 isp_prt_endcmd(isp, xs); 4575 isp_done(xs); 4576 } else { 4577 if (ohandle != ISP_HANDLE_FREE) { 4578 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle 0x%x, recovered during interrupt", __func__, ohandle); 4579 } else { 4580 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle already free", __func__); 4581 } 4582 } 4583 } 4584 4585 static void 4586 isp_make_here(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) 4587 { 4588 union ccb *ccb; 4589 struct isp_fc *fc = ISP_FC_PC(isp, chan); 4590 4591 if (isp_autoconfig == 0) { 4592 return; 4593 } 4594 4595 /* 4596 * Allocate a CCB, create a wildcard path for this target and schedule a rescan. 4597 */ 4598 ccb = xpt_alloc_ccb_nowait(); 4599 if (ccb == NULL) { 4600 isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan); 4601 return; 4602 } 4603 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(fc->sim), 4604 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 4605 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan"); 4606 xpt_free_ccb(ccb); 4607 return; 4608 } 4609 4610 /* 4611 * Since we're about to issue a rescan, mark this device as not 4612 * reported gone. 4613 */ 4614 fcp->reported_gone = 0; 4615 4616 xpt_rescan(ccb); 4617 } 4618 4619 static void 4620 isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) 4621 { 4622 struct cam_path *tp; 4623 struct isp_fc *fc = ISP_FC_PC(isp, chan); 4624 4625 if (isp_autoconfig == 0) { 4626 return; 4627 } 4628 if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { 4629 /* 4630 * We're about to send out the lost device async 4631 * notification, so indicate that we have reported it gone. 4632 */ 4633 fcp->reported_gone = 1; 4634 xpt_async(AC_LOST_DEVICE, tp, NULL); 4635 xpt_free_path(tp); 4636 } 4637 } 4638 4639 /* 4640 * Gone Device Timer Function- when we have decided that a device has gone 4641 * away, we wait a specific period of time prior to telling the OS it has 4642 * gone away. 4643 * 4644 * This timer function fires once a second and then scans the port database 4645 * for devices that are marked dead but still have a virtual target assigned. 4646 * We decrement a counter for that port database entry, and when it hits zero, 4647 * we tell the OS the device has gone away. 4648 */ 4649 static void 4650 isp_gdt(void *arg) 4651 { 4652 struct isp_fc *fc = arg; 4653 taskqueue_enqueue(taskqueue_thread, &fc->gtask); 4654 } 4655 4656 static void 4657 isp_gdt_task(void *arg, int pending) 4658 { 4659 struct isp_fc *fc = arg; 4660 ispsoftc_t *isp = fc->isp; 4661 int chan = fc - isp->isp_osinfo.pc.fc; 4662 fcportdb_t *lp; 4663 int dbidx, more_to_do = 0; 4664 4665 ISP_LOCK(isp); 4666 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan); 4667 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 4668 lp = &FCPARAM(isp, chan)->portdb[dbidx]; 4669 4670 if (lp->state != FC_PORTDB_STATE_ZOMBIE) { 4671 continue; 4672 } 4673 if (lp->dev_map_idx == 0 || lp->target_mode) { 4674 continue; 4675 } 4676 if (lp->gone_timer != 0) { 4677 isp_prt(isp, ISP_LOG_SANCFG, "%s: Chan %d more to do for target %u (timer=%u)", __func__, chan, lp->dev_map_idx - 1, lp->gone_timer); 4678 lp->gone_timer -= 1; 4679 more_to_do++; 4680 continue; 4681 } 4682 lp->dev_map_idx = 0; 4683 lp->state = FC_PORTDB_STATE_NIL; 4684 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Gone Device Timeout"); 4685 isp_make_gone(isp, lp, chan, dbidx); 4686 } 4687 if (fc->ready) { 4688 if (more_to_do) { 4689 callout_reset(&fc->gdt, hz, isp_gdt, fc); 4690 } else { 4691 callout_deactivate(&fc->gdt); 4692 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime); 4693 } 4694 } 4695 ISP_UNLOCK(isp); 4696 } 4697 4698 /* 4699 * Loop Down Timer Function- when loop goes down, a timer is started and 4700 * and after it expires we come here and take all probational devices that 4701 * the OS knows about and the tell the OS that they've gone away. 4702 * 4703 * We don't clear the devices out of our port database because, when loop 4704 * come back up, we have to do some actual cleanup with the chip at that 4705 * point (implicit PLOGO, e.g., to get the chip's port database state right). 4706 */ 4707 static void 4708 isp_ldt(void *arg) 4709 { 4710 struct isp_fc *fc = arg; 4711 taskqueue_enqueue(taskqueue_thread, &fc->ltask); 4712 } 4713 4714 static void 4715 isp_ldt_task(void *arg, int pending) 4716 { 4717 struct isp_fc *fc = arg; 4718 ispsoftc_t *isp = fc->isp; 4719 int chan = fc - isp->isp_osinfo.pc.fc; 4720 fcportdb_t *lp; 4721 int dbidx, i; 4722 4723 ISP_LOCK(isp); 4724 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime); 4725 callout_deactivate(&fc->ldt); 4726 4727 /* 4728 * Notify to the OS all targets who we now consider have departed. 4729 */ 4730 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 4731 lp = &FCPARAM(isp, chan)->portdb[dbidx]; 4732 4733 if (lp->state != FC_PORTDB_STATE_PROBATIONAL) { 4734 continue; 4735 } 4736 if (lp->dev_map_idx == 0 || lp->target_mode) { 4737 continue; 4738 } 4739 4740 /* 4741 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST! 4742 */ 4743 4744 4745 for (i = 0; i < isp->isp_maxcmds; i++) { 4746 struct ccb_scsiio *xs; 4747 4748 if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) { 4749 continue; 4750 } 4751 if ((xs = isp->isp_xflist[i].cmd) == NULL) { 4752 continue; 4753 } 4754 if (dbidx != XS_TGT(xs)) { 4755 continue; 4756 } 4757 isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%d orphaned by loop down timeout", 4758 isp->isp_xflist[i].handle, chan, XS_TGT(xs), XS_LUN(xs)); 4759 } 4760 4761 /* 4762 * Mark that we've announced that this device is gone.... 4763 */ 4764 lp->announced = 1; 4765 lp->dev_map_idx = 0; 4766 lp->state = FC_PORTDB_STATE_NIL; 4767 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, lp->portid, dbidx, "Loop Down Timeout"); 4768 isp_make_gone(isp, lp, chan, dbidx); 4769 } 4770 4771 if (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR) { 4772 isp_unfreeze_loopdown(isp, chan); 4773 } 4774 /* 4775 * The loop down timer has expired. Wake up the kthread 4776 * to notice that fact (or make it false). 4777 */ 4778 fc->loop_dead = 1; 4779 fc->loop_down_time = fc->loop_down_limit+1; 4780 wakeup(fc); 4781 ISP_UNLOCK(isp); 4782 } 4783 4784 static void 4785 isp_kthread(void *arg) 4786 { 4787 struct isp_fc *fc = arg; 4788 ispsoftc_t *isp = fc->isp; 4789 int chan = fc - isp->isp_osinfo.pc.fc; 4790 int slp = 0; 4791 4792 mtx_lock(&isp->isp_osinfo.lock); 4793 4794 while (isp->isp_osinfo.is_exiting == 0) { 4795 int lb, lim; 4796 4797 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan); 4798 lb = isp_fc_runstate(isp, chan, 250000); 4799 4800 /* 4801 * Our action is different based upon whether we're supporting 4802 * Initiator mode or not. If we are, we might freeze the simq 4803 * when loop is down and set all sorts of different delays to 4804 * check again. 4805 * 4806 * If not, we simply just wait for loop to come up. 4807 */ 4808 if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) { 4809 /* 4810 * Increment loop down time by the last sleep interval 4811 */ 4812 fc->loop_down_time += slp; 4813 4814 if (lb < 0) { 4815 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time); 4816 } else { 4817 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC got to %d (down count %d)", __func__, chan, lb, fc->loop_down_time); 4818 } 4819 4820 /* 4821 * If we've never seen loop up and we've waited longer 4822 * than quickboot time, or we've seen loop up but we've 4823 * waited longer than loop_down_limit, give up and go 4824 * to sleep until loop comes up. 4825 */ 4826 if (FCPARAM(isp, chan)->loop_seen_once == 0) { 4827 lim = isp_quickboot_time; 4828 } else { 4829 lim = fc->loop_down_limit; 4830 } 4831 if (fc->loop_down_time >= lim) { 4832 isp_freeze_loopdown(isp, chan, "loop limit hit"); 4833 slp = 0; 4834 } else if (fc->loop_down_time < 10) { 4835 slp = 1; 4836 } else if (fc->loop_down_time < 30) { 4837 slp = 5; 4838 } else if (fc->loop_down_time < 60) { 4839 slp = 10; 4840 } else if (fc->loop_down_time < 120) { 4841 slp = 20; 4842 } else { 4843 slp = 30; 4844 } 4845 4846 } else if (lb) { 4847 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan); 4848 fc->loop_down_time += slp; 4849 if (fc->loop_down_time > 300) 4850 slp = 0; 4851 else 4852 slp = 60; 4853 } else { 4854 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan); 4855 fc->loop_down_time = 0; 4856 slp = 0; 4857 } 4858 4859 4860 /* 4861 * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it 4862 * now so that CAM can start sending us commands. 4863 * 4864 * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again 4865 * or kill the commands, as appropriate. 4866 */ 4867 4868 if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) { 4869 isp_unfreeze_loopdown(isp, chan); 4870 } 4871 4872 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp); 4873 4874 msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz); 4875 4876 /* 4877 * If slp is zero, we're waking up for the first time after 4878 * things have been okay. In this case, we set a deferral state 4879 * for all commands and delay hysteresis seconds before starting 4880 * the FC state evaluation. This gives the loop/fabric a chance 4881 * to settle. 4882 */ 4883 if (slp == 0 && fc->hysteresis) { 4884 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz); 4885 mtx_unlock(&isp->isp_osinfo.lock); 4886 pause("ispt", fc->hysteresis * hz); 4887 mtx_lock(&isp->isp_osinfo.lock); 4888 } 4889 } 4890 fc->num_threads -= 1; 4891 mtx_unlock(&isp->isp_osinfo.lock); 4892 kthread_exit(); 4893 } 4894 4895 static void 4896 isp_action(struct cam_sim *sim, union ccb *ccb) 4897 { 4898 int bus, tgt, ts, error, lim; 4899 ispsoftc_t *isp; 4900 struct ccb_trans_settings *cts; 4901 4902 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 4903 4904 isp = (ispsoftc_t *)cam_sim_softc(sim); 4905 mtx_assert(&isp->isp_lock, MA_OWNED); 4906 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); 4907 ISP_PCMD(ccb) = NULL; 4908 4909 if (isp->isp_state != ISP_RUNSTATE && ccb->ccb_h.func_code == XPT_SCSI_IO) { 4910 isp_init(isp); 4911 if (isp->isp_state != ISP_INITSTATE) { 4912 /* 4913 * Lie. Say it was a selection timeout. 4914 */ 4915 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 4916 isp_done((struct ccb_scsiio *) ccb); 4917 return; 4918 } 4919 isp->isp_state = ISP_RUNSTATE; 4920 } 4921 4922 switch (ccb->ccb_h.func_code) { 4923 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 4924 bus = XS_CHANNEL(ccb); 4925 /* 4926 * Do a couple of preliminary checks... 4927 */ 4928 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 4929 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 4930 ccb->ccb_h.status = CAM_REQ_INVALID; 4931 isp_done((struct ccb_scsiio *) ccb); 4932 break; 4933 } 4934 } 4935 ccb->csio.req_map = NULL; 4936 #ifdef DIAGNOSTIC 4937 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) { 4938 xpt_print(ccb->ccb_h.path, "invalid target\n"); 4939 ccb->ccb_h.status = CAM_PATH_INVALID; 4940 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) { 4941 xpt_print(ccb->ccb_h.path, "invalid lun\n"); 4942 ccb->ccb_h.status = CAM_PATH_INVALID; 4943 } 4944 if (ccb->ccb_h.status == CAM_PATH_INVALID) { 4945 xpt_done(ccb); 4946 break; 4947 } 4948 #endif 4949 ccb->csio.scsi_status = SCSI_STATUS_OK; 4950 if (isp_get_pcmd(isp, ccb)) { 4951 isp_prt(isp, ISP_LOGWARN, "out of PCMDs"); 4952 cam_freeze_devq(ccb->ccb_h.path); 4953 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0); 4954 ccb->ccb_h.status = CAM_REQUEUE_REQ; 4955 xpt_done(ccb); 4956 break; 4957 } 4958 error = isp_start((XS_T *) ccb); 4959 switch (error) { 4960 case CMD_QUEUED: 4961 ccb->ccb_h.status |= CAM_SIM_QUEUED; 4962 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) { 4963 break; 4964 } 4965 ts = ccb->ccb_h.timeout; 4966 if (ts == CAM_TIME_DEFAULT) { 4967 ts = 60*1000; 4968 } 4969 ts = isp_mstohz(ts); 4970 callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb); 4971 break; 4972 case CMD_RQLATER: 4973 /* 4974 * We get this result for FC devices if the loop state isn't ready yet 4975 * or if the device in question has gone zombie on us. 4976 * 4977 * If we've never seen Loop UP at all, we requeue this request and wait 4978 * for the initial loop up delay to expire. 4979 */ 4980 lim = ISP_FC_PC(isp, bus)->loop_down_limit; 4981 if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) { 4982 if (FCPARAM(isp, bus)->loop_seen_once == 0) { 4983 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d loop not seen yet @ %lu", XS_TGT(ccb), XS_LUN(ccb), (unsigned long) time_uptime); 4984 } else { 4985 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d downtime (%d) > lim (%d)", XS_TGT(ccb), XS_LUN(ccb), ISP_FC_PC(isp, bus)->loop_down_time, lim); 4986 } 4987 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 4988 isp_done((struct ccb_scsiio *) ccb); 4989 break; 4990 } 4991 isp_prt(isp, ISP_LOGDEBUG0, "%d.%d retry later", XS_TGT(ccb), XS_LUN(ccb)); 4992 cam_freeze_devq(ccb->ccb_h.path); 4993 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0); 4994 ccb->ccb_h.status = CAM_REQUEUE_REQ; 4995 isp_free_pcmd(isp, ccb); 4996 xpt_done(ccb); 4997 break; 4998 case CMD_EAGAIN: 4999 isp_free_pcmd(isp, ccb); 5000 cam_freeze_devq(ccb->ccb_h.path); 5001 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0); 5002 ccb->ccb_h.status = CAM_REQUEUE_REQ; 5003 xpt_done(ccb); 5004 break; 5005 case CMD_COMPLETE: 5006 isp_done((struct ccb_scsiio *) ccb); 5007 break; 5008 default: 5009 isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__); 5010 ccb->ccb_h.status = CAM_REQUEUE_REQ; 5011 isp_free_pcmd(isp, ccb); 5012 xpt_done(ccb); 5013 } 5014 break; 5015 5016 #ifdef ISP_TARGET_MODE 5017 case XPT_EN_LUN: /* Enable/Disable LUN as a target */ 5018 if (ccb->cel.enable) { 5019 isp_enable_lun(isp, ccb); 5020 } else { 5021 isp_disable_lun(isp, ccb); 5022 } 5023 break; 5024 case XPT_IMMED_NOTIFY: 5025 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */ 5026 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 5027 { 5028 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun); 5029 if (tptr == NULL) { 5030 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD); 5031 } 5032 if (tptr == NULL) { 5033 const char *str; 5034 uint32_t tag; 5035 5036 if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) { 5037 str = "XPT_IMMEDIATE_NOTIFY"; 5038 tag = ccb->cin1.seq_id; 5039 } else { 5040 tag = ccb->atio.tag_id; 5041 str = "XPT_ACCEPT_TARGET_IO"; 5042 } 5043 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str); 5044 dump_tstates(isp, XS_CHANNEL(ccb)); 5045 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 5046 break; 5047 } 5048 ccb->ccb_h.spriv_field0 = 0; 5049 ccb->ccb_h.spriv_ptr1 = isp; 5050 5051 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 5052 if (ccb->atio.tag_id) { 5053 atio_private_data_t *atp = isp_find_atpd(isp, tptr, ccb->atio.tag_id); 5054 if (atp) { 5055 isp_put_atpd(isp, tptr, atp); 5056 } 5057 } 5058 tptr->atio_count++; 5059 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle); 5060 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n", 5061 ccb->atio.tag_id, tptr->atio_count); 5062 ccb->atio.tag_id = 0; 5063 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) { 5064 if (ccb->cin1.tag_id) { 5065 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id); 5066 if (ntp) { 5067 isp_put_ntpd(isp, tptr, ntp); 5068 } 5069 } 5070 tptr->inot_count++; 5071 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); 5072 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", 5073 ccb->cin1.seq_id, tptr->inot_count); 5074 ccb->cin1.seq_id = 0; 5075 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) { 5076 tptr->inot_count++; 5077 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); 5078 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", 5079 ccb->cin1.seq_id, tptr->inot_count); 5080 ccb->cin1.seq_id = 0; 5081 } 5082 rls_lun_statep(isp, tptr); 5083 ccb->ccb_h.status = CAM_REQ_INPROG; 5084 break; 5085 } 5086 case XPT_NOTIFY_ACK: 5087 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 5088 break; 5089 case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */ 5090 { 5091 tstate_t *tptr; 5092 inot_private_data_t *ntp; 5093 5094 /* 5095 * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb 5096 * XXX: matches that for the immediate notify, we have to *search* for the notify structure 5097 */ 5098 /* 5099 * All the relevant path information is in the associated immediate notify 5100 */ 5101 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] NOTIFY ACKNOWLEDGE for 0x%x seen\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id); 5102 ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr); 5103 if (ntp == NULL) { 5104 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] XPT_NOTIFY_ACKNOWLEDGE of 0x%x cannot find ntp private data\n", __func__, 5105 ccb->cna2.tag_id, ccb->cna2.seq_id); 5106 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 5107 xpt_done(ccb); 5108 break; 5109 } 5110 if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) { 5111 rls_lun_statep(isp, tptr); 5112 cam_freeze_devq(ccb->ccb_h.path); 5113 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0); 5114 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 5115 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 5116 break; 5117 } 5118 isp_put_ntpd(isp, tptr, ntp); 5119 rls_lun_statep(isp, tptr); 5120 ccb->ccb_h.status = CAM_REQ_CMP; 5121 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, ccb->ccb_h.path, "%s: [0x%x] calling xpt_done for tag 0x%x\n", __func__, ccb->cna2.tag_id, ccb->cna2.seq_id); 5122 xpt_done(ccb); 5123 break; 5124 } 5125 case XPT_CONT_TARGET_IO: 5126 isp_target_start_ctio(isp, ccb, FROM_CAM); 5127 break; 5128 #endif 5129 case XPT_RESET_DEV: /* BDR the specified SCSI device */ 5130 { 5131 struct isp_fc *fc; 5132 5133 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)); 5134 tgt = ccb->ccb_h.target_id; 5135 tgt |= (bus << 16); 5136 if (IS_FC(isp)) 5137 fc = ISP_FC_PC(isp, bus); 5138 else 5139 fc = NULL; 5140 5141 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt); 5142 if (error) { 5143 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 5144 } else { 5145 /* 5146 * If we have a FC device, reset the Command 5147 * Reference Number, because the target will expect 5148 * that we re-start the CRN at 1 after a reset. 5149 */ 5150 if (fc != NULL) 5151 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1); 5152 5153 ccb->ccb_h.status = CAM_REQ_CMP; 5154 } 5155 xpt_done(ccb); 5156 break; 5157 } 5158 case XPT_ABORT: /* Abort the specified CCB */ 5159 { 5160 union ccb *accb = ccb->cab.abort_ccb; 5161 switch (accb->ccb_h.func_code) { 5162 #ifdef ISP_TARGET_MODE 5163 case XPT_ACCEPT_TARGET_IO: 5164 isp_target_mark_aborted(isp, ccb); 5165 break; 5166 #endif 5167 case XPT_SCSI_IO: 5168 error = isp_control(isp, ISPCTL_ABORT_CMD, accb); 5169 if (error) { 5170 ccb->ccb_h.status = CAM_UA_ABORT; 5171 } else { 5172 ccb->ccb_h.status = CAM_REQ_CMP; 5173 } 5174 break; 5175 default: 5176 ccb->ccb_h.status = CAM_REQ_INVALID; 5177 break; 5178 } 5179 /* 5180 * This is not a queued CCB, so the caller expects it to be 5181 * complete when control is returned. 5182 */ 5183 break; 5184 } 5185 #define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS) 5186 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */ 5187 cts = &ccb->cts; 5188 if (!IS_CURRENT_SETTINGS(cts)) { 5189 ccb->ccb_h.status = CAM_REQ_INVALID; 5190 xpt_done(ccb); 5191 break; 5192 } 5193 tgt = cts->ccb_h.target_id; 5194 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 5195 if (IS_SCSI(isp)) { 5196 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 5197 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; 5198 sdparam *sdp = SDPARAM(isp, bus); 5199 uint16_t *dptr; 5200 5201 if (spi->valid == 0 && scsi->valid == 0) { 5202 ccb->ccb_h.status = CAM_REQ_CMP; 5203 xpt_done(ccb); 5204 break; 5205 } 5206 5207 /* 5208 * We always update (internally) from goal_flags 5209 * so any request to change settings just gets 5210 * vectored to that location. 5211 */ 5212 dptr = &sdp->isp_devparam[tgt].goal_flags; 5213 5214 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 5215 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 5216 *dptr |= DPARM_DISC; 5217 else 5218 *dptr &= ~DPARM_DISC; 5219 } 5220 5221 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 5222 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 5223 *dptr |= DPARM_TQING; 5224 else 5225 *dptr &= ~DPARM_TQING; 5226 } 5227 5228 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 5229 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT) 5230 *dptr |= DPARM_WIDE; 5231 else 5232 *dptr &= ~DPARM_WIDE; 5233 } 5234 5235 /* 5236 * XXX: FIX ME 5237 */ 5238 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) { 5239 *dptr |= DPARM_SYNC; 5240 /* 5241 * XXX: CHECK FOR LEGALITY 5242 */ 5243 sdp->isp_devparam[tgt].goal_period = spi->sync_period; 5244 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset; 5245 } else { 5246 *dptr &= ~DPARM_SYNC; 5247 } 5248 isp_prt(isp, ISP_LOGDEBUG0, "SET (%d.%d.%jx) to flags %x off %x per %x", bus, tgt, (uintmax_t)cts->ccb_h.target_lun, sdp->isp_devparam[tgt].goal_flags, 5249 sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period); 5250 sdp->isp_devparam[tgt].dev_update = 1; 5251 sdp->update = 1; 5252 } 5253 ccb->ccb_h.status = CAM_REQ_CMP; 5254 xpt_done(ccb); 5255 break; 5256 case XPT_GET_TRAN_SETTINGS: 5257 cts = &ccb->cts; 5258 tgt = cts->ccb_h.target_id; 5259 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 5260 if (IS_FC(isp)) { 5261 fcparam *fcp = FCPARAM(isp, bus); 5262 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 5263 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc; 5264 5265 cts->protocol = PROTO_SCSI; 5266 cts->protocol_version = SCSI_REV_2; 5267 cts->transport = XPORT_FC; 5268 cts->transport_version = 0; 5269 5270 scsi->valid = CTS_SCSI_VALID_TQ; 5271 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 5272 fc->valid = CTS_FC_VALID_SPEED; 5273 fc->bitrate = 100000; 5274 fc->bitrate *= fcp->isp_gbspeed; 5275 if (tgt < MAX_FC_TARG) { 5276 fcportdb_t *lp = &fcp->portdb[tgt]; 5277 fc->wwnn = lp->node_wwn; 5278 fc->wwpn = lp->port_wwn; 5279 fc->port = lp->portid; 5280 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT; 5281 } 5282 } else { 5283 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 5284 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; 5285 sdparam *sdp = SDPARAM(isp, bus); 5286 uint16_t dval, pval, oval; 5287 5288 if (IS_CURRENT_SETTINGS(cts)) { 5289 sdp->isp_devparam[tgt].dev_refresh = 1; 5290 sdp->update = 1; 5291 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus); 5292 dval = sdp->isp_devparam[tgt].actv_flags; 5293 oval = sdp->isp_devparam[tgt].actv_offset; 5294 pval = sdp->isp_devparam[tgt].actv_period; 5295 } else { 5296 dval = sdp->isp_devparam[tgt].nvrm_flags; 5297 oval = sdp->isp_devparam[tgt].nvrm_offset; 5298 pval = sdp->isp_devparam[tgt].nvrm_period; 5299 } 5300 5301 cts->protocol = PROTO_SCSI; 5302 cts->protocol_version = SCSI_REV_2; 5303 cts->transport = XPORT_SPI; 5304 cts->transport_version = 2; 5305 5306 spi->valid = 0; 5307 scsi->valid = 0; 5308 spi->flags = 0; 5309 scsi->flags = 0; 5310 if (dval & DPARM_DISC) { 5311 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 5312 } 5313 if ((dval & DPARM_SYNC) && oval && pval) { 5314 spi->sync_offset = oval; 5315 spi->sync_period = pval; 5316 } else { 5317 spi->sync_offset = 0; 5318 spi->sync_period = 0; 5319 } 5320 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 5321 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 5322 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 5323 if (dval & DPARM_WIDE) { 5324 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 5325 } else { 5326 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 5327 } 5328 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 5329 scsi->valid = CTS_SCSI_VALID_TQ; 5330 if (dval & DPARM_TQING) { 5331 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 5332 } 5333 spi->valid |= CTS_SPI_VALID_DISC; 5334 } 5335 isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%jx) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM", 5336 bus, tgt, (uintmax_t)cts->ccb_h.target_lun, dval, oval, pval); 5337 } 5338 ccb->ccb_h.status = CAM_REQ_CMP; 5339 xpt_done(ccb); 5340 break; 5341 5342 case XPT_CALC_GEOMETRY: 5343 cam_calc_geometry(&ccb->ccg, 1); 5344 xpt_done(ccb); 5345 break; 5346 5347 case XPT_RESET_BUS: /* Reset the specified bus */ 5348 bus = cam_sim_bus(sim); 5349 error = isp_control(isp, ISPCTL_RESET_BUS, bus); 5350 if (error) { 5351 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 5352 xpt_done(ccb); 5353 break; 5354 } 5355 if (bootverbose) { 5356 xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus); 5357 } 5358 if (IS_FC(isp)) { 5359 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0); 5360 } else { 5361 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0); 5362 } 5363 ccb->ccb_h.status = CAM_REQ_CMP; 5364 xpt_done(ccb); 5365 break; 5366 5367 case XPT_TERM_IO: /* Terminate the I/O process */ 5368 ccb->ccb_h.status = CAM_REQ_INVALID; 5369 xpt_done(ccb); 5370 break; 5371 5372 case XPT_SET_SIM_KNOB: /* Set SIM knobs */ 5373 { 5374 struct ccb_sim_knob *kp = &ccb->knob; 5375 fcparam *fcp; 5376 5377 if (!IS_FC(isp)) { 5378 ccb->ccb_h.status = CAM_REQ_INVALID; 5379 xpt_done(ccb); 5380 break; 5381 } 5382 5383 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path)); 5384 fcp = FCPARAM(isp, bus); 5385 5386 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) { 5387 fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn; 5388 fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn; 5389 isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn); 5390 } 5391 ccb->ccb_h.status = CAM_REQ_CMP; 5392 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) { 5393 int rchange = 0; 5394 int newrole = 0; 5395 5396 switch (kp->xport_specific.fc.role) { 5397 case KNOB_ROLE_NONE: 5398 if (fcp->role != ISP_ROLE_NONE) { 5399 rchange = 1; 5400 newrole = ISP_ROLE_NONE; 5401 } 5402 break; 5403 case KNOB_ROLE_TARGET: 5404 if (fcp->role != ISP_ROLE_TARGET) { 5405 rchange = 1; 5406 newrole = ISP_ROLE_TARGET; 5407 } 5408 break; 5409 case KNOB_ROLE_INITIATOR: 5410 if (fcp->role != ISP_ROLE_INITIATOR) { 5411 rchange = 1; 5412 newrole = ISP_ROLE_INITIATOR; 5413 } 5414 break; 5415 case KNOB_ROLE_BOTH: 5416 if (fcp->role != ISP_ROLE_BOTH) { 5417 rchange = 1; 5418 newrole = ISP_ROLE_BOTH; 5419 } 5420 break; 5421 } 5422 if (rchange) { 5423 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole); 5424 #ifdef ISP_TARGET_MODE 5425 ISP_SET_PC(isp, bus, tm_enabled, 0); 5426 ISP_SET_PC(isp, bus, tm_luns_enabled, 0); 5427 #endif 5428 if (isp_control(isp, ISPCTL_CHANGE_ROLE, 5429 bus, newrole) != 0) { 5430 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 5431 xpt_done(ccb); 5432 break; 5433 } 5434 #ifdef ISP_TARGET_MODE 5435 if (newrole == ISP_ROLE_TARGET || newrole == ISP_ROLE_BOTH) { 5436 /* 5437 * Give the new role a chance to complain and settle 5438 */ 5439 msleep(isp, &isp->isp_lock, PRIBIO, "taking a breather", 2); 5440 ccb->ccb_h.status = isp_enable_deferred_luns(isp, bus); 5441 } 5442 #endif 5443 } 5444 } 5445 xpt_done(ccb); 5446 break; 5447 } 5448 case XPT_GET_SIM_KNOB: /* Get SIM knobs */ 5449 { 5450 struct ccb_sim_knob *kp = &ccb->knob; 5451 5452 if (IS_FC(isp)) { 5453 fcparam *fcp; 5454 5455 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path)); 5456 fcp = FCPARAM(isp, bus); 5457 5458 kp->xport_specific.fc.wwnn = fcp->isp_wwnn; 5459 kp->xport_specific.fc.wwpn = fcp->isp_wwpn; 5460 switch (fcp->role) { 5461 case ISP_ROLE_NONE: 5462 kp->xport_specific.fc.role = KNOB_ROLE_NONE; 5463 break; 5464 case ISP_ROLE_TARGET: 5465 kp->xport_specific.fc.role = KNOB_ROLE_TARGET; 5466 break; 5467 case ISP_ROLE_INITIATOR: 5468 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR; 5469 break; 5470 case ISP_ROLE_BOTH: 5471 kp->xport_specific.fc.role = KNOB_ROLE_BOTH; 5472 break; 5473 } 5474 kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE; 5475 ccb->ccb_h.status = CAM_REQ_CMP; 5476 } else { 5477 ccb->ccb_h.status = CAM_REQ_INVALID; 5478 } 5479 xpt_done(ccb); 5480 break; 5481 } 5482 case XPT_PATH_INQ: /* Path routing inquiry */ 5483 { 5484 struct ccb_pathinq *cpi = &ccb->cpi; 5485 5486 cpi->version_num = 1; 5487 #ifdef ISP_TARGET_MODE 5488 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 5489 #else 5490 cpi->target_sprt = 0; 5491 #endif 5492 cpi->hba_eng_cnt = 0; 5493 cpi->max_target = ISP_MAX_TARGETS(isp) - 1; 5494 cpi->max_lun = ISP_MAX_LUNS(isp) - 1; 5495 cpi->bus_id = cam_sim_bus(sim); 5496 if (isp->isp_osinfo.sixtyfourbit) 5497 cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE; 5498 else 5499 cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE; 5500 5501 bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path)); 5502 if (IS_FC(isp)) { 5503 fcparam *fcp = FCPARAM(isp, bus); 5504 5505 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED; 5506 5507 /* 5508 * Because our loop ID can shift from time to time, 5509 * make our initiator ID out of range of our bus. 5510 */ 5511 cpi->initiator_id = cpi->max_target + 1; 5512 5513 /* 5514 * Set base transfer capabilities for Fibre Channel, for this HBA. 5515 */ 5516 if (IS_25XX(isp)) { 5517 cpi->base_transfer_speed = 8000000; 5518 } else if (IS_24XX(isp)) { 5519 cpi->base_transfer_speed = 4000000; 5520 } else if (IS_23XX(isp)) { 5521 cpi->base_transfer_speed = 2000000; 5522 } else { 5523 cpi->base_transfer_speed = 1000000; 5524 } 5525 cpi->hba_inquiry = PI_TAG_ABLE; 5526 cpi->transport = XPORT_FC; 5527 cpi->transport_version = 0; 5528 cpi->xport_specific.fc.wwnn = fcp->isp_wwnn; 5529 cpi->xport_specific.fc.wwpn = fcp->isp_wwpn; 5530 cpi->xport_specific.fc.port = fcp->isp_portid; 5531 cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000; 5532 } else { 5533 sdparam *sdp = SDPARAM(isp, bus); 5534 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 5535 cpi->hba_misc = PIM_UNMAPPED; 5536 cpi->initiator_id = sdp->isp_initiator_id; 5537 cpi->base_transfer_speed = 3300; 5538 cpi->transport = XPORT_SPI; 5539 cpi->transport_version = 2; 5540 } 5541 cpi->protocol = PROTO_SCSI; 5542 cpi->protocol_version = SCSI_REV_2; 5543 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 5544 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 5545 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 5546 cpi->unit_number = cam_sim_unit(sim); 5547 cpi->ccb_h.status = CAM_REQ_CMP; 5548 xpt_done(ccb); 5549 break; 5550 } 5551 default: 5552 ccb->ccb_h.status = CAM_REQ_INVALID; 5553 xpt_done(ccb); 5554 break; 5555 } 5556 } 5557 5558 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 5559 5560 void 5561 isp_done(XS_T *sccb) 5562 { 5563 ispsoftc_t *isp = XS_ISP(sccb); 5564 uint32_t status; 5565 5566 if (XS_NOERR(sccb)) 5567 XS_SETERR(sccb, CAM_REQ_CMP); 5568 5569 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) { 5570 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 5571 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) { 5572 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; 5573 } else { 5574 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 5575 } 5576 } 5577 5578 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 5579 status = sccb->ccb_h.status & CAM_STATUS_MASK; 5580 if (status != CAM_REQ_CMP) { 5581 if (status != CAM_SEL_TIMEOUT) 5582 isp_prt(isp, ISP_LOGDEBUG0, "target %d lun %d CAM status 0x%x SCSI status 0x%x", XS_TGT(sccb), XS_LUN(sccb), sccb->ccb_h.status, sccb->scsi_status); 5583 else if ((IS_FC(isp)) 5584 && (XS_TGT(sccb) < MAX_FC_TARG)) { 5585 fcparam *fcp; 5586 5587 fcp = FCPARAM(isp, XS_CHANNEL(sccb)); 5588 fcp->portdb[XS_TGT(sccb)].reported_gone = 1; 5589 } 5590 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 5591 sccb->ccb_h.status |= CAM_DEV_QFRZN; 5592 xpt_freeze_devq(sccb->ccb_h.path, 1); 5593 } 5594 } 5595 5596 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 5597 xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status); 5598 } 5599 5600 if (ISP_PCMD(sccb)) { 5601 if (callout_active(&PISP_PCMD(sccb)->wdog)) 5602 callout_stop(&PISP_PCMD(sccb)->wdog); 5603 isp_free_pcmd(isp, (union ccb *) sccb); 5604 } 5605 xpt_done((union ccb *) sccb); 5606 } 5607 5608 void 5609 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) 5610 { 5611 int bus, now; 5612 static const char prom0[] = "Chan %d PortID 0x%06x handle 0x%x %s %s WWPN 0x%08x%08x"; 5613 static const char prom2[] = "Chan %d PortID 0x%06x handle 0x%x %s %s tgt %u WWPN 0x%08x%08x"; 5614 char buf[64]; 5615 char *msg = NULL; 5616 target_id_t tgt; 5617 fcportdb_t *lp; 5618 struct isp_fc *fc; 5619 struct cam_path *tmppath; 5620 va_list ap; 5621 5622 switch (cmd) { 5623 case ISPASYNC_NEW_TGT_PARAMS: 5624 { 5625 struct ccb_trans_settings_scsi *scsi; 5626 struct ccb_trans_settings_spi *spi; 5627 int flags, tgt; 5628 sdparam *sdp; 5629 struct ccb_trans_settings cts; 5630 5631 memset(&cts, 0, sizeof (struct ccb_trans_settings)); 5632 5633 va_start(ap, cmd); 5634 bus = va_arg(ap, int); 5635 tgt = va_arg(ap, int); 5636 va_end(ap); 5637 sdp = SDPARAM(isp, bus); 5638 5639 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 5640 isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus); 5641 break; 5642 } 5643 flags = sdp->isp_devparam[tgt].actv_flags; 5644 cts.type = CTS_TYPE_CURRENT_SETTINGS; 5645 cts.protocol = PROTO_SCSI; 5646 cts.transport = XPORT_SPI; 5647 5648 scsi = &cts.proto_specific.scsi; 5649 spi = &cts.xport_specific.spi; 5650 5651 if (flags & DPARM_TQING) { 5652 scsi->valid |= CTS_SCSI_VALID_TQ; 5653 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 5654 } 5655 5656 if (flags & DPARM_DISC) { 5657 spi->valid |= CTS_SPI_VALID_DISC; 5658 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 5659 } 5660 spi->flags |= CTS_SPI_VALID_BUS_WIDTH; 5661 if (flags & DPARM_WIDE) { 5662 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 5663 } else { 5664 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 5665 } 5666 if (flags & DPARM_SYNC) { 5667 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 5668 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 5669 spi->sync_period = sdp->isp_devparam[tgt].actv_period; 5670 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset; 5671 } 5672 isp_prt(isp, ISP_LOGDEBUG2, "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x", bus, tgt, sdp->isp_devparam[tgt].actv_period, sdp->isp_devparam[tgt].actv_offset, flags); 5673 xpt_setup_ccb(&cts.ccb_h, tmppath, 1); 5674 xpt_async(AC_TRANSFER_NEG, tmppath, &cts); 5675 xpt_free_path(tmppath); 5676 break; 5677 } 5678 case ISPASYNC_BUS_RESET: 5679 { 5680 va_start(ap, cmd); 5681 bus = va_arg(ap, int); 5682 va_end(ap); 5683 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus); 5684 if (IS_FC(isp)) { 5685 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL); 5686 } else { 5687 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL); 5688 } 5689 break; 5690 } 5691 case ISPASYNC_LIP: 5692 if (msg == NULL) { 5693 msg = "LIP Received"; 5694 } 5695 /* FALLTHROUGH */ 5696 case ISPASYNC_LOOP_RESET: 5697 if (msg == NULL) { 5698 msg = "LOOP Reset"; 5699 } 5700 /* FALLTHROUGH */ 5701 case ISPASYNC_LOOP_DOWN: 5702 { 5703 if (msg == NULL) { 5704 msg = "LOOP Down"; 5705 } 5706 va_start(ap, cmd); 5707 bus = va_arg(ap, int); 5708 va_end(ap); 5709 5710 FCPARAM(isp, bus)->link_active = 0; 5711 5712 fc = ISP_FC_PC(isp, bus); 5713 if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) { 5714 /* 5715 * We don't do any simq freezing if we are only in target mode 5716 */ 5717 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) { 5718 if (fc->path) { 5719 isp_freeze_loopdown(isp, bus, msg); 5720 } 5721 if (!callout_active(&fc->ldt)) { 5722 callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc); 5723 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime); 5724 } 5725 } 5726 } 5727 isp_fcp_reset_crn(fc, /*tgt*/0, /*tgt_set*/ 0); 5728 5729 isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg); 5730 break; 5731 } 5732 case ISPASYNC_LOOP_UP: 5733 va_start(ap, cmd); 5734 bus = va_arg(ap, int); 5735 va_end(ap); 5736 fc = ISP_FC_PC(isp, bus); 5737 /* 5738 * Now we just note that Loop has come up. We don't 5739 * actually do anything because we're waiting for a 5740 * Change Notify before activating the FC cleanup 5741 * thread to look at the state of the loop again. 5742 */ 5743 FCPARAM(isp, bus)->link_active = 1; 5744 fc->loop_dead = 0; 5745 fc->loop_down_time = 0; 5746 isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus); 5747 break; 5748 case ISPASYNC_DEV_ARRIVED: 5749 va_start(ap, cmd); 5750 bus = va_arg(ap, int); 5751 lp = va_arg(ap, fcportdb_t *); 5752 va_end(ap); 5753 fc = ISP_FC_PC(isp, bus); 5754 lp->announced = 0; 5755 lp->gone_timer = 0; 5756 if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) { 5757 lp->dev_map_idx = (lp - FCPARAM(isp, bus)->portdb) + 1; 5758 } 5759 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 5760 if (lp->dev_map_idx) { 5761 tgt = lp->dev_map_idx - 1; 5762 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "arrived at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5763 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1); 5764 isp_make_here(isp, lp, bus, tgt); 5765 } else { 5766 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "arrived", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5767 } 5768 break; 5769 case ISPASYNC_DEV_CHANGED: 5770 va_start(ap, cmd); 5771 bus = va_arg(ap, int); 5772 lp = va_arg(ap, fcportdb_t *); 5773 va_end(ap); 5774 fc = ISP_FC_PC(isp, bus); 5775 lp->announced = 0; 5776 lp->gone_timer = 0; 5777 if (isp_change_is_bad) { 5778 lp->state = FC_PORTDB_STATE_NIL; 5779 if (lp->dev_map_idx) { 5780 tgt = lp->dev_map_idx - 1; 5781 lp->dev_map_idx = 0; 5782 isp_prt(isp, ISP_LOGCONFIG, prom3, bus, lp->portid, tgt, "change is bad"); 5783 isp_make_gone(isp, lp, bus, tgt); 5784 } else { 5785 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 5786 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed and departed", 5787 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5788 } 5789 } else { 5790 lp->portid = lp->new_portid; 5791 lp->prli_word3 = lp->new_prli_word3; 5792 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 5793 if (lp->dev_map_idx) { 5794 tgt = lp->dev_map_idx - 1; 5795 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "changed at", tgt, 5796 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5797 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1); 5798 } else { 5799 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "changed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5800 } 5801 } 5802 break; 5803 case ISPASYNC_DEV_STAYED: 5804 va_start(ap, cmd); 5805 bus = va_arg(ap, int); 5806 lp = va_arg(ap, fcportdb_t *); 5807 va_end(ap); 5808 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 5809 if (lp->dev_map_idx) { 5810 fc = ISP_FC_PC(isp, bus); 5811 tgt = lp->dev_map_idx - 1; 5812 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "stayed at", tgt, 5813 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5814 /* 5815 * Only issue a rescan if we've actually reported 5816 * that this device is gone. 5817 */ 5818 if (lp->reported_gone != 0) { 5819 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "rescanned at", tgt, 5820 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5821 isp_make_here(isp, lp, bus, tgt); 5822 } 5823 } else { 5824 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "stayed", 5825 (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5826 } 5827 break; 5828 case ISPASYNC_DEV_GONE: 5829 va_start(ap, cmd); 5830 bus = va_arg(ap, int); 5831 lp = va_arg(ap, fcportdb_t *); 5832 now = va_arg(ap, int); 5833 va_end(ap); 5834 fc = ISP_FC_PC(isp, bus); 5835 /* 5836 * If this has a virtual target and we haven't marked it 5837 * that we're going to have isp_gdt tell the OS it's gone, 5838 * set the isp_gdt timer running on it. 5839 * 5840 * If it isn't marked that isp_gdt is going to get rid of it, 5841 * announce that it's gone. 5842 * 5843 */ 5844 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 5845 if (lp->dev_map_idx && lp->announced == 0 && now) { 5846 lp->announced = 1; 5847 tgt = lp->dev_map_idx - 1; 5848 lp->dev_map_idx = 0; 5849 isp_make_gone(isp, lp, bus, tgt); 5850 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5851 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1); 5852 } else if (lp->dev_map_idx && lp->announced == 0) { 5853 lp->announced = 1; 5854 lp->state = FC_PORTDB_STATE_ZOMBIE; 5855 lp->gone_timer = ISP_FC_PC(isp, bus)->gone_device_time; 5856 if (fc->ready && !callout_active(&fc->gdt)) { 5857 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Starting Gone Device Timer with %u seconds time now %lu", bus, lp->gone_timer, (unsigned long)time_uptime); 5858 callout_reset(&fc->gdt, hz, isp_gdt, fc); 5859 } 5860 tgt = lp->dev_map_idx - 1; 5861 isp_prt(isp, ISP_LOGCONFIG, prom2, bus, lp->portid, lp->handle, buf, "gone zombie at", tgt, (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5862 isp_fcp_reset_crn(fc, tgt, /*tgt_set*/ 1); 5863 } else if (lp->announced == 0) { 5864 isp_prt(isp, ISP_LOGCONFIG, prom0, bus, lp->portid, lp->handle, buf, "departed", (uint32_t) (lp->port_wwn >> 32), (uint32_t) lp->port_wwn); 5865 } 5866 break; 5867 case ISPASYNC_CHANGE_NOTIFY: 5868 { 5869 char *msg; 5870 int evt, nphdl, nlstate, reason; 5871 5872 va_start(ap, cmd); 5873 bus = va_arg(ap, int); 5874 evt = va_arg(ap, int); 5875 if (IS_24XX(isp) && evt == ISPASYNC_CHANGE_PDB) { 5876 nphdl = va_arg(ap, int); 5877 nlstate = va_arg(ap, int); 5878 reason = va_arg(ap, int); 5879 } else { 5880 nphdl = NIL_HANDLE; 5881 nlstate = reason = 0; 5882 } 5883 va_end(ap); 5884 fc = ISP_FC_PC(isp, bus); 5885 5886 if (evt == ISPASYNC_CHANGE_PDB) { 5887 msg = "Chan %d Port Database Changed"; 5888 } else if (evt == ISPASYNC_CHANGE_SNS) { 5889 msg = "Chan %d Name Server Database Changed"; 5890 } else { 5891 msg = "Chan %d Other Change Notify"; 5892 } 5893 5894 /* 5895 * If the loop down timer is running, cancel it. 5896 */ 5897 if (fc->ready && callout_active(&fc->ldt)) { 5898 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime); 5899 callout_stop(&fc->ldt); 5900 } 5901 isp_prt(isp, ISP_LOGINFO, msg, bus); 5902 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) { 5903 isp_freeze_loopdown(isp, bus, msg); 5904 } 5905 wakeup(fc); 5906 break; 5907 } 5908 #ifdef ISP_TARGET_MODE 5909 case ISPASYNC_TARGET_NOTIFY: 5910 { 5911 isp_notify_t *notify; 5912 va_start(ap, cmd); 5913 notify = va_arg(ap, isp_notify_t *); 5914 va_end(ap); 5915 switch (notify->nt_ncode) { 5916 case NT_ABORT_TASK: 5917 case NT_ABORT_TASK_SET: 5918 case NT_CLEAR_ACA: 5919 case NT_CLEAR_TASK_SET: 5920 case NT_LUN_RESET: 5921 case NT_TARGET_RESET: 5922 /* 5923 * These are task management functions. 5924 */ 5925 isp_handle_platform_target_tmf(isp, notify); 5926 break; 5927 case NT_BUS_RESET: 5928 case NT_LIP_RESET: 5929 case NT_LINK_UP: 5930 case NT_LINK_DOWN: 5931 /* 5932 * No action need be taken here. 5933 */ 5934 break; 5935 case NT_HBA_RESET: 5936 isp_del_all_wwn_entries(isp, ISP_NOCHAN); 5937 break; 5938 case NT_GLOBAL_LOGOUT: 5939 case NT_LOGOUT: 5940 /* 5941 * This is device arrival/departure notification 5942 */ 5943 isp_handle_platform_target_notify_ack(isp, notify); 5944 break; 5945 case NT_ARRIVED: 5946 { 5947 struct ac_contract ac; 5948 struct ac_device_changed *fc; 5949 5950 ac.contract_number = AC_CONTRACT_DEV_CHG; 5951 fc = (struct ac_device_changed *) ac.contract_data; 5952 fc->wwpn = notify->nt_wwn; 5953 fc->port = notify->nt_sid; 5954 fc->target = notify->nt_nphdl; 5955 fc->arrived = 1; 5956 xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac); 5957 break; 5958 } 5959 case NT_DEPARTED: 5960 { 5961 struct ac_contract ac; 5962 struct ac_device_changed *fc; 5963 5964 ac.contract_number = AC_CONTRACT_DEV_CHG; 5965 fc = (struct ac_device_changed *) ac.contract_data; 5966 fc->wwpn = notify->nt_wwn; 5967 fc->port = notify->nt_sid; 5968 fc->target = notify->nt_nphdl; 5969 fc->arrived = 0; 5970 xpt_async(AC_CONTRACT, ISP_FC_PC(isp, notify->nt_channel)->path, &ac); 5971 break; 5972 } 5973 default: 5974 isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode); 5975 isp_handle_platform_target_notify_ack(isp, notify); 5976 break; 5977 } 5978 break; 5979 } 5980 case ISPASYNC_TARGET_NOTIFY_ACK: 5981 { 5982 void *inot; 5983 va_start(ap, cmd); 5984 inot = va_arg(ap, void *); 5985 va_end(ap); 5986 if (isp_notify_ack(isp, inot)) { 5987 isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT); 5988 if (tp) { 5989 tp->isp = isp; 5990 if (inot) { 5991 memcpy(tp->data, inot, sizeof (tp->data)); 5992 tp->not = tp->data; 5993 } else { 5994 tp->not = NULL; 5995 } 5996 callout_init_mtx(&tp->timer, &isp->isp_lock, 0); 5997 callout_reset(&tp->timer, 5, 5998 isp_refire_notify_ack, tp); 5999 } else { 6000 isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire"); 6001 } 6002 } 6003 break; 6004 } 6005 case ISPASYNC_TARGET_ACTION: 6006 { 6007 isphdr_t *hp; 6008 6009 va_start(ap, cmd); 6010 hp = va_arg(ap, isphdr_t *); 6011 va_end(ap); 6012 switch (hp->rqs_entry_type) { 6013 default: 6014 isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type); 6015 break; 6016 case RQSTYPE_NOTIFY: 6017 if (IS_SCSI(isp)) { 6018 isp_handle_platform_notify_scsi(isp, (in_entry_t *) hp); 6019 } else if (IS_24XX(isp)) { 6020 isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp); 6021 } else { 6022 isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp); 6023 } 6024 break; 6025 case RQSTYPE_ATIO: 6026 if (IS_24XX(isp)) { 6027 isp_handle_platform_atio7(isp, (at7_entry_t *) hp); 6028 } else { 6029 isp_handle_platform_atio(isp, (at_entry_t *) hp); 6030 } 6031 break; 6032 case RQSTYPE_ATIO2: 6033 isp_handle_platform_atio2(isp, (at2_entry_t *) hp); 6034 break; 6035 case RQSTYPE_CTIO7: 6036 case RQSTYPE_CTIO3: 6037 case RQSTYPE_CTIO2: 6038 case RQSTYPE_CTIO: 6039 isp_handle_platform_ctio(isp, hp); 6040 break; 6041 case RQSTYPE_ABTS_RCVD: 6042 { 6043 abts_t *abts = (abts_t *)hp; 6044 isp_notify_t notify, *nt = ¬ify; 6045 tstate_t *tptr; 6046 fcportdb_t *lp; 6047 uint16_t chan; 6048 uint32_t sid, did; 6049 6050 did = (abts->abts_did_hi << 16) | abts->abts_did_lo; 6051 sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; 6052 ISP_MEMZERO(nt, sizeof (isp_notify_t)); 6053 6054 nt->nt_hba = isp; 6055 nt->nt_did = did; 6056 nt->nt_nphdl = abts->abts_nphdl; 6057 nt->nt_sid = sid; 6058 isp_find_chan_by_did(isp, did, &chan); 6059 if (chan == ISP_NOCHAN) { 6060 nt->nt_tgt = TGT_ANY; 6061 } else { 6062 nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn; 6063 if (isp_find_pdb_by_loopid(isp, chan, abts->abts_nphdl, &lp)) { 6064 nt->nt_wwn = lp->port_wwn; 6065 } else { 6066 nt->nt_wwn = INI_ANY; 6067 } 6068 } 6069 /* 6070 * Try hard to find the lun for this command. 6071 */ 6072 tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task); 6073 if (tptr) { 6074 nt->nt_lun = tptr->ts_lun; 6075 rls_lun_statep(isp, tptr); 6076 } else { 6077 nt->nt_lun = LUN_ANY; 6078 } 6079 nt->nt_need_ack = 1; 6080 nt->nt_tagval = abts->abts_rxid_task; 6081 nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32); 6082 if (abts->abts_rxid_task == ISP24XX_NO_TASK) { 6083 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x has no task id (rx_id 0x%04x ox_id 0x%04x)", 6084 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id); 6085 } else { 6086 isp_prt(isp, ISP_LOGTINFO, "[0x%x] ABTS from N-Port handle 0x%x Port 0x%06x for task 0x%x (rx_id 0x%04x ox_id 0x%04x)", 6087 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id); 6088 } 6089 nt->nt_channel = chan; 6090 nt->nt_ncode = NT_ABORT_TASK; 6091 nt->nt_lreserved = hp; 6092 isp_handle_platform_target_tmf(isp, nt); 6093 break; 6094 } 6095 case RQSTYPE_ENABLE_LUN: 6096 case RQSTYPE_MODIFY_LUN: 6097 isp_ledone(isp, (lun_entry_t *) hp); 6098 break; 6099 } 6100 break; 6101 } 6102 #endif 6103 case ISPASYNC_FW_CRASH: 6104 { 6105 uint16_t mbox1, mbox6; 6106 mbox1 = ISP_READ(isp, OUTMAILBOX1); 6107 if (IS_DUALBUS(isp)) { 6108 mbox6 = ISP_READ(isp, OUTMAILBOX6); 6109 } else { 6110 mbox6 = 0; 6111 } 6112 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1); 6113 mbox1 = isp->isp_osinfo.mbox_sleep_ok; 6114 isp->isp_osinfo.mbox_sleep_ok = 0; 6115 isp_reinit(isp, 1); 6116 isp->isp_osinfo.mbox_sleep_ok = mbox1; 6117 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL); 6118 break; 6119 } 6120 default: 6121 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd); 6122 break; 6123 } 6124 } 6125 6126 6127 /* 6128 * Locks are held before coming here. 6129 */ 6130 void 6131 isp_uninit(ispsoftc_t *isp) 6132 { 6133 if (IS_24XX(isp)) { 6134 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); 6135 } else { 6136 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 6137 } 6138 ISP_DISABLE_INTS(isp); 6139 } 6140 6141 /* 6142 * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them 6143 * up from our platform default (defww{p|n}n) and morph them based upon 6144 * channel. 6145 * 6146 * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them 6147 * based upon channel. 6148 */ 6149 6150 uint64_t 6151 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn) 6152 { 6153 uint64_t seed; 6154 struct isp_fc *fc = ISP_FC_PC(isp, chan); 6155 6156 /* 6157 * If we're asking for a active WWN, the default overrides get 6158 * returned, otherwise the NVRAM value is picked. 6159 * 6160 * If we're asking for a default WWN, we just pick the default override. 6161 */ 6162 if (isactive) { 6163 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn; 6164 if (seed) { 6165 return (seed); 6166 } 6167 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram; 6168 if (seed) { 6169 return (seed); 6170 } 6171 return (0x400000007F000009ull); 6172 } 6173 6174 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn; 6175 6176 /* 6177 * For channel zero just return what we have. For either ACTIVE or 6178 * DEFAULT cases, we depend on default override of NVRAM values for 6179 * channel zero. 6180 */ 6181 if (chan == 0) { 6182 return (seed); 6183 } 6184 6185 /* 6186 * For other channels, we are doing one of three things: 6187 * 6188 * 1. If what we have now is non-zero, return it. Otherwise we morph 6189 * values from channel 0. 2. If we're here for a WWPN we synthesize 6190 * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a 6191 * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA. 6192 */ 6193 6194 if (seed) { 6195 return (seed); 6196 } 6197 seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn; 6198 if (seed == 0) 6199 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram; 6200 6201 if (((seed >> 60) & 0xf) == 2) { 6202 /* 6203 * The type 2 NAA fields for QLogic cards appear be laid out 6204 * thusly: 6205 * 6206 * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56 6207 * port (1) or node (0) WWN distinguishor bit 48 6208 * physical port on dual-port chips (23XX/24XX) 6209 * 6210 * This is somewhat nutty, particularly since bit 48 is 6211 * irrelevant as they assign separate serial numbers to 6212 * different physical ports anyway. 6213 * 6214 * We'll stick our channel number plus one first into bits 6215 * 57..59 and thence into bits 52..55 which allows for 8 bits 6216 * of channel which is comfortably more than our maximum 6217 * (126) now. 6218 */ 6219 seed &= ~0x0FF0000000000000ULL; 6220 if (iswwnn == 0) { 6221 seed |= ((uint64_t) (chan + 1) & 0xf) << 56; 6222 seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52; 6223 } 6224 } else { 6225 seed = 0; 6226 } 6227 return (seed); 6228 } 6229 6230 void 6231 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...) 6232 { 6233 int loc; 6234 char lbuf[200]; 6235 va_list ap; 6236 6237 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 6238 return; 6239 } 6240 snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev)); 6241 loc = strlen(lbuf); 6242 va_start(ap, fmt); 6243 vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap); 6244 va_end(ap); 6245 printf("%s\n", lbuf); 6246 } 6247 6248 void 6249 isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...) 6250 { 6251 va_list ap; 6252 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 6253 return; 6254 } 6255 xpt_print_path(xs->ccb_h.path); 6256 va_start(ap, fmt); 6257 vprintf(fmt, ap); 6258 va_end(ap); 6259 printf("\n"); 6260 } 6261 6262 uint64_t 6263 isp_nanotime_sub(struct timespec *b, struct timespec *a) 6264 { 6265 uint64_t elapsed; 6266 struct timespec x = *b; 6267 timespecsub(&x, a); 6268 elapsed = GET_NANOSEC(&x); 6269 if (elapsed == 0) 6270 elapsed++; 6271 return (elapsed); 6272 } 6273 6274 int 6275 isp_mbox_acquire(ispsoftc_t *isp) 6276 { 6277 if (isp->isp_osinfo.mboxbsy) { 6278 return (1); 6279 } else { 6280 isp->isp_osinfo.mboxcmd_done = 0; 6281 isp->isp_osinfo.mboxbsy = 1; 6282 return (0); 6283 } 6284 } 6285 6286 void 6287 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) 6288 { 6289 unsigned int usecs = mbp->timeout; 6290 unsigned int max, olim, ilim; 6291 6292 if (usecs == 0) { 6293 usecs = MBCMD_DEFAULT_TIMEOUT; 6294 } 6295 max = isp->isp_mbxwrk0 + 1; 6296 6297 if (isp->isp_osinfo.mbox_sleep_ok) { 6298 unsigned int ms = (usecs + 999) / 1000; 6299 6300 isp->isp_osinfo.mbox_sleep_ok = 0; 6301 isp->isp_osinfo.mbox_sleeping = 1; 6302 for (olim = 0; olim < max; olim++) { 6303 msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock, PRIBIO, "ispmbx_sleep", isp_mstohz(ms)); 6304 if (isp->isp_osinfo.mboxcmd_done) { 6305 break; 6306 } 6307 } 6308 isp->isp_osinfo.mbox_sleep_ok = 1; 6309 isp->isp_osinfo.mbox_sleeping = 0; 6310 } else { 6311 for (olim = 0; olim < max; olim++) { 6312 for (ilim = 0; ilim < usecs; ilim += 100) { 6313 uint32_t isr; 6314 uint16_t sema, mbox; 6315 if (isp->isp_osinfo.mboxcmd_done) { 6316 break; 6317 } 6318 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { 6319 isp_intr(isp, isr, sema, mbox); 6320 if (isp->isp_osinfo.mboxcmd_done) { 6321 break; 6322 } 6323 } 6324 ISP_DELAY(100); 6325 } 6326 if (isp->isp_osinfo.mboxcmd_done) { 6327 break; 6328 } 6329 } 6330 } 6331 if (isp->isp_osinfo.mboxcmd_done == 0) { 6332 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (started @ %s:%d)", 6333 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled", isp->isp_lastmbxcmd, usecs, mbp->func, mbp->lineno); 6334 mbp->param[0] = MBOX_TIMEOUT; 6335 isp->isp_osinfo.mboxcmd_done = 1; 6336 } 6337 } 6338 6339 void 6340 isp_mbox_notify_done(ispsoftc_t *isp) 6341 { 6342 if (isp->isp_osinfo.mbox_sleeping) { 6343 wakeup(&isp->isp_mbxworkp); 6344 } 6345 isp->isp_osinfo.mboxcmd_done = 1; 6346 } 6347 6348 void 6349 isp_mbox_release(ispsoftc_t *isp) 6350 { 6351 isp->isp_osinfo.mboxbsy = 0; 6352 } 6353 6354 int 6355 isp_fc_scratch_acquire(ispsoftc_t *isp, int chan) 6356 { 6357 int ret = 0; 6358 if (isp->isp_osinfo.pc.fc[chan].fcbsy) { 6359 ret = -1; 6360 } else { 6361 isp->isp_osinfo.pc.fc[chan].fcbsy = 1; 6362 } 6363 return (ret); 6364 } 6365 6366 int 6367 isp_mstohz(int ms) 6368 { 6369 int hz; 6370 struct timeval t; 6371 t.tv_sec = ms / 1000; 6372 t.tv_usec = (ms % 1000) * 1000; 6373 hz = tvtohz(&t); 6374 if (hz < 0) { 6375 hz = 0x7fffffff; 6376 } 6377 if (hz == 0) { 6378 hz = 1; 6379 } 6380 return (hz); 6381 } 6382 6383 void 6384 isp_platform_intr(void *arg) 6385 { 6386 ispsoftc_t *isp = arg; 6387 uint32_t isr; 6388 uint16_t sema, mbox; 6389 6390 ISP_LOCK(isp); 6391 isp->isp_intcnt++; 6392 if (ISP_READ_ISR(isp, &isr, &sema, &mbox) == 0) { 6393 isp->isp_intbogus++; 6394 } else { 6395 isp_intr(isp, isr, sema, mbox); 6396 } 6397 ISP_UNLOCK(isp); 6398 } 6399 6400 void 6401 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl) 6402 { 6403 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 6404 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD); 6405 } else { 6406 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE); 6407 } 6408 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); 6409 } 6410 6411 /* 6412 * Reset the command reference number for all LUNs on a specific target 6413 * (needed when a target arrives again) or for all targets on a port 6414 * (needed for events like a LIP). 6415 */ 6416 void 6417 isp_fcp_reset_crn(struct isp_fc *fc, uint32_t tgt, int tgt_set) 6418 { 6419 int i; 6420 struct isp_nexus *nxp; 6421 6422 if (tgt_set == 0) 6423 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN on all targets"); 6424 else 6425 isp_prt(fc->isp, ISP_LOG_SANCFG, "resetting CRN target %u", tgt); 6426 6427 for (i = 0; i < NEXUS_HASH_WIDTH; i++) { 6428 nxp = fc->nexus_hash[i]; 6429 while (nxp) { 6430 if ((tgt_set != 0) && (tgt == nxp->tgt)) 6431 nxp->crnseed = 0; 6432 6433 nxp = nxp->next; 6434 } 6435 } 6436 } 6437 6438 int 6439 isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd) 6440 { 6441 uint32_t chan, tgt, lun; 6442 struct isp_fc *fc; 6443 struct isp_nexus *nxp; 6444 int idx; 6445 6446 if (isp->isp_type < ISP_HA_FC_2300) 6447 return (0); 6448 6449 chan = XS_CHANNEL(cmd); 6450 tgt = XS_TGT(cmd); 6451 lun = XS_LUN(cmd); 6452 fc = &isp->isp_osinfo.pc.fc[chan]; 6453 idx = NEXUS_HASH(tgt, lun); 6454 nxp = fc->nexus_hash[idx]; 6455 6456 while (nxp) { 6457 if (nxp->tgt == tgt && nxp->lun == lun) 6458 break; 6459 nxp = nxp->next; 6460 } 6461 if (nxp == NULL) { 6462 nxp = fc->nexus_free_list; 6463 if (nxp == NULL) { 6464 nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT); 6465 if (nxp == NULL) { 6466 return (-1); 6467 } 6468 } else { 6469 fc->nexus_free_list = nxp->next; 6470 } 6471 nxp->tgt = tgt; 6472 nxp->lun = lun; 6473 nxp->next = fc->nexus_hash[idx]; 6474 fc->nexus_hash[idx] = nxp; 6475 } 6476 if (nxp) { 6477 if (nxp->crnseed == 0) 6478 nxp->crnseed = 1; 6479 if (cmd) 6480 PISP_PCMD(cmd)->crn = nxp->crnseed; 6481 *crnp = nxp->crnseed++; 6482 return (0); 6483 } 6484 return (-1); 6485 } 6486 6487 /* 6488 * We enter with the lock held 6489 */ 6490 void 6491 isp_timer(void *arg) 6492 { 6493 ispsoftc_t *isp = arg; 6494 #ifdef ISP_TARGET_MODE 6495 isp_tmcmd_restart(isp); 6496 #endif 6497 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp); 6498 } 6499 6500 isp_ecmd_t * 6501 isp_get_ecmd(ispsoftc_t *isp) 6502 { 6503 isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free; 6504 if (ecmd) { 6505 isp->isp_osinfo.ecmd_free = ecmd->next; 6506 } 6507 return (ecmd); 6508 } 6509 6510 void 6511 isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd) 6512 { 6513 ecmd->next = isp->isp_osinfo.ecmd_free; 6514 isp->isp_osinfo.ecmd_free = ecmd; 6515 } 6516