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_quickboot_time = 7; /* don't wait more than N secs for loop up */ 56 int isp_gone_device_time = 30; /* grace time before reporting device lost */ 57 static const char prom3[] = "Chan %d [%u] PortID 0x%06x Departed because of %s"; 58 59 static void isp_freeze_loopdown(ispsoftc_t *, int, char *); 60 static d_ioctl_t ispioctl; 61 static void isp_intr_enable(void *); 62 static void isp_cam_async(void *, uint32_t, struct cam_path *, void *); 63 static void isp_poll(struct cam_sim *); 64 static timeout_t isp_watchdog; 65 static timeout_t isp_gdt; 66 static task_fn_t isp_gdt_task; 67 static timeout_t isp_ldt; 68 static task_fn_t isp_ldt_task; 69 static void isp_kthread(void *); 70 static void isp_action(struct cam_sim *, union ccb *); 71 static int isp_timer_count; 72 static void isp_timer(void *); 73 74 static struct cdevsw isp_cdevsw = { 75 .d_version = D_VERSION, 76 .d_ioctl = ispioctl, 77 .d_name = "isp", 78 }; 79 80 static int 81 isp_role_sysctl(SYSCTL_HANDLER_ARGS) 82 { 83 ispsoftc_t *isp = (ispsoftc_t *)arg1; 84 int chan = arg2; 85 int error, old, value; 86 87 value = FCPARAM(isp, chan)->role; 88 89 error = sysctl_handle_int(oidp, &value, 0, req); 90 if ((error != 0) || (req->newptr == NULL)) 91 return (error); 92 93 if (value < ISP_ROLE_NONE || value > ISP_ROLE_BOTH) 94 return (EINVAL); 95 96 ISP_LOCK(isp); 97 old = FCPARAM(isp, chan)->role; 98 99 /* We don't allow target mode switch from here. */ 100 value = (old & ISP_ROLE_TARGET) | (value & ISP_ROLE_INITIATOR); 101 102 /* If nothing has changed -- we are done. */ 103 if (value == old) { 104 ISP_UNLOCK(isp); 105 return (0); 106 } 107 108 /* Actually change the role. */ 109 error = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, value); 110 ISP_UNLOCK(isp); 111 return (error); 112 } 113 114 static int 115 isp_attach_chan(ispsoftc_t *isp, struct cam_devq *devq, int chan) 116 { 117 struct ccb_setasync csa; 118 struct cam_sim *sim; 119 struct cam_path *path; 120 121 /* 122 * Construct our SIM entry. 123 */ 124 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); 125 126 if (sim == NULL) { 127 return (ENOMEM); 128 } 129 130 ISP_LOCK(isp); 131 if (xpt_bus_register(sim, isp->isp_dev, chan) != CAM_SUCCESS) { 132 ISP_UNLOCK(isp); 133 cam_sim_free(sim, FALSE); 134 return (EIO); 135 } 136 ISP_UNLOCK(isp); 137 if (xpt_create_path(&path, NULL, cam_sim_path(sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 138 ISP_LOCK(isp); 139 xpt_bus_deregister(cam_sim_path(sim)); 140 ISP_UNLOCK(isp); 141 cam_sim_free(sim, FALSE); 142 return (ENXIO); 143 } 144 xpt_setup_ccb(&csa.ccb_h, path, 5); 145 csa.ccb_h.func_code = XPT_SASYNC_CB; 146 csa.event_enable = AC_LOST_DEVICE; 147 csa.callback = isp_cam_async; 148 csa.callback_arg = sim; 149 150 ISP_LOCK(isp); 151 xpt_action((union ccb *)&csa); 152 ISP_UNLOCK(isp); 153 154 if (IS_SCSI(isp)) { 155 struct isp_spi *spi = ISP_SPI_PC(isp, chan); 156 spi->sim = sim; 157 spi->path = path; 158 } else { 159 fcparam *fcp = FCPARAM(isp, chan); 160 struct isp_fc *fc = ISP_FC_PC(isp, chan); 161 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(isp->isp_osinfo.dev); 162 struct sysctl_oid *tree = device_get_sysctl_tree(isp->isp_osinfo.dev); 163 char name[16]; 164 165 ISP_LOCK(isp); 166 fc->sim = sim; 167 fc->path = path; 168 fc->isp = isp; 169 fc->ready = 1; 170 171 callout_init_mtx(&fc->ldt, &isp->isp_osinfo.lock, 0); 172 callout_init_mtx(&fc->gdt, &isp->isp_osinfo.lock, 0); 173 TASK_INIT(&fc->ltask, 1, isp_ldt_task, fc); 174 TASK_INIT(&fc->gtask, 1, isp_gdt_task, fc); 175 176 /* 177 * We start by being "loop down" if we have an initiator role 178 */ 179 if (fcp->role & ISP_ROLE_INITIATOR) { 180 isp_freeze_loopdown(isp, chan, "isp_attach"); 181 callout_reset(&fc->ldt, isp_quickboot_time * hz, isp_ldt, fc); 182 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Initial Loop Down Timer @ %lu", (unsigned long) time_uptime); 183 } 184 ISP_UNLOCK(isp); 185 if (THREAD_CREATE(isp_kthread, fc, &fc->kproc, 0, 0, "%s: fc_thrd%d", device_get_nameunit(isp->isp_osinfo.dev), chan)) { 186 xpt_free_path(fc->path); 187 ISP_LOCK(isp); 188 if (callout_active(&fc->ldt)) 189 callout_stop(&fc->ldt); 190 xpt_bus_deregister(cam_sim_path(fc->sim)); 191 ISP_UNLOCK(isp); 192 cam_sim_free(fc->sim, FALSE); 193 return (ENOMEM); 194 } 195 fc->num_threads += 1; 196 if (chan > 0) { 197 snprintf(name, sizeof(name), "chan%d", chan); 198 tree = SYSCTL_ADD_NODE(ctx, SYSCTL_CHILDREN(tree), 199 OID_AUTO, name, CTLFLAG_RW, 0, "Virtual channel"); 200 } 201 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 202 "wwnn", CTLFLAG_RD, &fcp->isp_wwnn, 203 "World Wide Node Name"); 204 SYSCTL_ADD_QUAD(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 205 "wwpn", CTLFLAG_RD, &fcp->isp_wwpn, 206 "World Wide Port Name"); 207 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 208 "loop_down_limit", CTLFLAG_RW, &fc->loop_down_limit, 0, 209 "Loop Down Limit"); 210 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 211 "gone_device_time", CTLFLAG_RW, &fc->gone_device_time, 0, 212 "Gone Device Time"); 213 #if defined(ISP_TARGET_MODE) && defined(DEBUG) 214 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 215 "inject_lost_data_frame", CTLFLAG_RW, &fc->inject_lost_data_frame, 0, 216 "Cause a Lost Frame on a Read"); 217 #endif 218 SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 219 "role", CTLTYPE_INT | CTLFLAG_RW, isp, chan, 220 isp_role_sysctl, "I", "Current role"); 221 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 222 "speed", CTLFLAG_RD, &fcp->isp_gbspeed, 0, 223 "Connection speed in gigabits"); 224 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 225 "linkstate", CTLFLAG_RD, &fcp->isp_linkstate, 0, 226 "Link state"); 227 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 228 "fwstate", CTLFLAG_RD, &fcp->isp_fwstate, 0, 229 "Firmware state"); 230 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 231 "loopstate", CTLFLAG_RD, &fcp->isp_loopstate, 0, 232 "Loop state"); 233 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, 234 "topo", CTLFLAG_RD, &fcp->isp_topo, 0, 235 "Connection topology"); 236 } 237 return (0); 238 } 239 240 static void 241 isp_detach_chan(ispsoftc_t *isp, int chan) 242 { 243 struct cam_sim *sim; 244 struct cam_path *path; 245 struct ccb_setasync csa; 246 int *num_threads; 247 248 ISP_GET_PC(isp, chan, sim, sim); 249 ISP_GET_PC(isp, chan, path, path); 250 ISP_GET_PC_ADDR(isp, chan, num_threads, num_threads); 251 252 xpt_setup_ccb(&csa.ccb_h, path, 5); 253 csa.ccb_h.func_code = XPT_SASYNC_CB; 254 csa.event_enable = 0; 255 csa.callback = isp_cam_async; 256 csa.callback_arg = sim; 257 xpt_action((union ccb *)&csa); 258 xpt_free_path(path); 259 xpt_bus_deregister(cam_sim_path(sim)); 260 cam_sim_free(sim, FALSE); 261 262 /* Wait for the channel's spawned threads to exit. */ 263 wakeup(isp->isp_osinfo.pc.ptr); 264 while (*num_threads != 0) 265 mtx_sleep(isp, &isp->isp_osinfo.lock, PRIBIO, "isp_reap", 100); 266 } 267 268 int 269 isp_attach(ispsoftc_t *isp) 270 { 271 const char *nu = device_get_nameunit(isp->isp_osinfo.dev); 272 int du = device_get_unit(isp->isp_dev); 273 int chan; 274 275 isp->isp_osinfo.ehook.ich_func = isp_intr_enable; 276 isp->isp_osinfo.ehook.ich_arg = isp; 277 /* 278 * Haha. Set this first, because if we're loaded as a module isp_intr_enable 279 * will be called right awawy, which will clear isp_osinfo.ehook_active, 280 * which would be unwise to then set again later. 281 */ 282 isp->isp_osinfo.ehook_active = 1; 283 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) { 284 isp_prt(isp, ISP_LOGERR, "could not establish interrupt enable hook"); 285 return (-EIO); 286 } 287 288 /* 289 * Create the device queue for our SIM(s). 290 */ 291 isp->isp_osinfo.devq = cam_simq_alloc(isp->isp_maxcmds); 292 if (isp->isp_osinfo.devq == NULL) { 293 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 294 return (EIO); 295 } 296 297 for (chan = 0; chan < isp->isp_nchan; chan++) { 298 if (isp_attach_chan(isp, isp->isp_osinfo.devq, chan)) { 299 goto unwind; 300 } 301 } 302 303 callout_init_mtx(&isp->isp_osinfo.tmo, &isp->isp_osinfo.lock, 0); 304 isp_timer_count = hz >> 2; 305 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp); 306 isp->isp_osinfo.timer_active = 1; 307 308 isp->isp_osinfo.cdev = make_dev(&isp_cdevsw, du, UID_ROOT, GID_OPERATOR, 0600, "%s", nu); 309 if (isp->isp_osinfo.cdev) { 310 isp->isp_osinfo.cdev->si_drv1 = isp; 311 } 312 return (0); 313 314 unwind: 315 while (--chan >= 0) { 316 struct cam_sim *sim; 317 struct cam_path *path; 318 319 ISP_GET_PC(isp, chan, sim, sim); 320 ISP_GET_PC(isp, chan, path, path); 321 xpt_free_path(path); 322 ISP_LOCK(isp); 323 xpt_bus_deregister(cam_sim_path(sim)); 324 ISP_UNLOCK(isp); 325 cam_sim_free(sim, FALSE); 326 } 327 if (isp->isp_osinfo.ehook_active) { 328 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 329 isp->isp_osinfo.ehook_active = 0; 330 } 331 if (isp->isp_osinfo.cdev) { 332 destroy_dev(isp->isp_osinfo.cdev); 333 isp->isp_osinfo.cdev = NULL; 334 } 335 cam_simq_free(isp->isp_osinfo.devq); 336 isp->isp_osinfo.devq = NULL; 337 return (-1); 338 } 339 340 int 341 isp_detach(ispsoftc_t *isp) 342 { 343 struct cam_sim *sim; 344 int chan; 345 346 ISP_LOCK(isp); 347 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) { 348 ISP_GET_PC(isp, chan, sim, sim); 349 if (sim->refcount > 2) { 350 ISP_UNLOCK(isp); 351 return (EBUSY); 352 } 353 } 354 /* Tell spawned threads that we're exiting. */ 355 isp->isp_osinfo.is_exiting = 1; 356 if (isp->isp_osinfo.timer_active) { 357 callout_stop(&isp->isp_osinfo.tmo); 358 isp->isp_osinfo.timer_active = 0; 359 } 360 for (chan = isp->isp_nchan - 1; chan >= 0; chan -= 1) 361 isp_detach_chan(isp, chan); 362 ISP_UNLOCK(isp); 363 364 if (isp->isp_osinfo.cdev) { 365 destroy_dev(isp->isp_osinfo.cdev); 366 isp->isp_osinfo.cdev = NULL; 367 } 368 if (isp->isp_osinfo.ehook_active) { 369 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 370 isp->isp_osinfo.ehook_active = 0; 371 } 372 if (isp->isp_osinfo.devq != NULL) { 373 cam_simq_free(isp->isp_osinfo.devq); 374 isp->isp_osinfo.devq = NULL; 375 } 376 return (0); 377 } 378 379 static void 380 isp_freeze_loopdown(ispsoftc_t *isp, int chan, char *msg) 381 { 382 if (IS_FC(isp)) { 383 struct isp_fc *fc = ISP_FC_PC(isp, chan); 384 if (fc->simqfrozen == 0) { 385 isp_prt(isp, ISP_LOGDEBUG0, 386 "Chan %d %s -- freeze simq (loopdown)", chan, msg); 387 fc->simqfrozen = SIMQFRZ_LOOPDOWN; 388 #if __FreeBSD_version >= 1000039 389 xpt_hold_boot(); 390 #endif 391 xpt_freeze_simq(fc->sim, 1); 392 } else { 393 isp_prt(isp, ISP_LOGDEBUG0, 394 "Chan %d %s -- mark frozen (loopdown)", chan, msg); 395 fc->simqfrozen |= SIMQFRZ_LOOPDOWN; 396 } 397 } 398 } 399 400 static void 401 isp_unfreeze_loopdown(ispsoftc_t *isp, int chan) 402 { 403 if (IS_FC(isp)) { 404 struct isp_fc *fc = ISP_FC_PC(isp, chan); 405 int wasfrozen = fc->simqfrozen & SIMQFRZ_LOOPDOWN; 406 fc->simqfrozen &= ~SIMQFRZ_LOOPDOWN; 407 if (wasfrozen && fc->simqfrozen == 0) { 408 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d releasing simq", __func__, chan); 409 xpt_release_simq(fc->sim, 1); 410 #if __FreeBSD_version >= 1000039 411 xpt_release_boot(); 412 #endif 413 } 414 } 415 } 416 417 418 static int 419 ispioctl(struct cdev *dev, u_long c, caddr_t addr, int flags, struct thread *td) 420 { 421 ispsoftc_t *isp; 422 int nr, chan, retval = ENOTTY; 423 424 isp = dev->si_drv1; 425 426 switch (c) { 427 case ISP_SDBLEV: 428 { 429 int olddblev = isp->isp_dblev; 430 isp->isp_dblev = *(int *)addr; 431 *(int *)addr = olddblev; 432 retval = 0; 433 break; 434 } 435 case ISP_GETROLE: 436 chan = *(int *)addr; 437 if (chan < 0 || chan >= isp->isp_nchan) { 438 retval = -ENXIO; 439 break; 440 } 441 if (IS_FC(isp)) { 442 *(int *)addr = FCPARAM(isp, chan)->role; 443 } else { 444 *(int *)addr = ISP_ROLE_INITIATOR; 445 } 446 retval = 0; 447 break; 448 case ISP_SETROLE: 449 if (IS_SCSI(isp)) 450 break; 451 nr = *(int *)addr; 452 chan = nr >> 8; 453 if (chan < 0 || chan >= isp->isp_nchan) { 454 retval = -ENXIO; 455 break; 456 } 457 nr &= 0xff; 458 if (nr & ~(ISP_ROLE_INITIATOR|ISP_ROLE_TARGET)) { 459 retval = EINVAL; 460 break; 461 } 462 ISP_LOCK(isp); 463 *(int *)addr = FCPARAM(isp, chan)->role; 464 retval = isp_control(isp, ISPCTL_CHANGE_ROLE, chan, nr); 465 ISP_UNLOCK(isp); 466 retval = 0; 467 break; 468 469 case ISP_RESETHBA: 470 ISP_LOCK(isp); 471 isp_reinit(isp, 0); 472 ISP_UNLOCK(isp); 473 retval = 0; 474 break; 475 476 case ISP_RESCAN: 477 if (IS_FC(isp)) { 478 chan = *(int *)addr; 479 if (chan < 0 || chan >= isp->isp_nchan) { 480 retval = -ENXIO; 481 break; 482 } 483 ISP_LOCK(isp); 484 if (isp_fc_runstate(isp, chan, 5 * 1000000)) { 485 retval = EIO; 486 } else { 487 retval = 0; 488 } 489 ISP_UNLOCK(isp); 490 } 491 break; 492 493 case ISP_FC_LIP: 494 if (IS_FC(isp)) { 495 chan = *(int *)addr; 496 if (chan < 0 || chan >= isp->isp_nchan) { 497 retval = -ENXIO; 498 break; 499 } 500 ISP_LOCK(isp); 501 if (isp_control(isp, ISPCTL_SEND_LIP, chan)) { 502 retval = EIO; 503 } else { 504 retval = 0; 505 } 506 ISP_UNLOCK(isp); 507 } 508 break; 509 case ISP_FC_GETDINFO: 510 { 511 struct isp_fc_device *ifc = (struct isp_fc_device *) addr; 512 fcportdb_t *lp; 513 514 if (IS_SCSI(isp)) { 515 break; 516 } 517 if (ifc->loopid >= MAX_FC_TARG) { 518 retval = EINVAL; 519 break; 520 } 521 lp = &FCPARAM(isp, ifc->chan)->portdb[ifc->loopid]; 522 if (lp->state != FC_PORTDB_STATE_NIL) { 523 ifc->role = (lp->prli_word3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT; 524 ifc->loopid = lp->handle; 525 ifc->portid = lp->portid; 526 ifc->node_wwn = lp->node_wwn; 527 ifc->port_wwn = lp->port_wwn; 528 retval = 0; 529 } else { 530 retval = ENODEV; 531 } 532 break; 533 } 534 case ISP_GET_STATS: 535 { 536 isp_stats_t *sp = (isp_stats_t *) addr; 537 538 ISP_MEMZERO(sp, sizeof (*sp)); 539 sp->isp_stat_version = ISP_STATS_VERSION; 540 sp->isp_type = isp->isp_type; 541 sp->isp_revision = isp->isp_revision; 542 ISP_LOCK(isp); 543 sp->isp_stats[ISP_INTCNT] = isp->isp_intcnt; 544 sp->isp_stats[ISP_INTBOGUS] = isp->isp_intbogus; 545 sp->isp_stats[ISP_INTMBOXC] = isp->isp_intmboxc; 546 sp->isp_stats[ISP_INGOASYNC] = isp->isp_intoasync; 547 sp->isp_stats[ISP_RSLTCCMPLT] = isp->isp_rsltccmplt; 548 sp->isp_stats[ISP_FPHCCMCPLT] = isp->isp_fphccmplt; 549 sp->isp_stats[ISP_RSCCHIWAT] = isp->isp_rscchiwater; 550 sp->isp_stats[ISP_FPCCHIWAT] = isp->isp_fpcchiwater; 551 ISP_UNLOCK(isp); 552 retval = 0; 553 break; 554 } 555 case ISP_CLR_STATS: 556 ISP_LOCK(isp); 557 isp->isp_intcnt = 0; 558 isp->isp_intbogus = 0; 559 isp->isp_intmboxc = 0; 560 isp->isp_intoasync = 0; 561 isp->isp_rsltccmplt = 0; 562 isp->isp_fphccmplt = 0; 563 isp->isp_rscchiwater = 0; 564 isp->isp_fpcchiwater = 0; 565 ISP_UNLOCK(isp); 566 retval = 0; 567 break; 568 case ISP_FC_GETHINFO: 569 { 570 struct isp_hba_device *hba = (struct isp_hba_device *) addr; 571 int chan = hba->fc_channel; 572 573 if (chan < 0 || chan >= isp->isp_nchan) { 574 retval = ENXIO; 575 break; 576 } 577 hba->fc_fw_major = ISP_FW_MAJORX(isp->isp_fwrev); 578 hba->fc_fw_minor = ISP_FW_MINORX(isp->isp_fwrev); 579 hba->fc_fw_micro = ISP_FW_MICROX(isp->isp_fwrev); 580 hba->fc_nchannels = isp->isp_nchan; 581 if (IS_FC(isp)) { 582 hba->fc_nports = MAX_FC_TARG; 583 hba->fc_speed = FCPARAM(isp, hba->fc_channel)->isp_gbspeed; 584 hba->fc_topology = FCPARAM(isp, chan)->isp_topo + 1; 585 hba->fc_loopid = FCPARAM(isp, chan)->isp_loopid; 586 hba->nvram_node_wwn = FCPARAM(isp, chan)->isp_wwnn_nvram; 587 hba->nvram_port_wwn = FCPARAM(isp, chan)->isp_wwpn_nvram; 588 hba->active_node_wwn = FCPARAM(isp, chan)->isp_wwnn; 589 hba->active_port_wwn = FCPARAM(isp, chan)->isp_wwpn; 590 } else { 591 hba->fc_nports = MAX_TARGETS; 592 hba->fc_speed = 0; 593 hba->fc_topology = 0; 594 hba->nvram_node_wwn = 0ull; 595 hba->nvram_port_wwn = 0ull; 596 hba->active_node_wwn = 0ull; 597 hba->active_port_wwn = 0ull; 598 } 599 retval = 0; 600 break; 601 } 602 case ISP_TSK_MGMT: 603 { 604 int needmarker; 605 struct isp_fc_tsk_mgmt *fct = (struct isp_fc_tsk_mgmt *) addr; 606 uint16_t nphdl; 607 mbreg_t mbs; 608 609 if (IS_SCSI(isp)) { 610 break; 611 } 612 613 chan = fct->chan; 614 if (chan < 0 || chan >= isp->isp_nchan) { 615 retval = -ENXIO; 616 break; 617 } 618 619 needmarker = retval = 0; 620 nphdl = fct->loopid; 621 ISP_LOCK(isp); 622 if (IS_24XX(isp)) { 623 uint8_t local[QENTRY_LEN]; 624 isp24xx_tmf_t *tmf; 625 isp24xx_statusreq_t *sp; 626 fcparam *fcp = FCPARAM(isp, chan); 627 fcportdb_t *lp; 628 int i; 629 630 for (i = 0; i < MAX_FC_TARG; i++) { 631 lp = &fcp->portdb[i]; 632 if (lp->handle == nphdl) { 633 break; 634 } 635 } 636 if (i == MAX_FC_TARG) { 637 retval = ENXIO; 638 ISP_UNLOCK(isp); 639 break; 640 } 641 /* XXX VALIDATE LP XXX */ 642 tmf = (isp24xx_tmf_t *) local; 643 ISP_MEMZERO(tmf, QENTRY_LEN); 644 tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT; 645 tmf->tmf_header.rqs_entry_count = 1; 646 tmf->tmf_nphdl = lp->handle; 647 tmf->tmf_delay = 2; 648 tmf->tmf_timeout = 2; 649 tmf->tmf_tidlo = lp->portid; 650 tmf->tmf_tidhi = lp->portid >> 16; 651 tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan); 652 tmf->tmf_lun[1] = fct->lun & 0xff; 653 if (fct->lun >= 256) { 654 tmf->tmf_lun[0] = 0x40 | (fct->lun >> 8); 655 } 656 switch (fct->action) { 657 case IPT_CLEAR_ACA: 658 tmf->tmf_flags = ISP24XX_TMF_CLEAR_ACA; 659 break; 660 case IPT_TARGET_RESET: 661 tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET; 662 needmarker = 1; 663 break; 664 case IPT_LUN_RESET: 665 tmf->tmf_flags = ISP24XX_TMF_LUN_RESET; 666 needmarker = 1; 667 break; 668 case IPT_CLEAR_TASK_SET: 669 tmf->tmf_flags = ISP24XX_TMF_CLEAR_TASK_SET; 670 needmarker = 1; 671 break; 672 case IPT_ABORT_TASK_SET: 673 tmf->tmf_flags = ISP24XX_TMF_ABORT_TASK_SET; 674 needmarker = 1; 675 break; 676 default: 677 retval = EINVAL; 678 break; 679 } 680 if (retval) { 681 ISP_UNLOCK(isp); 682 break; 683 } 684 MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000); 685 mbs.param[1] = QENTRY_LEN; 686 mbs.param[2] = DMA_WD1(fcp->isp_scdma); 687 mbs.param[3] = DMA_WD0(fcp->isp_scdma); 688 mbs.param[6] = DMA_WD3(fcp->isp_scdma); 689 mbs.param[7] = DMA_WD2(fcp->isp_scdma); 690 691 if (FC_SCRATCH_ACQUIRE(isp, chan)) { 692 ISP_UNLOCK(isp); 693 retval = ENOMEM; 694 break; 695 } 696 isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch); 697 MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan); 698 sp = (isp24xx_statusreq_t *) local; 699 sp->req_completion_status = 1; 700 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 701 MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan); 702 isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp); 703 FC_SCRATCH_RELEASE(isp, chan); 704 if (retval || sp->req_completion_status != 0) { 705 FC_SCRATCH_RELEASE(isp, chan); 706 retval = EIO; 707 } 708 if (retval == 0) { 709 if (needmarker) { 710 fcp->sendmarker = 1; 711 } 712 } 713 } else { 714 MBSINIT(&mbs, 0, MBLOGALL, 0); 715 if (ISP_CAP_2KLOGIN(isp) == 0) { 716 nphdl <<= 8; 717 } 718 switch (fct->action) { 719 case IPT_CLEAR_ACA: 720 mbs.param[0] = MBOX_CLEAR_ACA; 721 mbs.param[1] = nphdl; 722 mbs.param[2] = fct->lun; 723 break; 724 case IPT_TARGET_RESET: 725 mbs.param[0] = MBOX_TARGET_RESET; 726 mbs.param[1] = nphdl; 727 needmarker = 1; 728 break; 729 case IPT_LUN_RESET: 730 mbs.param[0] = MBOX_LUN_RESET; 731 mbs.param[1] = nphdl; 732 mbs.param[2] = fct->lun; 733 needmarker = 1; 734 break; 735 case IPT_CLEAR_TASK_SET: 736 mbs.param[0] = MBOX_CLEAR_TASK_SET; 737 mbs.param[1] = nphdl; 738 mbs.param[2] = fct->lun; 739 needmarker = 1; 740 break; 741 case IPT_ABORT_TASK_SET: 742 mbs.param[0] = MBOX_ABORT_TASK_SET; 743 mbs.param[1] = nphdl; 744 mbs.param[2] = fct->lun; 745 needmarker = 1; 746 break; 747 default: 748 retval = EINVAL; 749 break; 750 } 751 if (retval == 0) { 752 if (needmarker) { 753 FCPARAM(isp, chan)->sendmarker = 1; 754 } 755 retval = isp_control(isp, ISPCTL_RUN_MBOXCMD, &mbs); 756 if (retval) { 757 retval = EIO; 758 } 759 } 760 } 761 ISP_UNLOCK(isp); 762 break; 763 } 764 default: 765 break; 766 } 767 return (retval); 768 } 769 770 static void 771 isp_intr_enable(void *arg) 772 { 773 int chan; 774 ispsoftc_t *isp = arg; 775 ISP_LOCK(isp); 776 if (IS_FC(isp)) { 777 for (chan = 0; chan < isp->isp_nchan; chan++) { 778 if (FCPARAM(isp, chan)->role != ISP_ROLE_NONE) { 779 ISP_ENABLE_INTS(isp); 780 break; 781 } 782 } 783 } else { 784 ISP_ENABLE_INTS(isp); 785 } 786 isp->isp_osinfo.ehook_active = 0; 787 ISP_UNLOCK(isp); 788 /* Release our hook so that the boot can continue. */ 789 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 790 } 791 792 /* 793 * Local Inlines 794 */ 795 796 static ISP_INLINE int isp_get_pcmd(ispsoftc_t *, union ccb *); 797 static ISP_INLINE void isp_free_pcmd(ispsoftc_t *, union ccb *); 798 799 static ISP_INLINE int 800 isp_get_pcmd(ispsoftc_t *isp, union ccb *ccb) 801 { 802 ISP_PCMD(ccb) = isp->isp_osinfo.pcmd_free; 803 if (ISP_PCMD(ccb) == NULL) { 804 return (-1); 805 } 806 isp->isp_osinfo.pcmd_free = ((struct isp_pcmd *)ISP_PCMD(ccb))->next; 807 return (0); 808 } 809 810 static ISP_INLINE void 811 isp_free_pcmd(ispsoftc_t *isp, union ccb *ccb) 812 { 813 if (ISP_PCMD(ccb)) { 814 #ifdef ISP_TARGET_MODE 815 PISP_PCMD(ccb)->datalen = 0; 816 PISP_PCMD(ccb)->totslen = 0; 817 PISP_PCMD(ccb)->cumslen = 0; 818 PISP_PCMD(ccb)->crn = 0; 819 #endif 820 PISP_PCMD(ccb)->next = isp->isp_osinfo.pcmd_free; 821 isp->isp_osinfo.pcmd_free = ISP_PCMD(ccb); 822 ISP_PCMD(ccb) = NULL; 823 } 824 } 825 826 /* 827 * Put the target mode functions here, because some are inlines 828 */ 829 #ifdef ISP_TARGET_MODE 830 static ISP_INLINE int is_lun_enabled(ispsoftc_t *, int, lun_id_t); 831 static ISP_INLINE tstate_t *get_lun_statep(ispsoftc_t *, int, lun_id_t); 832 static ISP_INLINE tstate_t *get_lun_statep_from_tag(ispsoftc_t *, int, uint32_t); 833 static ISP_INLINE void rls_lun_statep(ispsoftc_t *, tstate_t *); 834 static ISP_INLINE inot_private_data_t *get_ntp_from_tagdata(ispsoftc_t *, uint32_t, uint32_t, tstate_t **); 835 static ISP_INLINE atio_private_data_t *isp_get_atpd(ispsoftc_t *, tstate_t *, uint32_t); 836 static ISP_INLINE atio_private_data_t *isp_find_atpd(ispsoftc_t *, tstate_t *, uint32_t); 837 static ISP_INLINE void isp_put_atpd(ispsoftc_t *, tstate_t *, atio_private_data_t *); 838 static ISP_INLINE inot_private_data_t *isp_get_ntpd(ispsoftc_t *, tstate_t *); 839 static ISP_INLINE inot_private_data_t *isp_find_ntpd(ispsoftc_t *, tstate_t *, uint32_t, uint32_t); 840 static ISP_INLINE void isp_put_ntpd(ispsoftc_t *, tstate_t *, inot_private_data_t *); 841 static cam_status create_lun_state(ispsoftc_t *, int, struct cam_path *, tstate_t **); 842 static void destroy_lun_state(ispsoftc_t *, tstate_t *); 843 static void isp_enable_lun(ispsoftc_t *, union ccb *); 844 static void isp_disable_lun(ispsoftc_t *, union ccb *); 845 static timeout_t isp_refire_putback_atio; 846 static timeout_t isp_refire_notify_ack; 847 static void isp_complete_ctio(union ccb *); 848 static void isp_target_putback_atio(union ccb *); 849 enum Start_Ctio_How { FROM_CAM, FROM_TIMER, FROM_SRR, FROM_CTIO_DONE }; 850 static void isp_target_start_ctio(ispsoftc_t *, union ccb *, enum Start_Ctio_How); 851 static void isp_handle_platform_atio2(ispsoftc_t *, at2_entry_t *); 852 static void isp_handle_platform_atio7(ispsoftc_t *, at7_entry_t *); 853 static void isp_handle_platform_ctio(ispsoftc_t *, void *); 854 static void isp_handle_platform_notify_fc(ispsoftc_t *, in_fcentry_t *); 855 static void isp_handle_platform_notify_24xx(ispsoftc_t *, in_fcentry_24xx_t *); 856 static int isp_handle_platform_target_notify_ack(ispsoftc_t *, isp_notify_t *); 857 static void isp_handle_platform_target_tmf(ispsoftc_t *, isp_notify_t *); 858 static void isp_target_mark_aborted(ispsoftc_t *, union ccb *); 859 static void isp_target_mark_aborted_early(ispsoftc_t *, tstate_t *, uint32_t); 860 861 static ISP_INLINE int 862 is_lun_enabled(ispsoftc_t *isp, int bus, lun_id_t lun) 863 { 864 tstate_t *tptr; 865 struct tslist *lhp; 866 867 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 868 SLIST_FOREACH(tptr, lhp, next) { 869 if (tptr->ts_lun == lun) { 870 return (1); 871 } 872 } 873 return (0); 874 } 875 876 static void 877 dump_tstates(ispsoftc_t *isp, int bus) 878 { 879 int i, j; 880 struct tslist *lhp; 881 tstate_t *tptr = NULL; 882 883 if (bus >= isp->isp_nchan) { 884 return; 885 } 886 for (i = 0; i < LUN_HASH_SIZE; i++) { 887 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 888 j = 0; 889 SLIST_FOREACH(tptr, lhp, next) { 890 xpt_print(tptr->owner, "[%d, %d] atio_cnt=%d inot_cnt=%d\n", i, j, tptr->atio_count, tptr->inot_count); 891 j++; 892 } 893 } 894 } 895 896 static ISP_INLINE tstate_t * 897 get_lun_statep(ispsoftc_t *isp, int bus, lun_id_t lun) 898 { 899 tstate_t *tptr = NULL; 900 struct tslist *lhp; 901 902 if (bus < isp->isp_nchan) { 903 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 904 SLIST_FOREACH(tptr, lhp, next) { 905 if (tptr->ts_lun == lun) { 906 tptr->hold++; 907 return (tptr); 908 } 909 } 910 } 911 return (NULL); 912 } 913 914 static ISP_INLINE tstate_t * 915 get_lun_statep_from_tag(ispsoftc_t *isp, int bus, uint32_t tagval) 916 { 917 tstate_t *tptr = NULL; 918 atio_private_data_t *atp; 919 struct tslist *lhp; 920 int i; 921 922 if (bus < isp->isp_nchan && tagval != 0) { 923 for (i = 0; i < LUN_HASH_SIZE; i++) { 924 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 925 SLIST_FOREACH(tptr, lhp, next) { 926 atp = isp_find_atpd(isp, tptr, tagval); 927 if (atp) { 928 tptr->hold++; 929 return (tptr); 930 } 931 } 932 } 933 } 934 return (NULL); 935 } 936 937 static ISP_INLINE inot_private_data_t * 938 get_ntp_from_tagdata(ispsoftc_t *isp, uint32_t tag_id, uint32_t seq_id, tstate_t **rslt) 939 { 940 inot_private_data_t *ntp; 941 tstate_t *tptr; 942 struct tslist *lhp; 943 int bus, i; 944 945 for (bus = 0; bus < isp->isp_nchan; bus++) { 946 for (i = 0; i < LUN_HASH_SIZE; i++) { 947 ISP_GET_PC_ADDR(isp, bus, lun_hash[i], lhp); 948 SLIST_FOREACH(tptr, lhp, next) { 949 ntp = isp_find_ntpd(isp, tptr, tag_id, seq_id); 950 if (ntp) { 951 *rslt = tptr; 952 tptr->hold++; 953 return (ntp); 954 } 955 } 956 } 957 } 958 return (NULL); 959 } 960 961 static ISP_INLINE void 962 rls_lun_statep(ispsoftc_t *isp, tstate_t *tptr) 963 { 964 KASSERT((tptr->hold), ("tptr not held")); 965 tptr->hold--; 966 } 967 968 static void 969 isp_tmcmd_restart(ispsoftc_t *isp) 970 { 971 inot_private_data_t *ntp; 972 inot_private_data_t *restart_queue; 973 tstate_t *tptr; 974 union ccb *ccb; 975 struct tslist *lhp; 976 int bus, i; 977 978 for (bus = 0; bus < isp->isp_nchan; bus++) { 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 if ((restart_queue = tptr->restart_queue) != NULL) 983 tptr->restart_queue = NULL; 984 while (restart_queue) { 985 ntp = restart_queue; 986 restart_queue = ntp->rd.nt.nt_hba; 987 if (IS_24XX(isp)) { 988 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid); 989 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data); 990 } else { 991 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid); 992 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data); 993 } 994 isp_put_ntpd(isp, tptr, ntp); 995 if (tptr->restart_queue && restart_queue != NULL) { 996 ntp = tptr->restart_queue; 997 tptr->restart_queue = restart_queue; 998 while (restart_queue->rd.nt.nt_hba) { 999 restart_queue = restart_queue->rd.nt.nt_hba; 1000 } 1001 restart_queue->rd.nt.nt_hba = ntp; 1002 break; 1003 } 1004 } 1005 /* 1006 * We only need to do this once per tptr 1007 */ 1008 if (!TAILQ_EMPTY(&tptr->waitq)) { 1009 ccb = (union ccb *)TAILQ_LAST(&tptr->waitq, isp_ccbq); 1010 TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1011 isp_target_start_ctio(isp, ccb, FROM_TIMER); 1012 } 1013 } 1014 } 1015 } 1016 } 1017 1018 static ISP_INLINE atio_private_data_t * 1019 isp_get_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag) 1020 { 1021 atio_private_data_t *atp; 1022 1023 atp = LIST_FIRST(&tptr->atfree); 1024 if (atp) { 1025 LIST_REMOVE(atp, next); 1026 atp->tag = tag; 1027 LIST_INSERT_HEAD(&tptr->atused[ATPDPHASH(tag)], atp, next); 1028 } 1029 return (atp); 1030 } 1031 1032 static ISP_INLINE atio_private_data_t * 1033 isp_find_atpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag) 1034 { 1035 atio_private_data_t *atp; 1036 1037 LIST_FOREACH(atp, &tptr->atused[ATPDPHASH(tag)], next) { 1038 if (atp->tag == tag) 1039 return (atp); 1040 } 1041 return (NULL); 1042 } 1043 1044 static ISP_INLINE void 1045 isp_put_atpd(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp) 1046 { 1047 if (atp->ests) { 1048 isp_put_ecmd(isp, atp->ests); 1049 } 1050 LIST_REMOVE(atp, next); 1051 memset(atp, 0, sizeof (*atp)); 1052 LIST_INSERT_HEAD(&tptr->atfree, atp, next); 1053 } 1054 1055 static void 1056 isp_dump_atpd(ispsoftc_t *isp, tstate_t *tptr) 1057 { 1058 atio_private_data_t *atp; 1059 const char *states[8] = { "Free", "ATIO", "CAM", "CTIO", "LAST_CTIO", "PDON", "?6", "7" }; 1060 1061 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) { 1062 xpt_print(tptr->owner, "ATP: [0x%x] origdlen %u bytes_xfrd %u lun %x nphdl 0x%04x s_id 0x%06x d_id 0x%06x oxid 0x%04x state %s\n", 1063 atp->tag, atp->orig_datalen, atp->bytes_xfered, atp->lun, atp->nphdl, atp->sid, atp->portid, atp->oxid, states[atp->state & 0x7]); 1064 } 1065 } 1066 1067 1068 static ISP_INLINE inot_private_data_t * 1069 isp_get_ntpd(ispsoftc_t *isp, tstate_t *tptr) 1070 { 1071 inot_private_data_t *ntp; 1072 ntp = tptr->ntfree; 1073 if (ntp) { 1074 tptr->ntfree = ntp->next; 1075 } 1076 return (ntp); 1077 } 1078 1079 static ISP_INLINE inot_private_data_t * 1080 isp_find_ntpd(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id, uint32_t seq_id) 1081 { 1082 inot_private_data_t *ntp; 1083 for (ntp = tptr->ntpool; ntp < &tptr->ntpool[ATPDPSIZE]; ntp++) { 1084 if (ntp->rd.tag_id == tag_id && ntp->rd.seq_id == seq_id) { 1085 return (ntp); 1086 } 1087 } 1088 return (NULL); 1089 } 1090 1091 static ISP_INLINE void 1092 isp_put_ntpd(ispsoftc_t *isp, tstate_t *tptr, inot_private_data_t *ntp) 1093 { 1094 ntp->rd.tag_id = ntp->rd.seq_id = 0; 1095 ntp->next = tptr->ntfree; 1096 tptr->ntfree = ntp; 1097 } 1098 1099 static cam_status 1100 create_lun_state(ispsoftc_t *isp, int bus, struct cam_path *path, tstate_t **rslt) 1101 { 1102 cam_status status; 1103 lun_id_t lun; 1104 struct tslist *lhp; 1105 tstate_t *tptr; 1106 int i; 1107 1108 lun = xpt_path_lun_id(path); 1109 if (lun != CAM_LUN_WILDCARD) { 1110 if (ISP_MAX_LUNS(isp) > 0 && lun >= ISP_MAX_LUNS(isp)) { 1111 return (CAM_LUN_INVALID); 1112 } 1113 } 1114 if (is_lun_enabled(isp, bus, lun)) { 1115 return (CAM_LUN_ALRDY_ENA); 1116 } 1117 tptr = malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO); 1118 if (tptr == NULL) { 1119 return (CAM_RESRC_UNAVAIL); 1120 } 1121 tptr->ts_lun = lun; 1122 status = xpt_create_path(&tptr->owner, NULL, xpt_path_path_id(path), xpt_path_target_id(path), lun); 1123 if (status != CAM_REQ_CMP) { 1124 free(tptr, M_DEVBUF); 1125 return (status); 1126 } 1127 SLIST_INIT(&tptr->atios); 1128 SLIST_INIT(&tptr->inots); 1129 TAILQ_INIT(&tptr->waitq); 1130 LIST_INIT(&tptr->atfree); 1131 for (i = ATPDPSIZE-1; i >= 0; i--) 1132 LIST_INSERT_HEAD(&tptr->atfree, &tptr->atpool[i], next); 1133 for (i = 0; i < ATPDPHASHSIZE; i++) 1134 LIST_INIT(&tptr->atused[i]); 1135 for (i = 0; i < ATPDPSIZE-1; i++) 1136 tptr->ntpool[i].next = &tptr->ntpool[i+1]; 1137 tptr->ntfree = tptr->ntpool; 1138 tptr->hold = 1; 1139 ISP_GET_PC_ADDR(isp, bus, lun_hash[LUN_HASH_FUNC(lun)], lhp); 1140 SLIST_INSERT_HEAD(lhp, tptr, next); 1141 *rslt = tptr; 1142 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, path, "created tstate\n"); 1143 return (CAM_REQ_CMP); 1144 } 1145 1146 static ISP_INLINE void 1147 destroy_lun_state(ispsoftc_t *isp, tstate_t *tptr) 1148 { 1149 union ccb *ccb; 1150 struct tslist *lhp; 1151 1152 KASSERT((tptr->hold != 0), ("tptr is not held")); 1153 KASSERT((tptr->hold == 1), ("tptr still held (%d)", tptr->hold)); 1154 do { 1155 ccb = (union ccb *)SLIST_FIRST(&tptr->atios); 1156 if (ccb) { 1157 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1158 ccb->ccb_h.status = CAM_REQ_ABORTED; 1159 xpt_done(ccb); 1160 } 1161 } while (ccb); 1162 do { 1163 ccb = (union ccb *)SLIST_FIRST(&tptr->inots); 1164 if (ccb) { 1165 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 1166 ccb->ccb_h.status = CAM_REQ_ABORTED; 1167 xpt_done(ccb); 1168 } 1169 } while (ccb); 1170 ISP_GET_PC_ADDR(isp, cam_sim_bus(xpt_path_sim(tptr->owner)), lun_hash[LUN_HASH_FUNC(tptr->ts_lun)], lhp); 1171 SLIST_REMOVE(lhp, tptr, tstate, next); 1172 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0, tptr->owner, "destroyed tstate\n"); 1173 xpt_free_path(tptr->owner); 1174 free(tptr, M_DEVBUF); 1175 } 1176 1177 static void 1178 isp_enable_lun(ispsoftc_t *isp, union ccb *ccb) 1179 { 1180 tstate_t *tptr; 1181 int bus; 1182 target_id_t target; 1183 lun_id_t lun; 1184 1185 if (!IS_FC(isp) || !ISP_CAP_TMODE(isp) || !ISP_CAP_SCCFW(isp)) { 1186 xpt_print(ccb->ccb_h.path, "Target mode is not supported\n"); 1187 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 1188 xpt_done(ccb); 1189 return; 1190 } 1191 1192 /* 1193 * We only support either target and lun both wildcard 1194 * or target and lun both non-wildcard. 1195 */ 1196 bus = XS_CHANNEL(ccb); 1197 target = ccb->ccb_h.target_id; 1198 lun = ccb->ccb_h.target_lun; 1199 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, 1200 "enabling lun %jx\n", (uintmax_t)lun); 1201 if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) { 1202 ccb->ccb_h.status = CAM_LUN_INVALID; 1203 xpt_done(ccb); 1204 return; 1205 } 1206 1207 /* Create the state pointer. It should not already exist. */ 1208 tptr = get_lun_statep(isp, bus, lun); 1209 if (tptr) { 1210 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 1211 xpt_done(ccb); 1212 return; 1213 } 1214 ccb->ccb_h.status = create_lun_state(isp, bus, ccb->ccb_h.path, &tptr); 1215 if (ccb->ccb_h.status != CAM_REQ_CMP) { 1216 xpt_done(ccb); 1217 return; 1218 } 1219 1220 rls_lun_statep(isp, tptr); 1221 ccb->ccb_h.status = CAM_REQ_CMP; 1222 xpt_done(ccb); 1223 } 1224 1225 static void 1226 isp_disable_lun(ispsoftc_t *isp, union ccb *ccb) 1227 { 1228 tstate_t *tptr = NULL; 1229 int bus; 1230 target_id_t target; 1231 lun_id_t lun; 1232 1233 bus = XS_CHANNEL(ccb); 1234 target = ccb->ccb_h.target_id; 1235 lun = ccb->ccb_h.target_lun; 1236 ISP_PATH_PRT(isp, ISP_LOGTDEBUG0|ISP_LOGCONFIG, ccb->ccb_h.path, 1237 "disabling lun %jx\n", (uintmax_t)lun); 1238 if ((target == CAM_TARGET_WILDCARD) != (lun == CAM_LUN_WILDCARD)) { 1239 ccb->ccb_h.status = CAM_LUN_INVALID; 1240 xpt_done(ccb); 1241 return; 1242 } 1243 1244 /* Find the state pointer. */ 1245 if ((tptr = get_lun_statep(isp, bus, lun)) == NULL) { 1246 ccb->ccb_h.status = CAM_PATH_INVALID; 1247 xpt_done(ccb); 1248 return; 1249 } 1250 1251 destroy_lun_state(isp, tptr); 1252 ccb->ccb_h.status = CAM_REQ_CMP; 1253 xpt_done(ccb); 1254 } 1255 1256 static void 1257 isp_target_start_ctio(ispsoftc_t *isp, union ccb *ccb, enum Start_Ctio_How how) 1258 { 1259 int fctape, sendstatus, resid; 1260 tstate_t *tptr; 1261 fcparam *fcp; 1262 atio_private_data_t *atp; 1263 struct ccb_scsiio *cso; 1264 uint32_t dmaresult, handle, xfrlen, sense_length, tmp; 1265 uint8_t local[QENTRY_LEN]; 1266 1267 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), XS_LUN(ccb)); 1268 if (tptr == NULL) { 1269 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD); 1270 if (tptr == NULL) { 1271 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find tstate pointer", __func__, ccb->csio.tag_id); 1272 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 1273 xpt_done(ccb); 1274 return; 1275 } 1276 } 1277 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, 1278 (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0, ((ccb->ccb_h.flags & CAM_SEND_SENSE)? ccb->csio.sense_len : 0)); 1279 1280 switch (how) { 1281 case FROM_TIMER: 1282 case FROM_CAM: 1283 /* 1284 * Insert at the tail of the list, if any, waiting CTIO CCBs 1285 */ 1286 TAILQ_INSERT_TAIL(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1287 break; 1288 case FROM_SRR: 1289 case FROM_CTIO_DONE: 1290 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1291 break; 1292 } 1293 1294 while (TAILQ_FIRST(&tptr->waitq) != NULL) { 1295 ccb = (union ccb *) TAILQ_FIRST(&tptr->waitq); 1296 TAILQ_REMOVE(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1297 1298 cso = &ccb->csio; 1299 xfrlen = cso->dxfer_len; 1300 if (xfrlen == 0) { 1301 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) == 0) { 1302 ISP_PATH_PRT(isp, ISP_LOGERR, ccb->ccb_h.path, "a data transfer length of zero but no status to send is wrong\n"); 1303 ccb->ccb_h.status = CAM_REQ_INVALID; 1304 xpt_done(ccb); 1305 continue; 1306 } 1307 } 1308 1309 atp = isp_find_atpd(isp, tptr, cso->tag_id); 1310 if (atp == NULL) { 1311 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] cannot find private data adjunct in %s", __func__, cso->tag_id, __func__); 1312 isp_dump_atpd(isp, tptr); 1313 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1314 xpt_done(ccb); 1315 continue; 1316 } 1317 1318 /* 1319 * Is this command a dead duck? 1320 */ 1321 if (atp->dead) { 1322 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] not sending a CTIO for a dead command", __func__, cso->tag_id); 1323 ccb->ccb_h.status = CAM_REQ_ABORTED; 1324 xpt_done(ccb); 1325 continue; 1326 } 1327 1328 /* 1329 * Check to make sure we're still in target mode. 1330 */ 1331 fcp = FCPARAM(isp, XS_CHANNEL(ccb)); 1332 if ((fcp->role & ISP_ROLE_TARGET) == 0) { 1333 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] stopping sending a CTIO because we're no longer in target mode", __func__, cso->tag_id); 1334 ccb->ccb_h.status = CAM_PROVIDE_FAIL; 1335 xpt_done(ccb); 1336 continue; 1337 } 1338 1339 /* 1340 * We're only handling ATPD_CCB_OUTSTANDING outstanding CCB at a time (one of which 1341 * could be split into two CTIOs to split data and status). 1342 */ 1343 if (atp->ctcnt >= ATPD_CCB_OUTSTANDING) { 1344 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); 1345 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1346 break; 1347 } 1348 1349 /* 1350 * Does the initiator expect FC-Tape style responses? 1351 */ 1352 if ((atp->word3 & PRLI_WD3_RETRY) && fcp->fctape_enabled) { 1353 fctape = 1; 1354 } else { 1355 fctape = 0; 1356 } 1357 1358 /* 1359 * If we already did the data xfer portion of a CTIO that sends data 1360 * and status, don't do it again and do the status portion now. 1361 */ 1362 if (atp->sendst) { 1363 isp_prt(isp, ISP_LOGTINFO, "[0x%x] now sending synthesized status orig_dl=%u xfered=%u bit=%u", 1364 cso->tag_id, atp->orig_datalen, atp->bytes_xfered, atp->bytes_in_transit); 1365 xfrlen = 0; /* we already did the data transfer */ 1366 atp->sendst = 0; 1367 } 1368 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 1369 sendstatus = 1; 1370 } else { 1371 sendstatus = 0; 1372 } 1373 1374 if (ccb->ccb_h.flags & CAM_SEND_SENSE) { 1375 KASSERT((sendstatus != 0), ("how can you have CAM_SEND_SENSE w/o CAM_SEND_STATUS?")); 1376 /* 1377 * Sense length is not the entire sense data structure size. Periph 1378 * drivers don't seem to be setting sense_len to reflect the actual 1379 * size. We'll peek inside to get the right amount. 1380 */ 1381 sense_length = cso->sense_len; 1382 1383 /* 1384 * This 'cannot' happen 1385 */ 1386 if (sense_length > (XCMD_SIZE - MIN_FCP_RESPONSE_SIZE)) { 1387 sense_length = XCMD_SIZE - MIN_FCP_RESPONSE_SIZE; 1388 } 1389 } else { 1390 sense_length = 0; 1391 } 1392 1393 memset(local, 0, QENTRY_LEN); 1394 1395 /* 1396 * Check for overflow 1397 */ 1398 tmp = atp->bytes_xfered + atp->bytes_in_transit + xfrlen; 1399 if (tmp > atp->orig_datalen) { 1400 isp_prt(isp, ISP_LOGERR, "%s: [0x%x] data overflow by %u bytes", __func__, cso->tag_id, tmp - atp->orig_datalen); 1401 ccb->ccb_h.status = CAM_DATA_RUN_ERR; 1402 xpt_done(ccb); 1403 continue; 1404 } 1405 1406 if (IS_24XX(isp)) { 1407 ct7_entry_t *cto = (ct7_entry_t *) local; 1408 1409 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 1410 cto->ct_header.rqs_entry_count = 1; 1411 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM; 1412 ATPD_SET_SEQNO(cto, atp); 1413 cto->ct_nphdl = atp->nphdl; 1414 cto->ct_rxid = atp->tag; 1415 cto->ct_iid_lo = atp->portid; 1416 cto->ct_iid_hi = atp->portid >> 16; 1417 cto->ct_oxid = atp->oxid; 1418 cto->ct_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(ccb)); 1419 cto->ct_timeout = 120; 1420 cto->ct_flags = atp->tattr << CT7_TASK_ATTR_SHIFT; 1421 1422 /* 1423 * Mode 1, status, no data. Only possible when we are sending status, have 1424 * no data to transfer, and any sense data can fit into a ct7_entry_t. 1425 * 1426 * Mode 2, status, no data. We have to use this in the case that 1427 * the sense data won't fit into a ct7_entry_t. 1428 * 1429 */ 1430 if (sendstatus && xfrlen == 0) { 1431 cto->ct_flags |= CT7_SENDSTATUS | CT7_NO_DATA; 1432 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 1433 if (sense_length <= MAXRESPLEN_24XX) { 1434 if (resid < 0) { 1435 cto->ct_resid = -resid; 1436 } else if (resid > 0) { 1437 cto->ct_resid = resid; 1438 } 1439 cto->ct_flags |= CT7_FLAG_MODE1; 1440 cto->ct_scsi_status = cso->scsi_status; 1441 if (resid < 0) { 1442 cto->ct_scsi_status |= (FCP_RESID_OVERFLOW << 8); 1443 } else if (resid > 0) { 1444 cto->ct_scsi_status |= (FCP_RESID_UNDERFLOW << 8); 1445 } 1446 if (fctape) { 1447 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1448 } 1449 if (sense_length) { 1450 cto->ct_scsi_status |= (FCP_SNSLEN_VALID << 8); 1451 cto->rsp.m1.ct_resplen = cto->ct_senselen = sense_length; 1452 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length); 1453 } 1454 } else { 1455 bus_addr_t addr; 1456 char buf[XCMD_SIZE]; 1457 fcp_rsp_iu_t *rp; 1458 1459 if (atp->ests == NULL) { 1460 atp->ests = isp_get_ecmd(isp); 1461 if (atp->ests == NULL) { 1462 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1463 break; 1464 } 1465 } 1466 memset(buf, 0, sizeof (buf)); 1467 rp = (fcp_rsp_iu_t *)buf; 1468 if (fctape) { 1469 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1470 rp->fcp_rsp_bits |= FCP_CONF_REQ; 1471 } 1472 cto->ct_flags |= CT7_FLAG_MODE2; 1473 rp->fcp_rsp_scsi_status = cso->scsi_status; 1474 if (resid < 0) { 1475 rp->fcp_rsp_resid = -resid; 1476 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW; 1477 } else if (resid > 0) { 1478 rp->fcp_rsp_resid = resid; 1479 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW; 1480 } 1481 if (sense_length) { 1482 rp->fcp_rsp_snslen = sense_length; 1483 cto->ct_senselen = sense_length; 1484 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID; 1485 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1486 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length); 1487 } else { 1488 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1489 } 1490 if (isp->isp_dblev & ISP_LOGTDEBUG1) { 1491 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); 1492 } 1493 addr = isp->isp_osinfo.ecmd_dma; 1494 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); 1495 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, 1496 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length); 1497 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length; 1498 cto->rsp.m2.ct_fcp_rsp_iudata.ds_base = DMA_LO32(addr); 1499 cto->rsp.m2.ct_fcp_rsp_iudata.ds_basehi = DMA_HI32(addr); 1500 cto->rsp.m2.ct_fcp_rsp_iudata.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 1501 } 1502 if (sense_length) { 1503 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__, 1504 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, 1505 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]); 1506 } else { 1507 isp_prt(isp, ISP_LOGDEBUG0, "%s: CTIO7[0x%x] seq %u nc %d CDB0=%x sstatus=0x%x flags=0x%x resid=%d", __func__, 1508 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, cto->ct_resid); 1509 } 1510 atp->state = ATPD_STATE_LAST_CTIO; 1511 } 1512 1513 /* 1514 * Mode 0 data transfers, *possibly* with status. 1515 */ 1516 if (xfrlen != 0) { 1517 cto->ct_flags |= CT7_FLAG_MODE0; 1518 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1519 cto->ct_flags |= CT7_DATA_IN; 1520 } else { 1521 cto->ct_flags |= CT7_DATA_OUT; 1522 } 1523 1524 cto->rsp.m0.reloff = atp->bytes_xfered + atp->bytes_in_transit; 1525 cto->rsp.m0.ct_xfrlen = xfrlen; 1526 1527 #ifdef DEBUG 1528 if (ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame && xfrlen > ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame) { 1529 isp_prt(isp, ISP_LOGWARN, "%s: truncating data frame with xfrlen %d to %d", __func__, xfrlen, xfrlen - (xfrlen >> 2)); 1530 ISP_FC_PC(isp, XS_CHANNEL(ccb))->inject_lost_data_frame = 0; 1531 cto->rsp.m0.ct_xfrlen -= xfrlen >> 2; 1532 } 1533 #endif 1534 if (sendstatus) { 1535 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen; 1536 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /* && fctape == 0 */) { 1537 cto->ct_flags |= CT7_SENDSTATUS; 1538 atp->state = ATPD_STATE_LAST_CTIO; 1539 if (fctape) { 1540 cto->ct_flags |= CT7_CONFIRM|CT7_EXPLCT_CONF; 1541 } 1542 } else { 1543 atp->sendst = 1; /* send status later */ 1544 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM; 1545 atp->state = ATPD_STATE_CTIO; 1546 } 1547 } else { 1548 atp->state = ATPD_STATE_CTIO; 1549 } 1550 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__, 1551 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cto->ct_scsi_status, cto->ct_flags, xfrlen, atp->bytes_xfered); 1552 } 1553 } else { 1554 ct2_entry_t *cto = (ct2_entry_t *) local; 1555 1556 if (isp->isp_osinfo.sixtyfourbit) 1557 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO3; 1558 else 1559 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 1560 cto->ct_header.rqs_entry_count = 1; 1561 cto->ct_header.rqs_seqno |= ATPD_SEQ_NOTIFY_CAM; 1562 ATPD_SET_SEQNO(cto, atp); 1563 if (ISP_CAP_2KLOGIN(isp)) { 1564 ((ct2e_entry_t *)cto)->ct_iid = atp->nphdl; 1565 } else { 1566 cto->ct_iid = atp->nphdl; 1567 if (ISP_CAP_SCCFW(isp) == 0) { 1568 cto->ct_lun = ccb->ccb_h.target_lun; 1569 } 1570 } 1571 cto->ct_timeout = 10; 1572 cto->ct_rxid = cso->tag_id; 1573 1574 /* 1575 * Mode 1, status, no data. Only possible when we are sending status, have 1576 * no data to transfer, and the sense length can fit in the ct7_entry. 1577 * 1578 * Mode 2, status, no data. We have to use this in the case the response 1579 * length won't fit into a ct2_entry_t. 1580 * 1581 * We'll fill out this structure with information as if this were a 1582 * Mode 1. The hardware layer will create the Mode 2 FCP RSP IU as 1583 * needed based upon this. 1584 */ 1585 if (sendstatus && xfrlen == 0) { 1586 cto->ct_flags |= CT2_SENDSTATUS | CT2_NO_DATA; 1587 resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 1588 if (sense_length <= MAXRESPLEN) { 1589 if (resid < 0) { 1590 cto->ct_resid = -resid; 1591 } else if (resid > 0) { 1592 cto->ct_resid = resid; 1593 } 1594 cto->ct_flags |= CT2_FLAG_MODE1; 1595 cto->rsp.m1.ct_scsi_status = cso->scsi_status; 1596 if (resid < 0) { 1597 cto->rsp.m1.ct_scsi_status |= CT2_DATA_OVER; 1598 } else if (resid > 0) { 1599 cto->rsp.m1.ct_scsi_status |= CT2_DATA_UNDER; 1600 } 1601 if (fctape) { 1602 cto->ct_flags |= CT2_CONFIRM; 1603 } 1604 if (sense_length) { 1605 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 1606 cto->rsp.m1.ct_resplen = cto->rsp.m1.ct_senselen = sense_length; 1607 memcpy(cto->rsp.m1.ct_resp, &cso->sense_data, sense_length); 1608 } 1609 } else { 1610 bus_addr_t addr; 1611 char buf[XCMD_SIZE]; 1612 fcp_rsp_iu_t *rp; 1613 1614 if (atp->ests == NULL) { 1615 atp->ests = isp_get_ecmd(isp); 1616 if (atp->ests == NULL) { 1617 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1618 break; 1619 } 1620 } 1621 memset(buf, 0, sizeof (buf)); 1622 rp = (fcp_rsp_iu_t *)buf; 1623 if (fctape) { 1624 cto->ct_flags |= CT2_CONFIRM; 1625 rp->fcp_rsp_bits |= FCP_CONF_REQ; 1626 } 1627 cto->ct_flags |= CT2_FLAG_MODE2; 1628 rp->fcp_rsp_scsi_status = cso->scsi_status; 1629 if (resid < 0) { 1630 rp->fcp_rsp_resid = -resid; 1631 rp->fcp_rsp_bits |= FCP_RESID_OVERFLOW; 1632 } else if (resid > 0) { 1633 rp->fcp_rsp_resid = resid; 1634 rp->fcp_rsp_bits |= FCP_RESID_UNDERFLOW; 1635 } 1636 if (sense_length) { 1637 rp->fcp_rsp_snslen = sense_length; 1638 rp->fcp_rsp_bits |= FCP_SNSLEN_VALID; 1639 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1640 memcpy(((fcp_rsp_iu_t *)atp->ests)->fcp_rsp_extra, &cso->sense_data, sense_length); 1641 } else { 1642 isp_put_fcp_rsp_iu(isp, rp, atp->ests); 1643 } 1644 if (isp->isp_dblev & ISP_LOGTDEBUG1) { 1645 isp_print_bytes(isp, "FCP Response Frame After Swizzling", MIN_FCP_RESPONSE_SIZE + sense_length, atp->ests); 1646 } 1647 addr = isp->isp_osinfo.ecmd_dma; 1648 addr += ((((isp_ecmd_t *)atp->ests) - isp->isp_osinfo.ecmd_base) * XCMD_SIZE); 1649 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, 1650 (uintmax_t) isp->isp_osinfo.ecmd_dma, (uintmax_t)addr, MIN_FCP_RESPONSE_SIZE + sense_length); 1651 cto->rsp.m2.ct_datalen = MIN_FCP_RESPONSE_SIZE + sense_length; 1652 if (isp->isp_osinfo.sixtyfourbit) { 1653 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_base = DMA_LO32(addr); 1654 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_basehi = DMA_HI32(addr); 1655 cto->rsp.m2.u.ct_fcp_rsp_iudata_64.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 1656 } else { 1657 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_base = DMA_LO32(addr); 1658 cto->rsp.m2.u.ct_fcp_rsp_iudata_32.ds_count = MIN_FCP_RESPONSE_SIZE + sense_length; 1659 } 1660 } 1661 if (sense_length) { 1662 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__, 1663 cto->ct_rxid, ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid, 1664 cso->sense_data.error_code, cso->sense_data.sense_buf[1], cso->sense_data.sense_buf[11], cso->sense_data.sense_buf[12]); 1665 } else { 1666 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, 1667 ATPD_GET_SEQNO(cto), ATPD_GET_NCAM(cto), atp->cdb0, cso->scsi_status, cto->ct_flags, cto->ct_resid); 1668 } 1669 atp->state = ATPD_STATE_LAST_CTIO; 1670 } 1671 1672 if (xfrlen != 0) { 1673 cto->ct_flags |= CT2_FLAG_MODE0; 1674 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 1675 cto->ct_flags |= CT2_DATA_IN; 1676 } else { 1677 cto->ct_flags |= CT2_DATA_OUT; 1678 } 1679 1680 cto->ct_reloff = atp->bytes_xfered + atp->bytes_in_transit; 1681 cto->rsp.m0.ct_xfrlen = xfrlen; 1682 1683 if (sendstatus) { 1684 resid = atp->orig_datalen - atp->bytes_xfered - xfrlen; 1685 if (cso->scsi_status == SCSI_STATUS_OK && resid == 0 /*&& fctape == 0*/) { 1686 cto->ct_flags |= CT2_SENDSTATUS; 1687 atp->state = ATPD_STATE_LAST_CTIO; 1688 if (fctape) { 1689 cto->ct_flags |= CT2_CONFIRM; 1690 } 1691 } else { 1692 atp->sendst = 1; /* send status later */ 1693 cto->ct_header.rqs_seqno &= ~ATPD_SEQ_NOTIFY_CAM; 1694 atp->state = ATPD_STATE_CTIO; 1695 } 1696 } else { 1697 atp->state = ATPD_STATE_CTIO; 1698 } 1699 } 1700 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, 1701 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); 1702 } 1703 1704 if (isp_get_pcmd(isp, ccb)) { 1705 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "out of PCMDs\n"); 1706 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1707 break; 1708 } 1709 if (isp_allocate_xs_tgt(isp, ccb, &handle)) { 1710 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "No XFLIST pointers for %s\n", __func__); 1711 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1712 isp_free_pcmd(isp, ccb); 1713 break; 1714 } 1715 atp->bytes_in_transit += xfrlen; 1716 PISP_PCMD(ccb)->datalen = xfrlen; 1717 1718 1719 /* 1720 * Call the dma setup routines for this entry (and any subsequent 1721 * CTIOs) if there's data to move, and then tell the f/w it's got 1722 * new things to play with. As with isp_start's usage of DMA setup, 1723 * any swizzling is done in the machine dependent layer. Because 1724 * of this, we put the request onto the queue area first in native 1725 * format. 1726 */ 1727 1728 if (IS_24XX(isp)) { 1729 ct7_entry_t *cto = (ct7_entry_t *) local; 1730 cto->ct_syshandle = handle; 1731 } else { 1732 ct2_entry_t *cto = (ct2_entry_t *) local; 1733 cto->ct_syshandle = handle; 1734 } 1735 1736 dmaresult = ISP_DMASETUP(isp, cso, (ispreq_t *) local); 1737 if (dmaresult != CMD_QUEUED) { 1738 isp_destroy_tgt_handle(isp, handle); 1739 isp_free_pcmd(isp, ccb); 1740 if (dmaresult == CMD_EAGAIN) { 1741 TAILQ_INSERT_HEAD(&tptr->waitq, &ccb->ccb_h, periph_links.tqe); 1742 break; 1743 } 1744 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1745 xpt_done(ccb); 1746 continue; 1747 } 1748 isp->isp_nactive++; 1749 ccb->ccb_h.status = CAM_REQ_INPROG | CAM_SIM_QUEUED; 1750 if (xfrlen) { 1751 ccb->ccb_h.spriv_field0 = atp->bytes_xfered; 1752 } else { 1753 ccb->ccb_h.spriv_field0 = ~0; 1754 } 1755 atp->ctcnt++; 1756 atp->seqno++; 1757 } 1758 rls_lun_statep(isp, tptr); 1759 } 1760 1761 static void 1762 isp_refire_putback_atio(void *arg) 1763 { 1764 union ccb *ccb = arg; 1765 1766 ISP_ASSERT_LOCKED((ispsoftc_t *)XS_ISP(ccb)); 1767 isp_target_putback_atio(ccb); 1768 } 1769 1770 static void 1771 isp_refire_notify_ack(void *arg) 1772 { 1773 isp_tna_t *tp = arg; 1774 ispsoftc_t *isp = tp->isp; 1775 1776 ISP_ASSERT_LOCKED(isp); 1777 if (isp_notify_ack(isp, tp->not)) { 1778 callout_schedule(&tp->timer, 5); 1779 } else { 1780 free(tp, M_DEVBUF); 1781 } 1782 } 1783 1784 1785 static void 1786 isp_target_putback_atio(union ccb *ccb) 1787 { 1788 ispsoftc_t *isp; 1789 struct ccb_scsiio *cso; 1790 void *qe; 1791 at2_entry_t local, *at = &local; 1792 1793 isp = XS_ISP(ccb); 1794 1795 qe = isp_getrqentry(isp); 1796 if (qe == NULL) { 1797 xpt_print(ccb->ccb_h.path, 1798 "%s: Request Queue Overflow\n", __func__); 1799 callout_reset(&PISP_PCMD(ccb)->wdog, 10, 1800 isp_refire_putback_atio, ccb); 1801 return; 1802 } 1803 memset(qe, 0, QENTRY_LEN); 1804 cso = &ccb->csio; 1805 ISP_MEMZERO(at, sizeof (at2_entry_t)); 1806 at->at_header.rqs_entry_type = RQSTYPE_ATIO2; 1807 at->at_header.rqs_entry_count = 1; 1808 if (ISP_CAP_SCCFW(isp)) { 1809 at->at_scclun = (uint16_t) ccb->ccb_h.target_lun; 1810 #if __FreeBSD_version < 1000700 1811 if (at->at_scclun >= 256) 1812 at->at_scclun |= 0x4000; 1813 #endif 1814 } else { 1815 at->at_lun = (uint8_t) ccb->ccb_h.target_lun; 1816 } 1817 at->at_status = CT_OK; 1818 at->at_rxid = cso->tag_id; 1819 at->at_iid = cso->ccb_h.target_id; 1820 isp_put_atio2(isp, at, qe); 1821 ISP_TDQE(isp, "isp_target_putback_atio", isp->isp_reqidx, qe); 1822 ISP_SYNC_REQUEST(isp); 1823 isp_complete_ctio(ccb); 1824 } 1825 1826 static void 1827 isp_complete_ctio(union ccb *ccb) 1828 { 1829 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_INPROG) { 1830 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1831 xpt_done(ccb); 1832 } 1833 } 1834 1835 static void 1836 isp_handle_platform_atio2(ispsoftc_t *isp, at2_entry_t *aep) 1837 { 1838 fcparam *fcp; 1839 lun_id_t lun; 1840 fcportdb_t *lp; 1841 tstate_t *tptr; 1842 struct ccb_accept_tio *atiop; 1843 uint16_t nphdl; 1844 atio_private_data_t *atp; 1845 inot_private_data_t *ntp; 1846 1847 /* 1848 * The firmware status (except for the QLTM_SVALID bit) 1849 * indicates why this ATIO was sent to us. 1850 * 1851 * If QLTM_SVALID is set, the firmware has recommended Sense Data. 1852 */ 1853 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) { 1854 isp_prt(isp, ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", aep->at_status); 1855 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1856 return; 1857 } 1858 1859 fcp = FCPARAM(isp, 0); 1860 if (ISP_CAP_SCCFW(isp)) { 1861 lun = aep->at_scclun; 1862 #if __FreeBSD_version < 1000700 1863 lun &= 0x3fff; 1864 #endif 1865 } else { 1866 lun = aep->at_lun; 1867 } 1868 if (ISP_CAP_2KLOGIN(isp)) { 1869 nphdl = ((at2e_entry_t *)aep)->at_iid; 1870 } else { 1871 nphdl = aep->at_iid; 1872 } 1873 tptr = get_lun_statep(isp, 0, lun); 1874 if (tptr == NULL) { 1875 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 1876 if (tptr == NULL) { 1877 isp_prt(isp, ISP_LOGWARN, "%s: [0x%x] no state pointer for lun %jx or wildcard", __func__, aep->at_rxid, (uintmax_t)lun); 1878 if (lun == 0) { 1879 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1880 } else { 1881 isp_endcmd(isp, aep, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0); 1882 } 1883 return; 1884 } 1885 } 1886 1887 /* 1888 * Start any commands pending resources first. 1889 */ 1890 if (tptr->restart_queue) { 1891 inot_private_data_t *restart_queue = tptr->restart_queue; 1892 tptr->restart_queue = NULL; 1893 while (restart_queue) { 1894 ntp = restart_queue; 1895 restart_queue = ntp->rd.nt.nt_hba; 1896 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at2_entry_t *)ntp->rd.data)->at_rxid); 1897 isp_handle_platform_atio2(isp, (at2_entry_t *) ntp->rd.data); 1898 isp_put_ntpd(isp, tptr, ntp); 1899 /* 1900 * If a recursion caused the restart queue to start to fill again, 1901 * stop and splice the new list on top of the old list and restore 1902 * it and go to noresrc. 1903 */ 1904 if (tptr->restart_queue) { 1905 ntp = tptr->restart_queue; 1906 tptr->restart_queue = restart_queue; 1907 while (restart_queue->rd.nt.nt_hba) { 1908 restart_queue = restart_queue->rd.nt.nt_hba; 1909 } 1910 restart_queue->rd.nt.nt_hba = ntp; 1911 goto noresrc; 1912 } 1913 } 1914 } 1915 1916 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 1917 if (atiop == NULL) { 1918 goto noresrc; 1919 } 1920 1921 atp = isp_get_atpd(isp, tptr, aep->at_rxid); 1922 if (atp == NULL) { 1923 goto noresrc; 1924 } 1925 1926 atp->state = ATPD_STATE_ATIO; 1927 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1928 tptr->atio_count--; 1929 isp_prt(isp, ISP_LOGTDEBUG2, "Take FREE ATIO count now %d", tptr->atio_count); 1930 atiop->ccb_h.target_id = fcp->isp_loopid; 1931 atiop->ccb_h.target_lun = lun; 1932 1933 /* 1934 * We don't get 'suggested' sense data as we do with SCSI cards. 1935 */ 1936 atiop->sense_len = 0; 1937 1938 /* 1939 * If we're not in the port database, add ourselves. 1940 */ 1941 if (IS_2100(isp)) 1942 atiop->init_id = nphdl; 1943 else { 1944 if ((isp_find_pdb_by_handle(isp, 0, nphdl, &lp) == 0 || 1945 lp->state == FC_PORTDB_STATE_ZOMBIE)) { 1946 uint64_t wwpn = 1947 (((uint64_t) aep->at_wwpn[0]) << 48) | 1948 (((uint64_t) aep->at_wwpn[1]) << 32) | 1949 (((uint64_t) aep->at_wwpn[2]) << 16) | 1950 (((uint64_t) aep->at_wwpn[3]) << 0); 1951 isp_add_wwn_entry(isp, 0, wwpn, INI_NONE, 1952 nphdl, PORT_ANY, 0); 1953 if (fcp->isp_loopstate > LOOP_LTEST_DONE) 1954 fcp->isp_loopstate = LOOP_LTEST_DONE; 1955 isp_async(isp, ISPASYNC_CHANGE_NOTIFY, 0, 1956 ISPASYNC_CHANGE_PDB, nphdl, 0x06, 0xff); 1957 isp_find_pdb_by_handle(isp, 0, nphdl, &lp); 1958 } 1959 atiop->init_id = FC_PORTDB_TGT(isp, 0, lp); 1960 } 1961 atiop->cdb_len = ATIO2_CDBLEN; 1962 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN); 1963 atiop->ccb_h.status = CAM_CDB_RECVD; 1964 atiop->tag_id = atp->tag; 1965 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) { 1966 case ATIO2_TC_ATTR_SIMPLEQ: 1967 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 1968 atiop->tag_action = MSG_SIMPLE_Q_TAG; 1969 break; 1970 case ATIO2_TC_ATTR_HEADOFQ: 1971 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 1972 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 1973 break; 1974 case ATIO2_TC_ATTR_ORDERED: 1975 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 1976 atiop->tag_action = MSG_ORDERED_Q_TAG; 1977 break; 1978 case ATIO2_TC_ATTR_ACAQ: /* ?? */ 1979 case ATIO2_TC_ATTR_UNTAGGED: 1980 default: 1981 atiop->tag_action = 0; 1982 break; 1983 } 1984 1985 atp->orig_datalen = aep->at_datalen; 1986 atp->bytes_xfered = 0; 1987 atp->lun = lun; 1988 atp->nphdl = nphdl; 1989 atp->sid = PORT_ANY; 1990 atp->oxid = aep->at_oxid; 1991 atp->cdb0 = aep->at_cdb[0]; 1992 atp->tattr = aep->at_taskflags & ATIO2_TC_ATTR_MASK; 1993 atp->state = ATPD_STATE_CAM; 1994 xpt_done((union ccb *)atiop); 1995 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); 1996 rls_lun_statep(isp, tptr); 1997 return; 1998 noresrc: 1999 ntp = isp_get_ntpd(isp, tptr); 2000 if (ntp == NULL) { 2001 rls_lun_statep(isp, tptr); 2002 isp_endcmd(isp, aep, nphdl, 0, SCSI_STATUS_BUSY, 0); 2003 return; 2004 } 2005 memcpy(ntp->rd.data, aep, QENTRY_LEN); 2006 ntp->rd.nt.nt_hba = tptr->restart_queue; 2007 tptr->restart_queue = ntp; 2008 rls_lun_statep(isp, tptr); 2009 } 2010 2011 static void 2012 isp_handle_platform_atio7(ispsoftc_t *isp, at7_entry_t *aep) 2013 { 2014 int cdbxlen; 2015 lun_id_t lun; 2016 uint16_t chan, nphdl = NIL_HANDLE; 2017 uint32_t did, sid; 2018 fcportdb_t *lp; 2019 tstate_t *tptr; 2020 struct ccb_accept_tio *atiop; 2021 atio_private_data_t *atp = NULL; 2022 atio_private_data_t *oatp; 2023 inot_private_data_t *ntp; 2024 2025 did = (aep->at_hdr.d_id[0] << 16) | (aep->at_hdr.d_id[1] << 8) | aep->at_hdr.d_id[2]; 2026 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 2027 #if __FreeBSD_version >= 1000700 2028 lun = CAM_EXTLUN_BYTE_SWIZZLE(be64dec(aep->at_cmnd.fcp_cmnd_lun)); 2029 #else 2030 lun = (aep->at_cmnd.fcp_cmnd_lun[0] & 0x3f << 8) | 2031 aep->at_cmnd.fcp_cmnd_lun[1]; 2032 #endif 2033 2034 /* 2035 * Find the N-port handle, and Virtual Port Index for this command. 2036 * 2037 * If we can't, we're somewhat in trouble because we can't actually respond w/o that information. 2038 * We also, as a matter of course, need to know the WWN of the initiator too. 2039 */ 2040 if (ISP_CAP_MULTI_ID(isp) && isp->isp_nchan > 1) { 2041 /* 2042 * Find the right channel based upon D_ID 2043 */ 2044 isp_find_chan_by_did(isp, did, &chan); 2045 2046 if (chan == ISP_NOCHAN) { 2047 NANOTIME_T now; 2048 2049 /* 2050 * If we don't recognizer our own D_DID, terminate the exchange, unless we're within 2 seconds of startup 2051 * It's a bit tricky here as we need to stash this command *somewhere*. 2052 */ 2053 GET_NANOTIME(&now); 2054 if (NANOTIME_SUB(&isp->isp_init_time, &now) > 2000000000ULL) { 2055 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- dropping", __func__, aep->at_rxid, did); 2056 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0); 2057 return; 2058 } 2059 tptr = get_lun_statep(isp, 0, 0); 2060 if (tptr == NULL) { 2061 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 2062 if (tptr == NULL) { 2063 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); 2064 isp_endcmd(isp, aep, NIL_HANDLE, ISP_NOCHAN, ECMD_TERMINATE, 0); 2065 return; 2066 } 2067 } 2068 isp_prt(isp, ISP_LOGWARN, "%s: [RX_ID 0x%x] D_ID %x not found on any channel- deferring", __func__, aep->at_rxid, did); 2069 goto noresrc; 2070 } 2071 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); 2072 } else { 2073 chan = 0; 2074 } 2075 2076 /* 2077 * Find the PDB entry for this initiator 2078 */ 2079 if (isp_find_pdb_by_portid(isp, chan, sid, &lp) == 0) { 2080 /* 2081 * If we're not in the port database terminate the exchange. 2082 */ 2083 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", 2084 __func__, aep->at_rxid, did, chan, sid); 2085 isp_dump_portdb(isp, chan); 2086 isp_endcmd(isp, aep, NIL_HANDLE, chan, ECMD_TERMINATE, 0); 2087 return; 2088 } 2089 nphdl = lp->handle; 2090 2091 /* 2092 * Get the tstate pointer 2093 */ 2094 tptr = get_lun_statep(isp, chan, lun); 2095 if (tptr == NULL) { 2096 tptr = get_lun_statep(isp, chan, CAM_LUN_WILDCARD); 2097 if (tptr == NULL) { 2098 isp_prt(isp, ISP_LOGWARN, 2099 "%s: [0x%x] no state pointer for lun %jx or wildcard", 2100 __func__, aep->at_rxid, (uintmax_t)lun); 2101 if (lun == 0) { 2102 isp_endcmd(isp, aep, nphdl, SCSI_STATUS_BUSY, 0); 2103 } else { 2104 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_CHECK_COND | ECMD_SVALID | (0x5 << 12) | (0x25 << 16), 0); 2105 } 2106 return; 2107 } 2108 } 2109 2110 /* 2111 * Start any commands pending resources first. 2112 */ 2113 if (tptr->restart_queue) { 2114 inot_private_data_t *restart_queue = tptr->restart_queue; 2115 tptr->restart_queue = NULL; 2116 while (restart_queue) { 2117 ntp = restart_queue; 2118 restart_queue = ntp->rd.nt.nt_hba; 2119 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restarting resrc deprived %x", __func__, ((at7_entry_t *)ntp->rd.data)->at_rxid); 2120 isp_handle_platform_atio7(isp, (at7_entry_t *) ntp->rd.data); 2121 isp_put_ntpd(isp, tptr, ntp); 2122 /* 2123 * If a recursion caused the restart queue to start to fill again, 2124 * stop and splice the new list on top of the old list and restore 2125 * it and go to noresrc. 2126 */ 2127 if (tptr->restart_queue) { 2128 isp_prt(isp, ISP_LOGTDEBUG0, "%s: restart queue refilling", __func__); 2129 if (restart_queue) { 2130 ntp = tptr->restart_queue; 2131 tptr->restart_queue = restart_queue; 2132 while (restart_queue->rd.nt.nt_hba) { 2133 restart_queue = restart_queue->rd.nt.nt_hba; 2134 } 2135 restart_queue->rd.nt.nt_hba = ntp; 2136 } 2137 goto noresrc; 2138 } 2139 } 2140 } 2141 2142 /* 2143 * If the f/w is out of resources, just send a BUSY status back. 2144 */ 2145 if (aep->at_rxid == AT7_NORESRC_RXID) { 2146 rls_lun_statep(isp, tptr); 2147 isp_endcmd(isp, aep, nphdl, chan, SCSI_BUSY, 0); 2148 return; 2149 } 2150 2151 /* 2152 * If we're out of resources, just send a BUSY status back. 2153 */ 2154 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 2155 if (atiop == NULL) { 2156 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atios", aep->at_rxid); 2157 goto noresrc; 2158 } 2159 2160 oatp = isp_find_atpd(isp, tptr, aep->at_rxid); 2161 if (oatp) { 2162 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", 2163 aep->at_rxid, nphdl, sid, aep->at_hdr.ox_id, oatp->state); 2164 /* 2165 * It's not a "no resource" condition- but we can treat it like one 2166 */ 2167 goto noresrc; 2168 } 2169 atp = isp_get_atpd(isp, tptr, aep->at_rxid); 2170 if (atp == NULL) { 2171 isp_prt(isp, ISP_LOGTDEBUG0, "[0x%x] out of atps", aep->at_rxid); 2172 goto noresrc; 2173 } 2174 atp->word3 = lp->prli_word3; 2175 atp->state = ATPD_STATE_ATIO; 2176 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 2177 tptr->atio_count--; 2178 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, atiop->ccb_h.path, "Take FREE ATIO count now %d\n", tptr->atio_count); 2179 atiop->init_id = FC_PORTDB_TGT(isp, chan, lp); 2180 atiop->ccb_h.target_id = FCPARAM(isp, chan)->isp_loopid; 2181 atiop->ccb_h.target_lun = lun; 2182 atiop->sense_len = 0; 2183 cdbxlen = aep->at_cmnd.fcp_cmnd_alen_datadir >> FCP_CMND_ADDTL_CDBLEN_SHIFT; 2184 if (cdbxlen) { 2185 isp_prt(isp, ISP_LOGWARN, "additional CDBLEN ignored"); 2186 } 2187 cdbxlen = sizeof (aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb); 2188 ISP_MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cmnd.cdb_dl.sf.fcp_cmnd_cdb, cdbxlen); 2189 atiop->cdb_len = cdbxlen; 2190 atiop->ccb_h.status = CAM_CDB_RECVD; 2191 atiop->tag_id = atp->tag; 2192 switch (aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK) { 2193 case FCP_CMND_TASK_ATTR_SIMPLE: 2194 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2195 atiop->tag_action = MSG_SIMPLE_Q_TAG; 2196 break; 2197 case FCP_CMND_TASK_ATTR_HEAD: 2198 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2199 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 2200 break; 2201 case FCP_CMND_TASK_ATTR_ORDERED: 2202 atiop->ccb_h.flags |= CAM_TAG_ACTION_VALID; 2203 atiop->tag_action = MSG_ORDERED_Q_TAG; 2204 break; 2205 default: 2206 /* FALLTHROUGH */ 2207 case FCP_CMND_TASK_ATTR_ACA: 2208 case FCP_CMND_TASK_ATTR_UNTAGGED: 2209 atiop->tag_action = 0; 2210 break; 2211 } 2212 atp->orig_datalen = aep->at_cmnd.cdb_dl.sf.fcp_cmnd_dl; 2213 atp->bytes_xfered = 0; 2214 atp->lun = lun; 2215 atp->nphdl = nphdl; 2216 atp->portid = sid; 2217 atp->oxid = aep->at_hdr.ox_id; 2218 atp->rxid = aep->at_hdr.rx_id; 2219 atp->cdb0 = atiop->cdb_io.cdb_bytes[0]; 2220 atp->tattr = aep->at_cmnd.fcp_cmnd_task_attribute & FCP_CMND_TASK_ATTR_MASK; 2221 atp->state = ATPD_STATE_CAM; 2222 isp_prt(isp, ISP_LOGTDEBUG0, "ATIO7[0x%x] CDB=0x%x lun %jx datalen %u", 2223 aep->at_rxid, atp->cdb0, (uintmax_t)lun, atp->orig_datalen); 2224 xpt_done((union ccb *)atiop); 2225 rls_lun_statep(isp, tptr); 2226 return; 2227 noresrc: 2228 if (atp) { 2229 isp_put_atpd(isp, tptr, atp); 2230 } 2231 ntp = isp_get_ntpd(isp, tptr); 2232 if (ntp == NULL) { 2233 rls_lun_statep(isp, tptr); 2234 isp_endcmd(isp, aep, nphdl, chan, SCSI_STATUS_BUSY, 0); 2235 return; 2236 } 2237 memcpy(ntp->rd.data, aep, QENTRY_LEN); 2238 ntp->rd.nt.nt_hba = tptr->restart_queue; 2239 tptr->restart_queue = ntp; 2240 rls_lun_statep(isp, tptr); 2241 } 2242 2243 2244 /* 2245 * Handle starting an SRR (sequence retransmit request) 2246 * We get here when we've gotten the immediate notify 2247 * and the return of all outstanding CTIOs for this 2248 * transaction. 2249 */ 2250 static void 2251 isp_handle_srr_start(ispsoftc_t *isp, tstate_t *tptr, atio_private_data_t *atp) 2252 { 2253 in_fcentry_24xx_t *inot; 2254 uint32_t srr_off, ccb_off, ccb_len, ccb_end; 2255 union ccb *ccb; 2256 2257 inot = (in_fcentry_24xx_t *)atp->srr; 2258 srr_off = inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16); 2259 ccb = atp->srr_ccb; 2260 atp->srr_ccb = NULL; 2261 atp->nsrr++; 2262 if (ccb == NULL) { 2263 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] null ccb", atp->tag); 2264 goto fail; 2265 } 2266 2267 ccb_off = ccb->ccb_h.spriv_field0; 2268 ccb_len = ccb->csio.dxfer_len; 2269 ccb_end = (ccb_off == ~0)? ~0 : ccb_off + ccb_len; 2270 2271 switch (inot->in_srr_iu) { 2272 case R_CTL_INFO_SOLICITED_DATA: 2273 /* 2274 * We have to restart a FCP_DATA data out transaction 2275 */ 2276 atp->sendst = 0; 2277 atp->bytes_xfered = srr_off; 2278 if (ccb_len == 0) { 2279 isp_prt(isp, ISP_LOGWARN, "SRR[0x%x] SRR offset 0x%x but current CCB doesn't transfer data", atp->tag, srr_off); 2280 goto mdp; 2281 } 2282 if (srr_off < ccb_off || ccb_off > srr_off + ccb_len) { 2283 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); 2284 goto mdp; 2285 } 2286 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); 2287 break; 2288 case R_CTL_INFO_COMMAND_STATUS: 2289 isp_prt(isp, ISP_LOGTINFO, "SRR[0x%x] Got an FCP RSP SRR- resending status", atp->tag); 2290 atp->sendst = 1; 2291 /* 2292 * We have to restart a FCP_RSP IU transaction 2293 */ 2294 break; 2295 case R_CTL_INFO_DATA_DESCRIPTOR: 2296 /* 2297 * We have to restart an FCP DATA in transaction 2298 */ 2299 isp_prt(isp, ISP_LOGWARN, "Got an FCP DATA IN SRR- dropping"); 2300 goto fail; 2301 2302 default: 2303 isp_prt(isp, ISP_LOGWARN, "Got an unknown information (%x) SRR- dropping", inot->in_srr_iu); 2304 goto fail; 2305 } 2306 2307 /* 2308 * We can't do anything until this is acked, so we might as well start it now. 2309 * We aren't going to do the usual asynchronous ack issue because we need 2310 * to make sure this gets on the wire first. 2311 */ 2312 if (isp_notify_ack(isp, inot)) { 2313 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose"); 2314 goto fail; 2315 } 2316 isp_target_start_ctio(isp, ccb, FROM_SRR); 2317 return; 2318 fail: 2319 inot->in_reserved = 1; 2320 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2321 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2322 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 2323 isp_complete_ctio(ccb); 2324 return; 2325 mdp: 2326 if (isp_notify_ack(isp, inot)) { 2327 isp_prt(isp, ISP_LOGWARN, "could not push positive ack for SRR- you lose"); 2328 goto fail; 2329 } 2330 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2331 ccb->ccb_h.status = CAM_MESSAGE_RECV; 2332 /* 2333 * This is not a strict interpretation of MDP, but it's close 2334 */ 2335 ccb->csio.msg_ptr = &ccb->csio.sense_data.sense_buf[SSD_FULL_SIZE - 16]; 2336 ccb->csio.msg_len = 7; 2337 ccb->csio.msg_ptr[0] = MSG_EXTENDED; 2338 ccb->csio.msg_ptr[1] = 5; 2339 ccb->csio.msg_ptr[2] = 0; /* modify data pointer */ 2340 ccb->csio.msg_ptr[3] = srr_off >> 24; 2341 ccb->csio.msg_ptr[4] = srr_off >> 16; 2342 ccb->csio.msg_ptr[5] = srr_off >> 8; 2343 ccb->csio.msg_ptr[6] = srr_off; 2344 isp_complete_ctio(ccb); 2345 } 2346 2347 2348 static void 2349 isp_handle_srr_notify(ispsoftc_t *isp, void *inot_raw) 2350 { 2351 tstate_t *tptr; 2352 in_fcentry_24xx_t *inot = inot_raw; 2353 atio_private_data_t *atp; 2354 uint32_t tag = inot->in_rxid; 2355 uint32_t bus = inot->in_vpidx; 2356 2357 if (!IS_24XX(isp)) { 2358 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot_raw); 2359 return; 2360 } 2361 2362 tptr = get_lun_statep_from_tag(isp, bus, tag); 2363 if (tptr == NULL) { 2364 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x in SRR Notify", __func__, tag); 2365 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2366 return; 2367 } 2368 atp = isp_find_atpd(isp, tptr, tag); 2369 if (atp == NULL) { 2370 rls_lun_statep(isp, tptr); 2371 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x in SRR Notify", __func__, tag); 2372 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2373 return; 2374 } 2375 atp->srr_notify_rcvd = 1; 2376 memcpy(atp->srr, inot, sizeof (atp->srr)); 2377 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, 2378 inot->in_srr_reloff_lo | (inot->in_srr_reloff_hi << 16)); 2379 if (atp->srr_ccb) 2380 isp_handle_srr_start(isp, tptr, atp); 2381 rls_lun_statep(isp, tptr); 2382 } 2383 2384 static void 2385 isp_handle_platform_ctio(ispsoftc_t *isp, void *arg) 2386 { 2387 union ccb *ccb; 2388 int sentstatus = 0, ok = 0, notify_cam = 0, resid = 0, failure = 0; 2389 tstate_t *tptr = NULL; 2390 atio_private_data_t *atp = NULL; 2391 int bus; 2392 uint32_t handle, moved_data = 0, data_requested; 2393 2394 handle = ((ct2_entry_t *)arg)->ct_syshandle; 2395 ccb = isp_find_xs_tgt(isp, handle); 2396 if (ccb == NULL) { 2397 isp_print_bytes(isp, "null ccb in isp_handle_platform_ctio", QENTRY_LEN, arg); 2398 return; 2399 } 2400 isp_destroy_tgt_handle(isp, handle); 2401 data_requested = PISP_PCMD(ccb)->datalen; 2402 isp_free_pcmd(isp, ccb); 2403 if (isp->isp_nactive) { 2404 isp->isp_nactive--; 2405 } 2406 2407 bus = XS_CHANNEL(ccb); 2408 tptr = get_lun_statep(isp, bus, XS_LUN(ccb)); 2409 if (tptr == NULL) { 2410 tptr = get_lun_statep(isp, bus, CAM_LUN_WILDCARD); 2411 } 2412 if (tptr == NULL) { 2413 isp_prt(isp, ISP_LOGERR, "%s: cannot find tptr for tag %x after I/O", __func__, ccb->csio.tag_id); 2414 return; 2415 } 2416 2417 if (IS_24XX(isp)) { 2418 atp = isp_find_atpd(isp, tptr, ((ct7_entry_t *)arg)->ct_rxid); 2419 } else { 2420 atp = isp_find_atpd(isp, tptr, ((ct2_entry_t *)arg)->ct_rxid); 2421 } 2422 if (atp == NULL) { 2423 /* 2424 * XXX: isp_clear_commands() generates fake CTIO with zero 2425 * ct_rxid value, filling only ct_syshandle. Workaround 2426 * that using tag_id from the CCB, pointed by ct_syshandle. 2427 */ 2428 atp = isp_find_atpd(isp, tptr, ccb->csio.tag_id); 2429 } 2430 if (atp == NULL) { 2431 rls_lun_statep(isp, tptr); 2432 isp_prt(isp, ISP_LOGERR, "%s: cannot find adjunct for %x after I/O", __func__, ccb->csio.tag_id); 2433 return; 2434 } 2435 KASSERT((atp->ctcnt > 0), ("ctio count not greater than zero")); 2436 atp->bytes_in_transit -= data_requested; 2437 atp->ctcnt -= 1; 2438 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 2439 2440 if (IS_24XX(isp)) { 2441 ct7_entry_t *ct = arg; 2442 2443 if (ct->ct_nphdl == CT7_SRR) { 2444 atp->srr_ccb = ccb; 2445 if (atp->srr_notify_rcvd) 2446 isp_handle_srr_start(isp, tptr, atp); 2447 rls_lun_statep(isp, tptr); 2448 return; 2449 } 2450 if (ct->ct_nphdl == CT_HBA_RESET) { 2451 failure = CAM_UNREC_HBA_ERROR; 2452 } else { 2453 sentstatus = ct->ct_flags & CT7_SENDSTATUS; 2454 ok = (ct->ct_nphdl == CT7_OK); 2455 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; 2456 if ((ct->ct_flags & CT7_DATAMASK) != CT7_NO_DATA) { 2457 resid = ct->ct_resid; 2458 moved_data = data_requested - resid; 2459 } 2460 } 2461 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), 2462 notify_cam, ct->ct_nphdl, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); 2463 } else { 2464 ct2_entry_t *ct = arg; 2465 if (ct->ct_status == CT_SRR) { 2466 atp->srr_ccb = ccb; 2467 if (atp->srr_notify_rcvd) 2468 isp_handle_srr_start(isp, tptr, atp); 2469 rls_lun_statep(isp, tptr); 2470 isp_target_putback_atio(ccb); 2471 return; 2472 } 2473 if (ct->ct_status == CT_HBA_RESET) { 2474 failure = CAM_UNREC_HBA_ERROR; 2475 } else { 2476 sentstatus = ct->ct_flags & CT2_SENDSTATUS; 2477 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 2478 notify_cam = (ct->ct_header.rqs_seqno & ATPD_SEQ_NOTIFY_CAM) != 0; 2479 if ((ct->ct_flags & CT2_DATAMASK) != CT2_NO_DATA) { 2480 resid = ct->ct_resid; 2481 moved_data = data_requested - resid; 2482 } 2483 } 2484 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), 2485 notify_cam, ct->ct_status, ct->ct_flags, (ccb->ccb_h.status & CAM_SENT_SENSE) != 0, resid, sentstatus? "FIN" : "MID"); 2486 } 2487 if (ok) { 2488 if (moved_data) { 2489 atp->bytes_xfered += moved_data; 2490 ccb->csio.resid = atp->orig_datalen - atp->bytes_xfered - atp->bytes_in_transit; 2491 } 2492 if (sentstatus && (ccb->ccb_h.flags & CAM_SEND_SENSE)) { 2493 ccb->ccb_h.status |= CAM_SENT_SENSE; 2494 } 2495 ccb->ccb_h.status |= CAM_REQ_CMP; 2496 } else { 2497 notify_cam = 1; 2498 if (failure == CAM_UNREC_HBA_ERROR) 2499 ccb->ccb_h.status |= CAM_UNREC_HBA_ERROR; 2500 else 2501 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 2502 } 2503 atp->state = ATPD_STATE_PDON; 2504 rls_lun_statep(isp, tptr); 2505 2506 /* 2507 * We never *not* notify CAM when there has been any error (ok == 0), 2508 * so we never need to do an ATIO putback if we're not notifying CAM. 2509 */ 2510 isp_prt(isp, ISP_LOGTDEBUG0, "%s CTIO[0x%x] done (ok=%d nc=%d nowsendstatus=%d ccb ss=%d)", 2511 (sentstatus)? " FINAL " : "MIDTERM ", atp->tag, ok, notify_cam, atp->sendst, (ccb->ccb_h.flags & CAM_SEND_STATUS) != 0); 2512 if (notify_cam == 0) { 2513 if (atp->sendst) { 2514 isp_target_start_ctio(isp, ccb, FROM_CTIO_DONE); 2515 } 2516 return; 2517 } 2518 2519 /* 2520 * We're telling CAM we're done with this CTIO transaction. 2521 * 2522 * 24XX cards never need an ATIO put back. 2523 * 2524 * Other cards need one put back only on error. 2525 * In the latter case, a timeout will re-fire 2526 * and try again in case we didn't have 2527 * queue resources to do so at first. In any case, 2528 * once the putback is done we do the completion 2529 * call. 2530 */ 2531 if (ok || IS_24XX(isp)) { 2532 isp_complete_ctio(ccb); 2533 } else { 2534 isp_target_putback_atio(ccb); 2535 } 2536 } 2537 2538 static void 2539 isp_handle_platform_notify_fc(ispsoftc_t *isp, in_fcentry_t *inp) 2540 { 2541 int needack = 1; 2542 switch (inp->in_status) { 2543 case IN_PORT_LOGOUT: 2544 /* 2545 * XXX: Need to delete this initiator's WWN from the database 2546 * XXX: Need to send this LOGOUT upstream 2547 */ 2548 isp_prt(isp, ISP_LOGWARN, "port logout of S_ID 0x%x", inp->in_iid); 2549 break; 2550 case IN_PORT_CHANGED: 2551 isp_prt(isp, ISP_LOGWARN, "port changed for S_ID 0x%x", inp->in_iid); 2552 break; 2553 case IN_GLOBAL_LOGO: 2554 isp_del_all_wwn_entries(isp, 0); 2555 isp_prt(isp, ISP_LOGINFO, "all ports logged out"); 2556 break; 2557 case IN_ABORT_TASK: 2558 { 2559 tstate_t *tptr; 2560 uint16_t nphdl, lun; 2561 uint32_t sid; 2562 uint64_t wwn; 2563 atio_private_data_t *atp; 2564 fcportdb_t *lp; 2565 struct ccb_immediate_notify *inot = NULL; 2566 2567 if (ISP_CAP_SCCFW(isp)) { 2568 lun = inp->in_scclun; 2569 #if __FreeBSD_version < 1000700 2570 lun &= 0x3fff; 2571 #endif 2572 } else { 2573 lun = inp->in_lun; 2574 } 2575 if (ISP_CAP_2KLOGIN(isp)) { 2576 nphdl = ((in_fcentry_e_t *)inp)->in_iid; 2577 } else { 2578 nphdl = inp->in_iid; 2579 } 2580 if (isp_find_pdb_by_handle(isp, 0, nphdl, &lp)) { 2581 wwn = lp->port_wwn; 2582 sid = lp->portid; 2583 } else { 2584 wwn = INI_ANY; 2585 sid = PORT_ANY; 2586 } 2587 tptr = get_lun_statep(isp, 0, lun); 2588 if (tptr == NULL) { 2589 tptr = get_lun_statep(isp, 0, CAM_LUN_WILDCARD); 2590 if (tptr == NULL) { 2591 isp_prt(isp, ISP_LOGWARN, "ABORT TASK for lun %x, but no tstate", lun); 2592 return; 2593 } 2594 } 2595 atp = isp_find_atpd(isp, tptr, inp->in_seqid); 2596 2597 if (atp) { 2598 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots); 2599 isp_prt(isp, ISP_LOGTDEBUG0, "ABORT TASK RX_ID %x WWN 0x%016llx state %d", inp->in_seqid, (unsigned long long) wwn, atp->state); 2600 if (inot) { 2601 tptr->inot_count--; 2602 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 2603 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count); 2604 } else { 2605 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "out of INOT structures\n"); 2606 } 2607 } else { 2608 ISP_PATH_PRT(isp, ISP_LOGWARN, tptr->owner, "abort task RX_ID %x from wwn 0x%016llx, state unknown\n", inp->in_seqid, wwn); 2609 } 2610 if (inot) { 2611 isp_notify_t tmp, *nt = &tmp; 2612 ISP_MEMZERO(nt, sizeof (isp_notify_t)); 2613 nt->nt_hba = isp; 2614 nt->nt_tgt = FCPARAM(isp, 0)->isp_wwpn; 2615 nt->nt_wwn = wwn; 2616 nt->nt_nphdl = nphdl; 2617 nt->nt_sid = sid; 2618 nt->nt_did = PORT_ANY; 2619 nt->nt_lun = lun; 2620 nt->nt_need_ack = 1; 2621 nt->nt_channel = 0; 2622 nt->nt_ncode = NT_ABORT_TASK; 2623 nt->nt_lreserved = inot; 2624 isp_handle_platform_target_tmf(isp, nt); 2625 needack = 0; 2626 } 2627 rls_lun_statep(isp, tptr); 2628 break; 2629 } 2630 default: 2631 break; 2632 } 2633 if (needack) { 2634 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inp); 2635 } 2636 } 2637 2638 static void 2639 isp_handle_platform_notify_24xx(ispsoftc_t *isp, in_fcentry_24xx_t *inot) 2640 { 2641 uint16_t nphdl; 2642 uint16_t prli_options = 0; 2643 uint32_t portid; 2644 fcportdb_t *lp; 2645 char *msg = NULL; 2646 uint8_t *ptr = (uint8_t *)inot; 2647 uint64_t wwpn = INI_NONE, wwnn = INI_NONE; 2648 2649 nphdl = inot->in_nphdl; 2650 if (nphdl != NIL_HANDLE) { 2651 portid = inot->in_portid_hi << 16 | inot->in_portid_lo; 2652 } else { 2653 portid = PORT_ANY; 2654 } 2655 2656 switch (inot->in_status) { 2657 case IN24XX_ELS_RCVD: 2658 { 2659 char buf[16]; 2660 int chan = ISP_GET_VPIDX(isp, inot->in_vpidx); 2661 2662 /* 2663 * Note that we're just getting notification that an ELS was received 2664 * (possibly with some associated information sent upstream). This is 2665 * *not* the same as being given the ELS frame to accept or reject. 2666 */ 2667 switch (inot->in_status_subcode) { 2668 case LOGO: 2669 msg = "LOGO"; 2670 wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); 2671 isp_del_wwn_entry(isp, chan, wwpn, nphdl, portid); 2672 break; 2673 case PRLO: 2674 msg = "PRLO"; 2675 break; 2676 case PLOGI: 2677 msg = "PLOGI"; 2678 wwnn = be64dec(&ptr[IN24XX_PLOGI_WWNN_OFF]); 2679 wwpn = be64dec(&ptr[IN24XX_PLOGI_WWPN_OFF]); 2680 isp_add_wwn_entry(isp, chan, wwpn, wwnn, 2681 nphdl, portid, prli_options); 2682 break; 2683 case PRLI: 2684 msg = "PRLI"; 2685 prli_options = inot->in_prli_options; 2686 if (inot->in_flags & IN24XX_FLAG_PN_NN_VALID) 2687 wwnn = be64dec(&ptr[IN24XX_PRLI_WWNN_OFF]); 2688 wwpn = be64dec(&ptr[IN24XX_PRLI_WWPN_OFF]); 2689 isp_add_wwn_entry(isp, chan, wwpn, wwnn, 2690 nphdl, portid, prli_options); 2691 break; 2692 case PDISC: 2693 msg = "PDISC"; 2694 break; 2695 case ADISC: 2696 msg = "ADISC"; 2697 break; 2698 default: 2699 ISP_SNPRINTF(buf, sizeof (buf), "ELS 0x%x", inot->in_status_subcode); 2700 msg = buf; 2701 break; 2702 } 2703 if (inot->in_flags & IN24XX_FLAG_PUREX_IOCB) { 2704 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); 2705 break; 2706 } 2707 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, 2708 inot->in_rxid, inot->in_oxid); 2709 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2710 break; 2711 } 2712 2713 case IN24XX_PORT_LOGOUT: 2714 msg = "PORT LOGOUT"; 2715 if (isp_find_pdb_by_handle(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), nphdl, &lp)) { 2716 isp_del_wwn_entry(isp, ISP_GET_VPIDX(isp, inot->in_vpidx), lp->port_wwn, nphdl, lp->portid); 2717 } 2718 /* FALLTHROUGH */ 2719 case IN24XX_PORT_CHANGED: 2720 if (msg == NULL) 2721 msg = "PORT CHANGED"; 2722 /* FALLTHROUGH */ 2723 case IN24XX_LIP_RESET: 2724 if (msg == NULL) 2725 msg = "LIP RESET"; 2726 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), msg, inot->in_status_subcode, nphdl); 2727 2728 /* 2729 * All subcodes here are irrelevant. What is relevant 2730 * is that we need to terminate all active commands from 2731 * this initiator (known by N-port handle). 2732 */ 2733 /* XXX IMPLEMENT XXX */ 2734 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2735 break; 2736 2737 case IN24XX_SRR_RCVD: 2738 #ifdef ISP_TARGET_MODE 2739 isp_handle_srr_notify(isp, inot); 2740 break; 2741 #else 2742 if (msg == NULL) 2743 msg = "SRR RCVD"; 2744 /* FALLTHROUGH */ 2745 #endif 2746 case IN24XX_LINK_RESET: 2747 if (msg == NULL) 2748 msg = "LINK RESET"; 2749 case IN24XX_LINK_FAILED: 2750 if (msg == NULL) 2751 msg = "LINK FAILED"; 2752 default: 2753 isp_prt(isp, ISP_LOGWARN, "Chan %d %s", ISP_GET_VPIDX(isp, inot->in_vpidx), msg); 2754 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, inot); 2755 break; 2756 } 2757 } 2758 2759 static int 2760 isp_handle_platform_target_notify_ack(ispsoftc_t *isp, isp_notify_t *mp) 2761 { 2762 2763 if (isp->isp_state != ISP_RUNSTATE) { 2764 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) acked- h/w not ready (dropping)", mp->nt_ncode, mp->nt_lreserved != NULL); 2765 return (0); 2766 } 2767 2768 /* 2769 * This case is for a Task Management Function, which shows up as an ATIO7 entry. 2770 */ 2771 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ATIO) { 2772 ct7_entry_t local, *cto = &local; 2773 at7_entry_t *aep = (at7_entry_t *)mp->nt_lreserved; 2774 fcportdb_t *lp; 2775 uint32_t sid; 2776 uint16_t nphdl; 2777 2778 sid = (aep->at_hdr.s_id[0] << 16) | (aep->at_hdr.s_id[1] << 8) | aep->at_hdr.s_id[2]; 2779 if (isp_find_pdb_by_portid(isp, mp->nt_channel, sid, &lp)) { 2780 nphdl = lp->handle; 2781 } else { 2782 nphdl = NIL_HANDLE; 2783 } 2784 ISP_MEMZERO(&local, sizeof (local)); 2785 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 2786 cto->ct_header.rqs_entry_count = 1; 2787 cto->ct_nphdl = nphdl; 2788 cto->ct_rxid = aep->at_rxid; 2789 cto->ct_vpidx = mp->nt_channel; 2790 cto->ct_iid_lo = sid; 2791 cto->ct_iid_hi = sid >> 16; 2792 cto->ct_oxid = aep->at_hdr.ox_id; 2793 cto->ct_flags = CT7_SENDSTATUS|CT7_NOACK|CT7_NO_DATA|CT7_FLAG_MODE1; 2794 cto->ct_flags |= (aep->at_ta_len >> 12) << CT7_TASK_ATTR_SHIFT; 2795 return (isp_target_put_entry(isp, &local)); 2796 } 2797 2798 /* 2799 * This case is for a responding to an ABTS frame 2800 */ 2801 if (IS_24XX(isp) && mp->nt_lreserved && ((isphdr_t *)mp->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { 2802 2803 /* 2804 * Overload nt_need_ack here to mark whether we've terminated the associated command. 2805 */ 2806 if (mp->nt_need_ack) { 2807 uint8_t storage[QENTRY_LEN]; 2808 ct7_entry_t *cto = (ct7_entry_t *) storage; 2809 abts_t *abts = (abts_t *)mp->nt_lreserved; 2810 2811 ISP_MEMZERO(cto, sizeof (ct7_entry_t)); 2812 isp_prt(isp, ISP_LOGTDEBUG0, "%s: [%x] terminating after ABTS received", __func__, abts->abts_rxid_task); 2813 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO7; 2814 cto->ct_header.rqs_entry_count = 1; 2815 cto->ct_nphdl = mp->nt_nphdl; 2816 cto->ct_rxid = abts->abts_rxid_task; 2817 cto->ct_iid_lo = mp->nt_sid; 2818 cto->ct_iid_hi = mp->nt_sid >> 16; 2819 cto->ct_oxid = abts->abts_ox_id; 2820 cto->ct_vpidx = mp->nt_channel; 2821 cto->ct_flags = CT7_NOACK|CT7_TERMINATE; 2822 if (isp_target_put_entry(isp, cto)) { 2823 return (ENOMEM); 2824 } 2825 mp->nt_need_ack = 0; 2826 } 2827 if (isp_acknak_abts(isp, mp->nt_lreserved, 0) == ENOMEM) { 2828 return (ENOMEM); 2829 } else { 2830 return (0); 2831 } 2832 } 2833 2834 /* 2835 * Handle logout cases here 2836 */ 2837 if (mp->nt_ncode == NT_GLOBAL_LOGOUT) { 2838 isp_del_all_wwn_entries(isp, mp->nt_channel); 2839 } 2840 2841 if (mp->nt_ncode == NT_LOGOUT) { 2842 if (!IS_2100(isp) && IS_FC(isp)) { 2843 isp_del_wwn_entries(isp, mp); 2844 } 2845 } 2846 2847 /* 2848 * General purpose acknowledgement 2849 */ 2850 if (mp->nt_need_ack) { 2851 isp_prt(isp, ISP_LOGTINFO, "Notify Code 0x%x (qevalid=%d) being acked", mp->nt_ncode, mp->nt_lreserved != NULL); 2852 /* 2853 * Don't need to use the guaranteed send because the caller can retry 2854 */ 2855 return (isp_notify_ack(isp, mp->nt_lreserved)); 2856 } 2857 return (0); 2858 } 2859 2860 /* 2861 * Handle task management functions. 2862 * 2863 * We show up here with a notify structure filled out. 2864 * 2865 * The nt_lreserved tag points to the original queue entry 2866 */ 2867 static void 2868 isp_handle_platform_target_tmf(ispsoftc_t *isp, isp_notify_t *notify) 2869 { 2870 tstate_t *tptr; 2871 fcportdb_t *lp; 2872 struct ccb_immediate_notify *inot; 2873 inot_private_data_t *ntp = NULL; 2874 lun_id_t lun; 2875 2876 isp_prt(isp, ISP_LOGTDEBUG0, "%s: code 0x%x sid 0x%x tagval 0x%016llx chan %d lun 0x%x", __func__, notify->nt_ncode, 2877 notify->nt_sid, (unsigned long long) notify->nt_tagval, notify->nt_channel, notify->nt_lun); 2878 /* 2879 * NB: This assignment is necessary because of tricky type conversion. 2880 * XXX: This is tricky and I need to check this. If the lun isn't known 2881 * XXX: for the task management function, it does not of necessity follow 2882 * XXX: that it should go up stream to the wildcard listener. 2883 */ 2884 if (notify->nt_lun == LUN_ANY) { 2885 lun = CAM_LUN_WILDCARD; 2886 } else { 2887 lun = notify->nt_lun; 2888 } 2889 tptr = get_lun_statep(isp, notify->nt_channel, lun); 2890 if (tptr == NULL) { 2891 tptr = get_lun_statep(isp, notify->nt_channel, CAM_LUN_WILDCARD); 2892 if (tptr == NULL) { 2893 isp_prt(isp, ISP_LOGWARN, "%s: no state pointer found for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun); 2894 goto bad; 2895 } 2896 } 2897 inot = (struct ccb_immediate_notify *) SLIST_FIRST(&tptr->inots); 2898 if (inot == NULL) { 2899 isp_prt(isp, ISP_LOGWARN, "%s: out of immediate notify structures for chan %d lun %#jx", __func__, notify->nt_channel, (uintmax_t)lun); 2900 goto bad; 2901 } 2902 2903 if (isp_find_pdb_by_portid(isp, notify->nt_channel, notify->nt_sid, &lp) == 0 && 2904 isp_find_pdb_by_handle(isp, notify->nt_channel, notify->nt_nphdl, &lp) == 0) { 2905 inot->initiator_id = CAM_TARGET_WILDCARD; 2906 } else { 2907 inot->initiator_id = FC_PORTDB_TGT(isp, notify->nt_channel, lp); 2908 } 2909 inot->seq_id = notify->nt_tagval; 2910 inot->tag_id = notify->nt_tagval >> 32; 2911 2912 switch (notify->nt_ncode) { 2913 case NT_ABORT_TASK: 2914 isp_target_mark_aborted_early(isp, tptr, inot->tag_id); 2915 inot->arg = MSG_ABORT_TASK; 2916 break; 2917 case NT_ABORT_TASK_SET: 2918 isp_target_mark_aborted_early(isp, tptr, TAG_ANY); 2919 inot->arg = MSG_ABORT_TASK_SET; 2920 break; 2921 case NT_CLEAR_ACA: 2922 inot->arg = MSG_CLEAR_ACA; 2923 break; 2924 case NT_CLEAR_TASK_SET: 2925 inot->arg = MSG_CLEAR_TASK_SET; 2926 break; 2927 case NT_LUN_RESET: 2928 inot->arg = MSG_LOGICAL_UNIT_RESET; 2929 break; 2930 case NT_TARGET_RESET: 2931 inot->arg = MSG_TARGET_RESET; 2932 break; 2933 case NT_QUERY_TASK_SET: 2934 inot->arg = MSG_QUERY_TASK_SET; 2935 break; 2936 case NT_QUERY_ASYNC_EVENT: 2937 inot->arg = MSG_QUERY_ASYNC_EVENT; 2938 break; 2939 default: 2940 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); 2941 goto bad; 2942 } 2943 2944 ntp = isp_get_ntpd(isp, tptr); 2945 if (ntp == NULL) { 2946 isp_prt(isp, ISP_LOGWARN, "%s: out of inotify private structures", __func__); 2947 goto bad; 2948 } 2949 ISP_MEMCPY(&ntp->rd.nt, notify, sizeof (isp_notify_t)); 2950 if (notify->nt_lreserved) { 2951 ISP_MEMCPY(&ntp->rd.data, notify->nt_lreserved, QENTRY_LEN); 2952 ntp->rd.nt.nt_lreserved = &ntp->rd.data; 2953 } 2954 ntp->rd.seq_id = notify->nt_tagval; 2955 ntp->rd.tag_id = notify->nt_tagval >> 32; 2956 2957 tptr->inot_count--; 2958 SLIST_REMOVE_HEAD(&tptr->inots, sim_links.sle); 2959 rls_lun_statep(isp, tptr); 2960 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, inot->ccb_h.path, "%s: Take FREE INOT count now %d\n", __func__, tptr->inot_count); 2961 inot->ccb_h.status = CAM_MESSAGE_RECV; 2962 xpt_done((union ccb *)inot); 2963 return; 2964 bad: 2965 if (tptr) { 2966 rls_lun_statep(isp, tptr); 2967 } 2968 if (notify->nt_need_ack && notify->nt_lreserved) { 2969 if (((isphdr_t *)notify->nt_lreserved)->rqs_entry_type == RQSTYPE_ABTS_RCVD) { 2970 if (isp_acknak_abts(isp, notify->nt_lreserved, ENOMEM)) { 2971 isp_prt(isp, ISP_LOGWARN, "you lose- unable to send an ACKNAK"); 2972 } 2973 } else { 2974 isp_async(isp, ISPASYNC_TARGET_NOTIFY_ACK, notify->nt_lreserved); 2975 } 2976 } 2977 } 2978 2979 /* 2980 * Find the associated private data and mark it as dead so 2981 * we don't try to work on it any further. 2982 */ 2983 static void 2984 isp_target_mark_aborted(ispsoftc_t *isp, union ccb *ccb) 2985 { 2986 tstate_t *tptr; 2987 atio_private_data_t *atp; 2988 union ccb *accb = ccb->cab.abort_ccb; 2989 2990 tptr = get_lun_statep(isp, XS_CHANNEL(accb), XS_LUN(accb)); 2991 if (tptr == NULL) { 2992 tptr = get_lun_statep(isp, XS_CHANNEL(accb), CAM_LUN_WILDCARD); 2993 if (tptr == NULL) { 2994 ccb->ccb_h.status = CAM_REQ_INVALID; 2995 return; 2996 } 2997 } 2998 2999 atp = isp_find_atpd(isp, tptr, accb->atio.tag_id); 3000 if (atp == NULL) { 3001 ccb->ccb_h.status = CAM_REQ_INVALID; 3002 } else { 3003 atp->dead = 1; 3004 ccb->ccb_h.status = CAM_REQ_CMP; 3005 } 3006 rls_lun_statep(isp, tptr); 3007 } 3008 3009 static void 3010 isp_target_mark_aborted_early(ispsoftc_t *isp, tstate_t *tptr, uint32_t tag_id) 3011 { 3012 atio_private_data_t *atp; 3013 inot_private_data_t *restart_queue = tptr->restart_queue; 3014 3015 /* 3016 * First, clean any commands pending restart 3017 */ 3018 tptr->restart_queue = NULL; 3019 while (restart_queue) { 3020 uint32_t this_tag_id; 3021 inot_private_data_t *ntp = restart_queue; 3022 3023 restart_queue = ntp->rd.nt.nt_hba; 3024 3025 if (IS_24XX(isp)) { 3026 this_tag_id = ((at7_entry_t *)ntp->rd.data)->at_rxid; 3027 } else { 3028 this_tag_id = ((at2_entry_t *)ntp->rd.data)->at_rxid; 3029 } 3030 if ((uint64_t)tag_id == TAG_ANY || tag_id == this_tag_id) { 3031 isp_put_ntpd(isp, tptr, ntp); 3032 } else { 3033 ntp->rd.nt.nt_hba = tptr->restart_queue; 3034 tptr->restart_queue = ntp; 3035 } 3036 } 3037 3038 /* 3039 * Now mark other ones dead as well. 3040 */ 3041 for (atp = tptr->atpool; atp < &tptr->atpool[ATPDPSIZE]; atp++) { 3042 if ((uint64_t)tag_id == TAG_ANY || atp->tag == tag_id) { 3043 atp->dead = 1; 3044 } 3045 } 3046 } 3047 #endif 3048 3049 static void 3050 isp_cam_async(void *cbarg, uint32_t code, struct cam_path *path, void *arg) 3051 { 3052 struct cam_sim *sim; 3053 int bus, tgt; 3054 ispsoftc_t *isp; 3055 3056 sim = (struct cam_sim *)cbarg; 3057 isp = (ispsoftc_t *) cam_sim_softc(sim); 3058 bus = cam_sim_bus(sim); 3059 tgt = xpt_path_target_id(path); 3060 3061 switch (code) { 3062 case AC_LOST_DEVICE: 3063 if (IS_SCSI(isp)) { 3064 uint16_t oflags, nflags; 3065 sdparam *sdp = SDPARAM(isp, bus); 3066 3067 if (tgt >= 0) { 3068 nflags = sdp->isp_devparam[tgt].nvrm_flags; 3069 nflags &= DPARM_SAFE_DFLT; 3070 if (isp->isp_loaded_fw) { 3071 nflags |= DPARM_NARROW | DPARM_ASYNC; 3072 } 3073 oflags = sdp->isp_devparam[tgt].goal_flags; 3074 sdp->isp_devparam[tgt].goal_flags = nflags; 3075 sdp->isp_devparam[tgt].dev_update = 1; 3076 sdp->update = 1; 3077 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus); 3078 sdp->isp_devparam[tgt].goal_flags = oflags; 3079 } 3080 } 3081 break; 3082 default: 3083 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code); 3084 break; 3085 } 3086 } 3087 3088 static void 3089 isp_poll(struct cam_sim *sim) 3090 { 3091 ispsoftc_t *isp = cam_sim_softc(sim); 3092 uint16_t isr, sema, info; 3093 3094 if (ISP_READ_ISR(isp, &isr, &sema, &info)) 3095 isp_intr(isp, isr, sema, info); 3096 } 3097 3098 3099 static void 3100 isp_watchdog(void *arg) 3101 { 3102 struct ccb_scsiio *xs = arg; 3103 ispsoftc_t *isp; 3104 uint32_t ohandle = ISP_HANDLE_FREE, handle; 3105 3106 isp = XS_ISP(xs); 3107 3108 handle = isp_find_handle(isp, xs); 3109 3110 /* 3111 * Hand crank the interrupt code just to be sure the command isn't stuck somewhere. 3112 */ 3113 if (handle != ISP_HANDLE_FREE) { 3114 uint16_t isr, sema, info; 3115 if (ISP_READ_ISR(isp, &isr, &sema, &info) != 0) 3116 isp_intr(isp, isr, sema, info); 3117 ohandle = handle; 3118 handle = isp_find_handle(isp, xs); 3119 } 3120 if (handle != ISP_HANDLE_FREE) { 3121 /* 3122 * Try and make sure the command is really dead before 3123 * we release the handle (and DMA resources) for reuse. 3124 * 3125 * If we are successful in aborting the command then 3126 * we're done here because we'll get the command returned 3127 * back separately. 3128 */ 3129 if (isp_control(isp, ISPCTL_ABORT_CMD, xs) == 0) { 3130 return; 3131 } 3132 3133 /* 3134 * Note that after calling the above, the command may in 3135 * fact have been completed. 3136 */ 3137 xs = isp_find_xs(isp, handle); 3138 3139 /* 3140 * If the command no longer exists, then we won't 3141 * be able to find the xs again with this handle. 3142 */ 3143 if (xs == NULL) { 3144 return; 3145 } 3146 3147 /* 3148 * After this point, the command is really dead. 3149 */ 3150 if (XS_XFRLEN(xs)) { 3151 ISP_DMAFREE(isp, xs, handle); 3152 } 3153 isp_destroy_handle(isp, handle); 3154 isp_prt(isp, ISP_LOGERR, "%s: timeout for handle 0x%x", __func__, handle); 3155 xs->ccb_h.status &= ~CAM_STATUS_MASK; 3156 xs->ccb_h.status |= CAM_CMD_TIMEOUT; 3157 isp_prt_endcmd(isp, xs); 3158 isp_done(xs); 3159 } else { 3160 if (ohandle != ISP_HANDLE_FREE) { 3161 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle 0x%x, recovered during interrupt", __func__, ohandle); 3162 } else { 3163 isp_prt(isp, ISP_LOGWARN, "%s: timeout for handle already free", __func__); 3164 } 3165 } 3166 } 3167 3168 static void 3169 isp_make_here(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) 3170 { 3171 union ccb *ccb; 3172 struct isp_fc *fc = ISP_FC_PC(isp, chan); 3173 3174 /* 3175 * Allocate a CCB, create a wildcard path for this target and schedule a rescan. 3176 */ 3177 ccb = xpt_alloc_ccb_nowait(); 3178 if (ccb == NULL) { 3179 isp_prt(isp, ISP_LOGWARN, "Chan %d unable to alloc CCB for rescan", chan); 3180 return; 3181 } 3182 if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(fc->sim), 3183 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 3184 isp_prt(isp, ISP_LOGWARN, "unable to create path for rescan"); 3185 xpt_free_ccb(ccb); 3186 return; 3187 } 3188 xpt_rescan(ccb); 3189 } 3190 3191 static void 3192 isp_make_gone(ispsoftc_t *isp, fcportdb_t *fcp, int chan, int tgt) 3193 { 3194 struct cam_path *tp; 3195 struct isp_fc *fc = ISP_FC_PC(isp, chan); 3196 3197 if (xpt_create_path(&tp, NULL, cam_sim_path(fc->sim), tgt, CAM_LUN_WILDCARD) == CAM_REQ_CMP) { 3198 xpt_async(AC_LOST_DEVICE, tp, NULL); 3199 xpt_free_path(tp); 3200 } 3201 } 3202 3203 /* 3204 * Gone Device Timer Function- when we have decided that a device has gone 3205 * away, we wait a specific period of time prior to telling the OS it has 3206 * gone away. 3207 * 3208 * This timer function fires once a second and then scans the port database 3209 * for devices that are marked dead but still have a virtual target assigned. 3210 * We decrement a counter for that port database entry, and when it hits zero, 3211 * we tell the OS the device has gone away. 3212 */ 3213 static void 3214 isp_gdt(void *arg) 3215 { 3216 struct isp_fc *fc = arg; 3217 taskqueue_enqueue(taskqueue_thread, &fc->gtask); 3218 } 3219 3220 static void 3221 isp_gdt_task(void *arg, int pending) 3222 { 3223 struct isp_fc *fc = arg; 3224 ispsoftc_t *isp = fc->isp; 3225 int chan = fc - isp->isp_osinfo.pc.fc; 3226 fcportdb_t *lp; 3227 struct ac_contract ac; 3228 struct ac_device_changed *adc; 3229 int dbidx, more_to_do = 0; 3230 3231 ISP_LOCK(isp); 3232 isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GDT timer expired", chan); 3233 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3234 lp = &FCPARAM(isp, chan)->portdb[dbidx]; 3235 3236 if (lp->state != FC_PORTDB_STATE_ZOMBIE) { 3237 continue; 3238 } 3239 if (lp->gone_timer != 0) { 3240 lp->gone_timer -= 1; 3241 more_to_do++; 3242 continue; 3243 } 3244 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Gone Device Timeout"); 3245 if (lp->is_target) { 3246 lp->is_target = 0; 3247 isp_make_gone(isp, lp, chan, dbidx); 3248 } 3249 if (lp->is_initiator) { 3250 lp->is_initiator = 0; 3251 ac.contract_number = AC_CONTRACT_DEV_CHG; 3252 adc = (struct ac_device_changed *) ac.contract_data; 3253 adc->wwpn = lp->port_wwn; 3254 adc->port = lp->portid; 3255 adc->target = dbidx; 3256 adc->arrived = 0; 3257 xpt_async(AC_CONTRACT, fc->path, &ac); 3258 } 3259 lp->state = FC_PORTDB_STATE_NIL; 3260 } 3261 if (fc->ready) { 3262 if (more_to_do) { 3263 callout_reset(&fc->gdt, hz, isp_gdt, fc); 3264 } else { 3265 callout_deactivate(&fc->gdt); 3266 isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Stopping Gone Device Timer @ %lu", chan, (unsigned long) time_uptime); 3267 } 3268 } 3269 ISP_UNLOCK(isp); 3270 } 3271 3272 /* 3273 * Loop Down Timer Function- when loop goes down, a timer is started and 3274 * and after it expires we come here and take all probational devices that 3275 * the OS knows about and the tell the OS that they've gone away. 3276 * 3277 * We don't clear the devices out of our port database because, when loop 3278 * come back up, we have to do some actual cleanup with the chip at that 3279 * point (implicit PLOGO, e.g., to get the chip's port database state right). 3280 */ 3281 static void 3282 isp_ldt(void *arg) 3283 { 3284 struct isp_fc *fc = arg; 3285 taskqueue_enqueue(taskqueue_thread, &fc->ltask); 3286 } 3287 3288 static void 3289 isp_ldt_task(void *arg, int pending) 3290 { 3291 struct isp_fc *fc = arg; 3292 ispsoftc_t *isp = fc->isp; 3293 int chan = fc - isp->isp_osinfo.pc.fc; 3294 fcportdb_t *lp; 3295 struct ac_contract ac; 3296 struct ac_device_changed *adc; 3297 int dbidx, i; 3298 3299 ISP_LOCK(isp); 3300 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Chan %d Loop Down Timer expired @ %lu", chan, (unsigned long) time_uptime); 3301 callout_deactivate(&fc->ldt); 3302 3303 /* 3304 * Notify to the OS all targets who we now consider have departed. 3305 */ 3306 for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) { 3307 lp = &FCPARAM(isp, chan)->portdb[dbidx]; 3308 3309 if (lp->state == FC_PORTDB_STATE_NIL) 3310 continue; 3311 3312 /* 3313 * XXX: CLEAN UP AND COMPLETE ANY PENDING COMMANDS FIRST! 3314 */ 3315 for (i = 0; i < isp->isp_maxcmds; i++) { 3316 struct ccb_scsiio *xs; 3317 3318 if (!ISP_VALID_HANDLE(isp, isp->isp_xflist[i].handle)) { 3319 continue; 3320 } 3321 if ((xs = isp->isp_xflist[i].cmd) == NULL) { 3322 continue; 3323 } 3324 if (dbidx != XS_TGT(xs)) { 3325 continue; 3326 } 3327 isp_prt(isp, ISP_LOGWARN, "command handle 0x%x for %d.%d.%jx orphaned by loop down timeout", 3328 isp->isp_xflist[i].handle, chan, XS_TGT(xs), 3329 (uintmax_t)XS_LUN(xs)); 3330 } 3331 3332 isp_prt(isp, ISP_LOGCONFIG, prom3, chan, dbidx, lp->portid, "Loop Down Timeout"); 3333 if (lp->is_target) { 3334 lp->is_target = 0; 3335 isp_make_gone(isp, lp, chan, dbidx); 3336 } 3337 if (lp->is_initiator) { 3338 lp->is_initiator = 0; 3339 ac.contract_number = AC_CONTRACT_DEV_CHG; 3340 adc = (struct ac_device_changed *) ac.contract_data; 3341 adc->wwpn = lp->port_wwn; 3342 adc->port = lp->portid; 3343 adc->target = dbidx; 3344 adc->arrived = 0; 3345 xpt_async(AC_CONTRACT, fc->path, &ac); 3346 } 3347 } 3348 3349 isp_unfreeze_loopdown(isp, chan); 3350 /* 3351 * The loop down timer has expired. Wake up the kthread 3352 * to notice that fact (or make it false). 3353 */ 3354 fc->loop_dead = 1; 3355 fc->loop_down_time = fc->loop_down_limit+1; 3356 wakeup(fc); 3357 ISP_UNLOCK(isp); 3358 } 3359 3360 static void 3361 isp_kthread(void *arg) 3362 { 3363 struct isp_fc *fc = arg; 3364 ispsoftc_t *isp = fc->isp; 3365 int chan = fc - isp->isp_osinfo.pc.fc; 3366 int slp = 0; 3367 3368 mtx_lock(&isp->isp_osinfo.lock); 3369 3370 while (isp->isp_osinfo.is_exiting == 0) { 3371 int lb, lim; 3372 3373 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d checking FC state", __func__, chan); 3374 lb = isp_fc_runstate(isp, chan, 250000); 3375 3376 /* 3377 * Our action is different based upon whether we're supporting 3378 * Initiator mode or not. If we are, we might freeze the simq 3379 * when loop is down and set all sorts of different delays to 3380 * check again. 3381 * 3382 * If not, we simply just wait for loop to come up. 3383 */ 3384 if (lb && (FCPARAM(isp, chan)->role & ISP_ROLE_INITIATOR)) { 3385 /* 3386 * Increment loop down time by the last sleep interval 3387 */ 3388 fc->loop_down_time += slp; 3389 3390 if (lb < 0) { 3391 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC loop not up (down count %d)", __func__, chan, fc->loop_down_time); 3392 } else { 3393 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); 3394 } 3395 3396 /* 3397 * If we've never seen loop up and we've waited longer 3398 * than quickboot time, or we've seen loop up but we've 3399 * waited longer than loop_down_limit, give up and go 3400 * to sleep until loop comes up. 3401 */ 3402 if (FCPARAM(isp, chan)->loop_seen_once == 0) { 3403 lim = isp_quickboot_time; 3404 } else { 3405 lim = fc->loop_down_limit; 3406 } 3407 if (fc->loop_down_time >= lim) { 3408 isp_freeze_loopdown(isp, chan, "loop limit hit"); 3409 slp = 0; 3410 } else if (fc->loop_down_time < 10) { 3411 slp = 1; 3412 } else if (fc->loop_down_time < 30) { 3413 slp = 5; 3414 } else if (fc->loop_down_time < 60) { 3415 slp = 10; 3416 } else if (fc->loop_down_time < 120) { 3417 slp = 20; 3418 } else { 3419 slp = 30; 3420 } 3421 3422 } else if (lb) { 3423 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC Loop Down", __func__, chan); 3424 fc->loop_down_time += slp; 3425 if (fc->loop_down_time > 300) 3426 slp = 0; 3427 else 3428 slp = 60; 3429 } else { 3430 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d FC state OK", __func__, chan); 3431 fc->loop_down_time = 0; 3432 slp = 0; 3433 } 3434 3435 3436 /* 3437 * If this is past the first loop up or the loop is dead and if we'd frozen the simq, unfreeze it 3438 * now so that CAM can start sending us commands. 3439 * 3440 * If the FC state isn't okay yet, they'll hit that in isp_start which will freeze the queue again 3441 * or kill the commands, as appropriate. 3442 */ 3443 3444 if (FCPARAM(isp, chan)->loop_seen_once || fc->loop_dead) { 3445 isp_unfreeze_loopdown(isp, chan); 3446 } 3447 3448 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep time %d", __func__, chan, slp); 3449 3450 msleep(fc, &isp->isp_osinfo.lock, PRIBIO, "ispf", slp * hz); 3451 3452 /* 3453 * If slp is zero, we're waking up for the first time after 3454 * things have been okay. In this case, we set a deferral state 3455 * for all commands and delay hysteresis seconds before starting 3456 * the FC state evaluation. This gives the loop/fabric a chance 3457 * to settle. 3458 */ 3459 if (slp == 0 && fc->hysteresis) { 3460 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "%s: Chan %d sleep hysteresis ticks %d", __func__, chan, fc->hysteresis * hz); 3461 mtx_unlock(&isp->isp_osinfo.lock); 3462 pause("ispt", fc->hysteresis * hz); 3463 mtx_lock(&isp->isp_osinfo.lock); 3464 } 3465 } 3466 fc->num_threads -= 1; 3467 mtx_unlock(&isp->isp_osinfo.lock); 3468 kthread_exit(); 3469 } 3470 3471 static void 3472 isp_action(struct cam_sim *sim, union ccb *ccb) 3473 { 3474 int bus, tgt, ts, error, lim; 3475 ispsoftc_t *isp; 3476 struct ccb_trans_settings *cts; 3477 3478 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 3479 3480 isp = (ispsoftc_t *)cam_sim_softc(sim); 3481 mtx_assert(&isp->isp_lock, MA_OWNED); 3482 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); 3483 ISP_PCMD(ccb) = NULL; 3484 3485 switch (ccb->ccb_h.func_code) { 3486 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 3487 bus = XS_CHANNEL(ccb); 3488 /* 3489 * Do a couple of preliminary checks... 3490 */ 3491 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 3492 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 3493 ccb->ccb_h.status = CAM_REQ_INVALID; 3494 isp_done((struct ccb_scsiio *) ccb); 3495 break; 3496 } 3497 } 3498 ccb->csio.req_map = NULL; 3499 #ifdef DIAGNOSTIC 3500 if (ccb->ccb_h.target_id >= ISP_MAX_TARGETS(isp)) { 3501 xpt_print(ccb->ccb_h.path, "invalid target\n"); 3502 ccb->ccb_h.status = CAM_PATH_INVALID; 3503 } else if (ISP_MAX_LUNS(isp) > 0 && 3504 ccb->ccb_h.target_lun >= ISP_MAX_LUNS(isp)) { 3505 xpt_print(ccb->ccb_h.path, "invalid lun\n"); 3506 ccb->ccb_h.status = CAM_PATH_INVALID; 3507 } 3508 if (ccb->ccb_h.status == CAM_PATH_INVALID) { 3509 xpt_done(ccb); 3510 break; 3511 } 3512 #endif 3513 ccb->csio.scsi_status = SCSI_STATUS_OK; 3514 if (isp_get_pcmd(isp, ccb)) { 3515 isp_prt(isp, ISP_LOGWARN, "out of PCMDs"); 3516 cam_freeze_devq(ccb->ccb_h.path); 3517 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 250, 0); 3518 ccb->ccb_h.status = CAM_REQUEUE_REQ; 3519 xpt_done(ccb); 3520 break; 3521 } 3522 error = isp_start((XS_T *) ccb); 3523 switch (error) { 3524 case CMD_QUEUED: 3525 ccb->ccb_h.status |= CAM_SIM_QUEUED; 3526 if (ccb->ccb_h.timeout == CAM_TIME_INFINITY) { 3527 break; 3528 } 3529 ts = ccb->ccb_h.timeout; 3530 if (ts == CAM_TIME_DEFAULT) { 3531 ts = 60*1000; 3532 } 3533 ts = isp_mstohz(ts); 3534 callout_reset(&PISP_PCMD(ccb)->wdog, ts, isp_watchdog, ccb); 3535 break; 3536 case CMD_RQLATER: 3537 /* 3538 * We get this result for FC devices if the loop state isn't ready yet 3539 * or if the device in question has gone zombie on us. 3540 * 3541 * If we've never seen Loop UP at all, we requeue this request and wait 3542 * for the initial loop up delay to expire. 3543 */ 3544 lim = ISP_FC_PC(isp, bus)->loop_down_limit; 3545 if (FCPARAM(isp, bus)->loop_seen_once == 0 || ISP_FC_PC(isp, bus)->loop_down_time >= lim) { 3546 if (FCPARAM(isp, bus)->loop_seen_once == 0) { 3547 isp_prt(isp, ISP_LOGDEBUG0, 3548 "%d.%jx loop not seen yet @ %lu", 3549 XS_TGT(ccb), (uintmax_t)XS_LUN(ccb), 3550 (unsigned long) time_uptime); 3551 } else { 3552 isp_prt(isp, ISP_LOGDEBUG0, 3553 "%d.%jx downtime (%d) > lim (%d)", 3554 XS_TGT(ccb), (uintmax_t)XS_LUN(ccb), 3555 ISP_FC_PC(isp, bus)->loop_down_time, 3556 lim); 3557 } 3558 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 3559 isp_done((struct ccb_scsiio *) ccb); 3560 break; 3561 } 3562 isp_prt(isp, ISP_LOGDEBUG0, "%d.%jx retry later", 3563 XS_TGT(ccb), (uintmax_t)XS_LUN(ccb)); 3564 cam_freeze_devq(ccb->ccb_h.path); 3565 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0); 3566 ccb->ccb_h.status = CAM_REQUEUE_REQ; 3567 isp_free_pcmd(isp, ccb); 3568 xpt_done(ccb); 3569 break; 3570 case CMD_EAGAIN: 3571 isp_free_pcmd(isp, ccb); 3572 cam_freeze_devq(ccb->ccb_h.path); 3573 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 100, 0); 3574 ccb->ccb_h.status = CAM_REQUEUE_REQ; 3575 xpt_done(ccb); 3576 break; 3577 case CMD_COMPLETE: 3578 isp_done((struct ccb_scsiio *) ccb); 3579 break; 3580 default: 3581 isp_prt(isp, ISP_LOGERR, "What's this? 0x%x at %d in file %s", error, __LINE__, __FILE__); 3582 ccb->ccb_h.status = CAM_REQUEUE_REQ; 3583 isp_free_pcmd(isp, ccb); 3584 xpt_done(ccb); 3585 } 3586 break; 3587 3588 #ifdef ISP_TARGET_MODE 3589 case XPT_EN_LUN: /* Enable/Disable LUN as a target */ 3590 if (ccb->cel.enable) { 3591 isp_enable_lun(isp, ccb); 3592 } else { 3593 isp_disable_lun(isp, ccb); 3594 } 3595 break; 3596 case XPT_IMMED_NOTIFY: 3597 case XPT_IMMEDIATE_NOTIFY: /* Add Immediate Notify Resource */ 3598 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 3599 { 3600 tstate_t *tptr = get_lun_statep(isp, XS_CHANNEL(ccb), ccb->ccb_h.target_lun); 3601 if (tptr == NULL) { 3602 tptr = get_lun_statep(isp, XS_CHANNEL(ccb), CAM_LUN_WILDCARD); 3603 } 3604 if (tptr == NULL) { 3605 const char *str; 3606 uint32_t tag; 3607 3608 if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) { 3609 str = "XPT_IMMEDIATE_NOTIFY"; 3610 tag = ccb->cin1.seq_id; 3611 } else { 3612 tag = ccb->atio.tag_id; 3613 str = "XPT_ACCEPT_TARGET_IO"; 3614 } 3615 ISP_PATH_PRT(isp, ISP_LOGWARN, ccb->ccb_h.path, "%s: [0x%x] no state pointer found for %s\n", __func__, tag, str); 3616 dump_tstates(isp, XS_CHANNEL(ccb)); 3617 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 3618 break; 3619 } 3620 ccb->ccb_h.spriv_field0 = 0; 3621 ccb->ccb_h.spriv_ptr1 = isp; 3622 3623 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 3624 if (ccb->atio.tag_id) { 3625 atio_private_data_t *atp = isp_find_atpd(isp, tptr, ccb->atio.tag_id); 3626 if (atp) { 3627 isp_put_atpd(isp, tptr, atp); 3628 } 3629 } 3630 tptr->atio_count++; 3631 SLIST_INSERT_HEAD(&tptr->atios, &ccb->ccb_h, sim_links.sle); 3632 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE ATIO (tag id 0x%x), count now %d\n", 3633 ccb->atio.tag_id, tptr->atio_count); 3634 ccb->atio.tag_id = 0; 3635 } else if (ccb->ccb_h.func_code == XPT_IMMEDIATE_NOTIFY) { 3636 if (ccb->cin1.tag_id) { 3637 inot_private_data_t *ntp = isp_find_ntpd(isp, tptr, ccb->cin1.tag_id, ccb->cin1.seq_id); 3638 if (ntp) { 3639 isp_put_ntpd(isp, tptr, ntp); 3640 } 3641 } 3642 tptr->inot_count++; 3643 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); 3644 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", 3645 ccb->cin1.seq_id, tptr->inot_count); 3646 ccb->cin1.seq_id = 0; 3647 } else if (ccb->ccb_h.func_code == XPT_IMMED_NOTIFY) { 3648 tptr->inot_count++; 3649 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, sim_links.sle); 3650 ISP_PATH_PRT(isp, ISP_LOGTDEBUG2, ccb->ccb_h.path, "Put FREE INOT, (seq id 0x%x) count now %d\n", 3651 ccb->cin1.seq_id, tptr->inot_count); 3652 ccb->cin1.seq_id = 0; 3653 } 3654 rls_lun_statep(isp, tptr); 3655 ccb->ccb_h.status = CAM_REQ_INPROG; 3656 break; 3657 } 3658 case XPT_NOTIFY_ACK: 3659 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 3660 break; 3661 case XPT_NOTIFY_ACKNOWLEDGE: /* notify ack */ 3662 { 3663 tstate_t *tptr; 3664 inot_private_data_t *ntp; 3665 3666 /* 3667 * XXX: Because we cannot guarantee that the path information in the notify acknowledge ccb 3668 * XXX: matches that for the immediate notify, we have to *search* for the notify structure 3669 */ 3670 /* 3671 * All the relevant path information is in the associated immediate notify 3672 */ 3673 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); 3674 ntp = get_ntp_from_tagdata(isp, ccb->cna2.tag_id, ccb->cna2.seq_id, &tptr); 3675 if (ntp == NULL) { 3676 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__, 3677 ccb->cna2.tag_id, ccb->cna2.seq_id); 3678 ccb->ccb_h.status = CAM_DEV_NOT_THERE; 3679 xpt_done(ccb); 3680 break; 3681 } 3682 if (isp_handle_platform_target_notify_ack(isp, &ntp->rd.nt)) { 3683 rls_lun_statep(isp, tptr); 3684 cam_freeze_devq(ccb->ccb_h.path); 3685 cam_release_devq(ccb->ccb_h.path, RELSIM_RELEASE_AFTER_TIMEOUT, 0, 1000, 0); 3686 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 3687 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 3688 break; 3689 } 3690 isp_put_ntpd(isp, tptr, ntp); 3691 rls_lun_statep(isp, tptr); 3692 ccb->ccb_h.status = CAM_REQ_CMP; 3693 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); 3694 xpt_done(ccb); 3695 break; 3696 } 3697 case XPT_CONT_TARGET_IO: 3698 isp_target_start_ctio(isp, ccb, FROM_CAM); 3699 break; 3700 #endif 3701 case XPT_RESET_DEV: /* BDR the specified SCSI device */ 3702 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)); 3703 tgt = ccb->ccb_h.target_id; 3704 tgt |= (bus << 16); 3705 3706 error = isp_control(isp, ISPCTL_RESET_DEV, bus, tgt); 3707 if (error) { 3708 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 3709 } else { 3710 /* 3711 * If we have a FC device, reset the Command 3712 * Reference Number, because the target will expect 3713 * that we re-start the CRN at 1 after a reset. 3714 */ 3715 if (IS_FC(isp)) 3716 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1); 3717 3718 ccb->ccb_h.status = CAM_REQ_CMP; 3719 } 3720 xpt_done(ccb); 3721 break; 3722 case XPT_ABORT: /* Abort the specified CCB */ 3723 { 3724 union ccb *accb = ccb->cab.abort_ccb; 3725 switch (accb->ccb_h.func_code) { 3726 #ifdef ISP_TARGET_MODE 3727 case XPT_ACCEPT_TARGET_IO: 3728 isp_target_mark_aborted(isp, ccb); 3729 break; 3730 #endif 3731 case XPT_SCSI_IO: 3732 error = isp_control(isp, ISPCTL_ABORT_CMD, accb); 3733 if (error) { 3734 ccb->ccb_h.status = CAM_UA_ABORT; 3735 } else { 3736 ccb->ccb_h.status = CAM_REQ_CMP; 3737 } 3738 break; 3739 default: 3740 ccb->ccb_h.status = CAM_REQ_INVALID; 3741 break; 3742 } 3743 /* 3744 * This is not a queued CCB, so the caller expects it to be 3745 * complete when control is returned. 3746 */ 3747 break; 3748 } 3749 #define IS_CURRENT_SETTINGS(c) (c->type == CTS_TYPE_CURRENT_SETTINGS) 3750 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */ 3751 cts = &ccb->cts; 3752 if (!IS_CURRENT_SETTINGS(cts)) { 3753 ccb->ccb_h.status = CAM_REQ_INVALID; 3754 xpt_done(ccb); 3755 break; 3756 } 3757 tgt = cts->ccb_h.target_id; 3758 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 3759 if (IS_SCSI(isp)) { 3760 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 3761 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; 3762 sdparam *sdp = SDPARAM(isp, bus); 3763 uint16_t *dptr; 3764 3765 if (spi->valid == 0 && scsi->valid == 0) { 3766 ccb->ccb_h.status = CAM_REQ_CMP; 3767 xpt_done(ccb); 3768 break; 3769 } 3770 3771 /* 3772 * We always update (internally) from goal_flags 3773 * so any request to change settings just gets 3774 * vectored to that location. 3775 */ 3776 dptr = &sdp->isp_devparam[tgt].goal_flags; 3777 3778 if ((spi->valid & CTS_SPI_VALID_DISC) != 0) { 3779 if ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) != 0) 3780 *dptr |= DPARM_DISC; 3781 else 3782 *dptr &= ~DPARM_DISC; 3783 } 3784 3785 if ((scsi->valid & CTS_SCSI_VALID_TQ) != 0) { 3786 if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) 3787 *dptr |= DPARM_TQING; 3788 else 3789 *dptr &= ~DPARM_TQING; 3790 } 3791 3792 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0) { 3793 if (spi->bus_width == MSG_EXT_WDTR_BUS_16_BIT) 3794 *dptr |= DPARM_WIDE; 3795 else 3796 *dptr &= ~DPARM_WIDE; 3797 } 3798 3799 /* 3800 * XXX: FIX ME 3801 */ 3802 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) && (spi->valid & CTS_SPI_VALID_SYNC_RATE) && (spi->sync_period && spi->sync_offset)) { 3803 *dptr |= DPARM_SYNC; 3804 /* 3805 * XXX: CHECK FOR LEGALITY 3806 */ 3807 sdp->isp_devparam[tgt].goal_period = spi->sync_period; 3808 sdp->isp_devparam[tgt].goal_offset = spi->sync_offset; 3809 } else { 3810 *dptr &= ~DPARM_SYNC; 3811 } 3812 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, 3813 sdp->isp_devparam[tgt].goal_offset, sdp->isp_devparam[tgt].goal_period); 3814 sdp->isp_devparam[tgt].dev_update = 1; 3815 sdp->update = 1; 3816 } 3817 ccb->ccb_h.status = CAM_REQ_CMP; 3818 xpt_done(ccb); 3819 break; 3820 case XPT_GET_TRAN_SETTINGS: 3821 cts = &ccb->cts; 3822 tgt = cts->ccb_h.target_id; 3823 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 3824 if (IS_FC(isp)) { 3825 fcparam *fcp = FCPARAM(isp, bus); 3826 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 3827 struct ccb_trans_settings_fc *fc = &cts->xport_specific.fc; 3828 3829 cts->protocol = PROTO_SCSI; 3830 cts->protocol_version = SCSI_REV_2; 3831 cts->transport = XPORT_FC; 3832 cts->transport_version = 0; 3833 3834 scsi->valid = CTS_SCSI_VALID_TQ; 3835 scsi->flags = CTS_SCSI_FLAGS_TAG_ENB; 3836 fc->valid = CTS_FC_VALID_SPEED; 3837 fc->bitrate = 100000; 3838 fc->bitrate *= fcp->isp_gbspeed; 3839 if (tgt < MAX_FC_TARG) { 3840 fcportdb_t *lp = &fcp->portdb[tgt]; 3841 fc->wwnn = lp->node_wwn; 3842 fc->wwpn = lp->port_wwn; 3843 fc->port = lp->portid; 3844 fc->valid |= CTS_FC_VALID_WWNN | CTS_FC_VALID_WWPN | CTS_FC_VALID_PORT; 3845 } 3846 } else { 3847 struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; 3848 struct ccb_trans_settings_spi *spi = &cts->xport_specific.spi; 3849 sdparam *sdp = SDPARAM(isp, bus); 3850 uint16_t dval, pval, oval; 3851 3852 if (IS_CURRENT_SETTINGS(cts)) { 3853 sdp->isp_devparam[tgt].dev_refresh = 1; 3854 sdp->update = 1; 3855 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, bus); 3856 dval = sdp->isp_devparam[tgt].actv_flags; 3857 oval = sdp->isp_devparam[tgt].actv_offset; 3858 pval = sdp->isp_devparam[tgt].actv_period; 3859 } else { 3860 dval = sdp->isp_devparam[tgt].nvrm_flags; 3861 oval = sdp->isp_devparam[tgt].nvrm_offset; 3862 pval = sdp->isp_devparam[tgt].nvrm_period; 3863 } 3864 3865 cts->protocol = PROTO_SCSI; 3866 cts->protocol_version = SCSI_REV_2; 3867 cts->transport = XPORT_SPI; 3868 cts->transport_version = 2; 3869 3870 spi->valid = 0; 3871 scsi->valid = 0; 3872 spi->flags = 0; 3873 scsi->flags = 0; 3874 if (dval & DPARM_DISC) { 3875 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 3876 } 3877 if ((dval & DPARM_SYNC) && oval && pval) { 3878 spi->sync_offset = oval; 3879 spi->sync_period = pval; 3880 } else { 3881 spi->sync_offset = 0; 3882 spi->sync_period = 0; 3883 } 3884 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 3885 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 3886 spi->valid |= CTS_SPI_VALID_BUS_WIDTH; 3887 if (dval & DPARM_WIDE) { 3888 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 3889 } else { 3890 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 3891 } 3892 if (cts->ccb_h.target_lun != CAM_LUN_WILDCARD) { 3893 scsi->valid = CTS_SCSI_VALID_TQ; 3894 if (dval & DPARM_TQING) { 3895 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 3896 } 3897 spi->valid |= CTS_SPI_VALID_DISC; 3898 } 3899 isp_prt(isp, ISP_LOGDEBUG0, "GET %s (%d.%d.%jx) to flags %x off %x per %x", IS_CURRENT_SETTINGS(cts)? "ACTIVE" : "NVRAM", 3900 bus, tgt, (uintmax_t)cts->ccb_h.target_lun, dval, oval, pval); 3901 } 3902 ccb->ccb_h.status = CAM_REQ_CMP; 3903 xpt_done(ccb); 3904 break; 3905 3906 case XPT_CALC_GEOMETRY: 3907 cam_calc_geometry(&ccb->ccg, 1); 3908 xpt_done(ccb); 3909 break; 3910 3911 case XPT_RESET_BUS: /* Reset the specified bus */ 3912 bus = cam_sim_bus(sim); 3913 error = isp_control(isp, ISPCTL_RESET_BUS, bus); 3914 if (error) { 3915 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 3916 xpt_done(ccb); 3917 break; 3918 } 3919 if (bootverbose) { 3920 xpt_print(ccb->ccb_h.path, "reset bus on channel %d\n", bus); 3921 } 3922 if (IS_FC(isp)) { 3923 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, 0); 3924 } else { 3925 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, 0); 3926 } 3927 ccb->ccb_h.status = CAM_REQ_CMP; 3928 xpt_done(ccb); 3929 break; 3930 3931 case XPT_TERM_IO: /* Terminate the I/O process */ 3932 ccb->ccb_h.status = CAM_REQ_INVALID; 3933 xpt_done(ccb); 3934 break; 3935 3936 case XPT_SET_SIM_KNOB: /* Set SIM knobs */ 3937 { 3938 struct ccb_sim_knob *kp = &ccb->knob; 3939 fcparam *fcp; 3940 3941 if (!IS_FC(isp)) { 3942 ccb->ccb_h.status = CAM_REQ_INVALID; 3943 xpt_done(ccb); 3944 break; 3945 } 3946 3947 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path)); 3948 fcp = FCPARAM(isp, bus); 3949 3950 if (kp->xport_specific.fc.valid & KNOB_VALID_ADDRESS) { 3951 fcp->isp_wwnn = ISP_FC_PC(isp, bus)->def_wwnn = kp->xport_specific.fc.wwnn; 3952 fcp->isp_wwpn = ISP_FC_PC(isp, bus)->def_wwpn = kp->xport_specific.fc.wwpn; 3953 isp_prt(isp, ISP_LOGALL, "Setting Channel %d wwns to 0x%jx 0x%jx", bus, fcp->isp_wwnn, fcp->isp_wwpn); 3954 } 3955 ccb->ccb_h.status = CAM_REQ_CMP; 3956 if (kp->xport_specific.fc.valid & KNOB_VALID_ROLE) { 3957 int rchange = 0; 3958 int newrole = 0; 3959 3960 switch (kp->xport_specific.fc.role) { 3961 case KNOB_ROLE_NONE: 3962 if (fcp->role != ISP_ROLE_NONE) { 3963 rchange = 1; 3964 newrole = ISP_ROLE_NONE; 3965 } 3966 break; 3967 case KNOB_ROLE_TARGET: 3968 if (fcp->role != ISP_ROLE_TARGET) { 3969 rchange = 1; 3970 newrole = ISP_ROLE_TARGET; 3971 } 3972 break; 3973 case KNOB_ROLE_INITIATOR: 3974 if (fcp->role != ISP_ROLE_INITIATOR) { 3975 rchange = 1; 3976 newrole = ISP_ROLE_INITIATOR; 3977 } 3978 break; 3979 case KNOB_ROLE_BOTH: 3980 if (fcp->role != ISP_ROLE_BOTH) { 3981 rchange = 1; 3982 newrole = ISP_ROLE_BOTH; 3983 } 3984 break; 3985 } 3986 if (rchange) { 3987 ISP_PATH_PRT(isp, ISP_LOGCONFIG, ccb->ccb_h.path, "changing role on from %d to %d\n", fcp->role, newrole); 3988 if (isp_control(isp, ISPCTL_CHANGE_ROLE, 3989 bus, newrole) != 0) { 3990 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 3991 xpt_done(ccb); 3992 break; 3993 } 3994 } 3995 } 3996 xpt_done(ccb); 3997 break; 3998 } 3999 case XPT_GET_SIM_KNOB: /* Get SIM knobs */ 4000 { 4001 struct ccb_sim_knob *kp = &ccb->knob; 4002 4003 if (IS_FC(isp)) { 4004 fcparam *fcp; 4005 4006 bus = cam_sim_bus(xpt_path_sim(kp->ccb_h.path)); 4007 fcp = FCPARAM(isp, bus); 4008 4009 kp->xport_specific.fc.wwnn = fcp->isp_wwnn; 4010 kp->xport_specific.fc.wwpn = fcp->isp_wwpn; 4011 switch (fcp->role) { 4012 case ISP_ROLE_NONE: 4013 kp->xport_specific.fc.role = KNOB_ROLE_NONE; 4014 break; 4015 case ISP_ROLE_TARGET: 4016 kp->xport_specific.fc.role = KNOB_ROLE_TARGET; 4017 break; 4018 case ISP_ROLE_INITIATOR: 4019 kp->xport_specific.fc.role = KNOB_ROLE_INITIATOR; 4020 break; 4021 case ISP_ROLE_BOTH: 4022 kp->xport_specific.fc.role = KNOB_ROLE_BOTH; 4023 break; 4024 } 4025 kp->xport_specific.fc.valid = KNOB_VALID_ADDRESS | KNOB_VALID_ROLE; 4026 ccb->ccb_h.status = CAM_REQ_CMP; 4027 } else { 4028 ccb->ccb_h.status = CAM_REQ_INVALID; 4029 } 4030 xpt_done(ccb); 4031 break; 4032 } 4033 case XPT_PATH_INQ: /* Path routing inquiry */ 4034 { 4035 struct ccb_pathinq *cpi = &ccb->cpi; 4036 4037 cpi->version_num = 1; 4038 #ifdef ISP_TARGET_MODE 4039 if (IS_FC(isp) && ISP_CAP_TMODE(isp) && ISP_CAP_SCCFW(isp)) 4040 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 4041 else 4042 #endif 4043 cpi->target_sprt = 0; 4044 cpi->hba_eng_cnt = 0; 4045 cpi->max_target = ISP_MAX_TARGETS(isp) - 1; 4046 cpi->max_lun = ISP_MAX_LUNS(isp) == 0 ? 4047 255 : ISP_MAX_LUNS(isp) - 1; 4048 cpi->bus_id = cam_sim_bus(sim); 4049 if (isp->isp_osinfo.sixtyfourbit) 4050 cpi->maxio = (ISP_NSEG64_MAX - 1) * PAGE_SIZE; 4051 else 4052 cpi->maxio = (ISP_NSEG_MAX - 1) * PAGE_SIZE; 4053 4054 bus = cam_sim_bus(xpt_path_sim(cpi->ccb_h.path)); 4055 if (IS_FC(isp)) { 4056 fcparam *fcp = FCPARAM(isp, bus); 4057 4058 cpi->hba_misc = PIM_NOBUSRESET | PIM_UNMAPPED; 4059 #if __FreeBSD_version >= 1000700 4060 cpi->hba_misc |= PIM_EXTLUNS; 4061 #endif 4062 #if __FreeBSD_version >= 1000039 4063 cpi->hba_misc |= PIM_NOSCAN; 4064 #endif 4065 4066 /* 4067 * Because our loop ID can shift from time to time, 4068 * make our initiator ID out of range of our bus. 4069 */ 4070 cpi->initiator_id = cpi->max_target + 1; 4071 4072 /* 4073 * Set base transfer capabilities for Fibre Channel, for this HBA. 4074 */ 4075 if (IS_25XX(isp)) { 4076 cpi->base_transfer_speed = 8000000; 4077 } else if (IS_24XX(isp)) { 4078 cpi->base_transfer_speed = 4000000; 4079 } else if (IS_23XX(isp)) { 4080 cpi->base_transfer_speed = 2000000; 4081 } else { 4082 cpi->base_transfer_speed = 1000000; 4083 } 4084 cpi->hba_inquiry = PI_TAG_ABLE; 4085 cpi->transport = XPORT_FC; 4086 cpi->transport_version = 0; 4087 cpi->xport_specific.fc.wwnn = fcp->isp_wwnn; 4088 cpi->xport_specific.fc.wwpn = fcp->isp_wwpn; 4089 cpi->xport_specific.fc.port = fcp->isp_portid; 4090 cpi->xport_specific.fc.bitrate = fcp->isp_gbspeed * 1000; 4091 } else { 4092 sdparam *sdp = SDPARAM(isp, bus); 4093 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 4094 cpi->hba_misc = PIM_UNMAPPED; 4095 cpi->initiator_id = sdp->isp_initiator_id; 4096 cpi->base_transfer_speed = 3300; 4097 cpi->transport = XPORT_SPI; 4098 cpi->transport_version = 2; 4099 } 4100 cpi->protocol = PROTO_SCSI; 4101 cpi->protocol_version = SCSI_REV_2; 4102 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 4103 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 4104 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 4105 cpi->unit_number = cam_sim_unit(sim); 4106 cpi->ccb_h.status = CAM_REQ_CMP; 4107 xpt_done(ccb); 4108 break; 4109 } 4110 default: 4111 ccb->ccb_h.status = CAM_REQ_INVALID; 4112 xpt_done(ccb); 4113 break; 4114 } 4115 } 4116 4117 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 4118 4119 void 4120 isp_done(XS_T *sccb) 4121 { 4122 ispsoftc_t *isp = XS_ISP(sccb); 4123 uint32_t status; 4124 4125 if (XS_NOERR(sccb)) 4126 XS_SETERR(sccb, CAM_REQ_CMP); 4127 4128 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (sccb->scsi_status != SCSI_STATUS_OK)) { 4129 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 4130 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) { 4131 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; 4132 } else { 4133 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 4134 } 4135 } 4136 4137 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 4138 status = sccb->ccb_h.status & CAM_STATUS_MASK; 4139 if (status != CAM_REQ_CMP) { 4140 if (status != CAM_SEL_TIMEOUT) 4141 isp_prt(isp, ISP_LOGDEBUG0, 4142 "target %d lun %jx CAM status 0x%x SCSI status 0x%x", 4143 XS_TGT(sccb), (uintmax_t)XS_LUN(sccb), 4144 sccb->ccb_h.status, sccb->scsi_status); 4145 else if ((IS_FC(isp)) 4146 && (XS_TGT(sccb) < MAX_FC_TARG)) { 4147 fcparam *fcp; 4148 4149 fcp = FCPARAM(isp, XS_CHANNEL(sccb)); 4150 fcp->portdb[XS_TGT(sccb)].is_target = 0; 4151 } 4152 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 4153 sccb->ccb_h.status |= CAM_DEV_QFRZN; 4154 xpt_freeze_devq(sccb->ccb_h.path, 1); 4155 } 4156 } 4157 4158 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4159 xpt_print(sccb->ccb_h.path, "cam completion status 0x%x\n", sccb->ccb_h.status); 4160 } 4161 4162 if (ISP_PCMD(sccb)) { 4163 if (callout_active(&PISP_PCMD(sccb)->wdog)) 4164 callout_stop(&PISP_PCMD(sccb)->wdog); 4165 isp_free_pcmd(isp, (union ccb *) sccb); 4166 } 4167 xpt_done((union ccb *) sccb); 4168 } 4169 4170 void 4171 isp_async(ispsoftc_t *isp, ispasync_t cmd, ...) 4172 { 4173 int bus; 4174 static const char prom[] = "Chan %d [%d] WWPN 0x%16jx PortID 0x%06x handle 0x%x %s %s"; 4175 char buf[64]; 4176 char *msg = NULL; 4177 target_id_t tgt; 4178 fcportdb_t *lp; 4179 struct isp_fc *fc; 4180 struct cam_path *tmppath; 4181 struct ac_contract ac; 4182 struct ac_device_changed *adc; 4183 va_list ap; 4184 4185 switch (cmd) { 4186 case ISPASYNC_NEW_TGT_PARAMS: 4187 { 4188 struct ccb_trans_settings_scsi *scsi; 4189 struct ccb_trans_settings_spi *spi; 4190 int flags, tgt; 4191 sdparam *sdp; 4192 struct ccb_trans_settings cts; 4193 4194 memset(&cts, 0, sizeof (struct ccb_trans_settings)); 4195 4196 va_start(ap, cmd); 4197 bus = va_arg(ap, int); 4198 tgt = va_arg(ap, int); 4199 va_end(ap); 4200 sdp = SDPARAM(isp, bus); 4201 4202 if (xpt_create_path(&tmppath, NULL, cam_sim_path(ISP_SPI_PC(isp, bus)->sim), tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 4203 isp_prt(isp, ISP_LOGWARN, "isp_async cannot make temp path for %d.%d", tgt, bus); 4204 break; 4205 } 4206 flags = sdp->isp_devparam[tgt].actv_flags; 4207 cts.type = CTS_TYPE_CURRENT_SETTINGS; 4208 cts.protocol = PROTO_SCSI; 4209 cts.transport = XPORT_SPI; 4210 4211 scsi = &cts.proto_specific.scsi; 4212 spi = &cts.xport_specific.spi; 4213 4214 if (flags & DPARM_TQING) { 4215 scsi->valid |= CTS_SCSI_VALID_TQ; 4216 scsi->flags |= CTS_SCSI_FLAGS_TAG_ENB; 4217 } 4218 4219 if (flags & DPARM_DISC) { 4220 spi->valid |= CTS_SPI_VALID_DISC; 4221 spi->flags |= CTS_SPI_FLAGS_DISC_ENB; 4222 } 4223 spi->flags |= CTS_SPI_VALID_BUS_WIDTH; 4224 if (flags & DPARM_WIDE) { 4225 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 4226 } else { 4227 spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 4228 } 4229 if (flags & DPARM_SYNC) { 4230 spi->valid |= CTS_SPI_VALID_SYNC_RATE; 4231 spi->valid |= CTS_SPI_VALID_SYNC_OFFSET; 4232 spi->sync_period = sdp->isp_devparam[tgt].actv_period; 4233 spi->sync_offset = sdp->isp_devparam[tgt].actv_offset; 4234 } 4235 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); 4236 xpt_setup_ccb(&cts.ccb_h, tmppath, 1); 4237 xpt_async(AC_TRANSFER_NEG, tmppath, &cts); 4238 xpt_free_path(tmppath); 4239 break; 4240 } 4241 case ISPASYNC_BUS_RESET: 4242 { 4243 va_start(ap, cmd); 4244 bus = va_arg(ap, int); 4245 va_end(ap); 4246 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", bus); 4247 if (IS_FC(isp)) { 4248 xpt_async(AC_BUS_RESET, ISP_FC_PC(isp, bus)->path, NULL); 4249 } else { 4250 xpt_async(AC_BUS_RESET, ISP_SPI_PC(isp, bus)->path, NULL); 4251 } 4252 break; 4253 } 4254 case ISPASYNC_LIP: 4255 if (msg == NULL) 4256 msg = "LIP Received"; 4257 /* FALLTHROUGH */ 4258 case ISPASYNC_LOOP_RESET: 4259 if (msg == NULL) 4260 msg = "LOOP Reset"; 4261 /* FALLTHROUGH */ 4262 case ISPASYNC_LOOP_DOWN: 4263 { 4264 if (msg == NULL) 4265 msg = "LOOP Down"; 4266 va_start(ap, cmd); 4267 bus = va_arg(ap, int); 4268 va_end(ap); 4269 4270 FCPARAM(isp, bus)->isp_linkstate = 0; 4271 4272 fc = ISP_FC_PC(isp, bus); 4273 if (cmd == ISPASYNC_LOOP_DOWN && fc->ready) { 4274 /* 4275 * We don't do any simq freezing if we are only in target mode 4276 */ 4277 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) { 4278 if (fc->path) { 4279 isp_freeze_loopdown(isp, bus, msg); 4280 } 4281 } 4282 if (!callout_active(&fc->ldt)) { 4283 callout_reset(&fc->ldt, fc->loop_down_limit * hz, isp_ldt, fc); 4284 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Starting Loop Down Timer @ %lu", (unsigned long) time_uptime); 4285 } 4286 } 4287 isp_fcp_reset_crn(isp, bus, /*tgt*/0, /*tgt_set*/ 0); 4288 4289 isp_prt(isp, ISP_LOGINFO, "Chan %d: %s", bus, msg); 4290 break; 4291 } 4292 case ISPASYNC_LOOP_UP: 4293 va_start(ap, cmd); 4294 bus = va_arg(ap, int); 4295 va_end(ap); 4296 fc = ISP_FC_PC(isp, bus); 4297 /* 4298 * Now we just note that Loop has come up. We don't 4299 * actually do anything because we're waiting for a 4300 * Change Notify before activating the FC cleanup 4301 * thread to look at the state of the loop again. 4302 */ 4303 FCPARAM(isp, bus)->isp_linkstate = 1; 4304 fc->loop_dead = 0; 4305 fc->loop_down_time = 0; 4306 isp_prt(isp, ISP_LOGINFO, "Chan %d Loop UP", bus); 4307 break; 4308 case ISPASYNC_DEV_ARRIVED: 4309 va_start(ap, cmd); 4310 bus = va_arg(ap, int); 4311 lp = va_arg(ap, fcportdb_t *); 4312 va_end(ap); 4313 fc = ISP_FC_PC(isp, bus); 4314 tgt = FC_PORTDB_TGT(isp, bus, lp); 4315 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 4316 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "arrived"); 4317 if ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && 4318 (lp->prli_word3 & PRLI_WD3_TARGET_FUNCTION)) { 4319 lp->is_target = 1; 4320 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1); 4321 isp_make_here(isp, lp, bus, tgt); 4322 } 4323 if ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) && 4324 (lp->prli_word3 & PRLI_WD3_INITIATOR_FUNCTION)) { 4325 lp->is_initiator = 1; 4326 ac.contract_number = AC_CONTRACT_DEV_CHG; 4327 adc = (struct ac_device_changed *) ac.contract_data; 4328 adc->wwpn = lp->port_wwn; 4329 adc->port = lp->portid; 4330 adc->target = tgt; 4331 adc->arrived = 1; 4332 xpt_async(AC_CONTRACT, fc->path, &ac); 4333 } 4334 break; 4335 case ISPASYNC_DEV_CHANGED: 4336 va_start(ap, cmd); 4337 bus = va_arg(ap, int); 4338 lp = va_arg(ap, fcportdb_t *); 4339 va_end(ap); 4340 fc = ISP_FC_PC(isp, bus); 4341 tgt = FC_PORTDB_TGT(isp, bus, lp); 4342 isp_gen_role_str(buf, sizeof (buf), lp->new_prli_word3); 4343 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->new_portid, lp->handle, buf, "changed"); 4344 changed: 4345 if (lp->is_target != 4346 ((FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) && 4347 (lp->new_prli_word3 & PRLI_WD3_TARGET_FUNCTION))) { 4348 lp->is_target = !lp->is_target; 4349 if (lp->is_target) { 4350 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1); 4351 isp_make_here(isp, lp, bus, tgt); 4352 } else { 4353 isp_make_gone(isp, lp, bus, tgt); 4354 isp_fcp_reset_crn(isp, bus, tgt, /*tgt_set*/ 1); 4355 } 4356 } 4357 if (lp->is_initiator != 4358 ((FCPARAM(isp, bus)->role & ISP_ROLE_TARGET) && 4359 (lp->new_prli_word3 & PRLI_WD3_INITIATOR_FUNCTION))) { 4360 lp->is_initiator = !lp->is_initiator; 4361 ac.contract_number = AC_CONTRACT_DEV_CHG; 4362 adc = (struct ac_device_changed *) ac.contract_data; 4363 adc->wwpn = lp->port_wwn; 4364 adc->port = lp->portid; 4365 adc->target = tgt; 4366 adc->arrived = lp->is_initiator; 4367 xpt_async(AC_CONTRACT, fc->path, &ac); 4368 } 4369 break; 4370 case ISPASYNC_DEV_STAYED: 4371 va_start(ap, cmd); 4372 bus = va_arg(ap, int); 4373 lp = va_arg(ap, fcportdb_t *); 4374 va_end(ap); 4375 fc = ISP_FC_PC(isp, bus); 4376 tgt = FC_PORTDB_TGT(isp, bus, lp); 4377 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 4378 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "stayed"); 4379 goto changed; 4380 case ISPASYNC_DEV_GONE: 4381 va_start(ap, cmd); 4382 bus = va_arg(ap, int); 4383 lp = va_arg(ap, fcportdb_t *); 4384 va_end(ap); 4385 fc = ISP_FC_PC(isp, bus); 4386 tgt = FC_PORTDB_TGT(isp, bus, lp); 4387 /* 4388 * If this has a virtual target or initiator set the isp_gdt 4389 * timer running on it to delay its departure. 4390 */ 4391 isp_gen_role_str(buf, sizeof (buf), lp->prli_word3); 4392 if (lp->is_target || lp->is_initiator) { 4393 lp->state = FC_PORTDB_STATE_ZOMBIE; 4394 lp->gone_timer = fc->gone_device_time; 4395 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone zombie"); 4396 if (fc->ready && !callout_active(&fc->gdt)) { 4397 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); 4398 callout_reset(&fc->gdt, hz, isp_gdt, fc); 4399 } 4400 break; 4401 } 4402 isp_prt(isp, ISP_LOGCONFIG, prom, bus, tgt, lp->port_wwn, lp->portid, lp->handle, buf, "gone"); 4403 break; 4404 case ISPASYNC_CHANGE_NOTIFY: 4405 { 4406 char *msg; 4407 int evt, nphdl, nlstate, portid, reason; 4408 4409 va_start(ap, cmd); 4410 bus = va_arg(ap, int); 4411 evt = va_arg(ap, int); 4412 if (evt == ISPASYNC_CHANGE_PDB) { 4413 nphdl = va_arg(ap, int); 4414 nlstate = va_arg(ap, int); 4415 reason = va_arg(ap, int); 4416 } else if (evt == ISPASYNC_CHANGE_SNS) { 4417 portid = va_arg(ap, int); 4418 } else { 4419 nphdl = NIL_HANDLE; 4420 nlstate = reason = 0; 4421 } 4422 va_end(ap); 4423 fc = ISP_FC_PC(isp, bus); 4424 4425 if (evt == ISPASYNC_CHANGE_PDB) { 4426 msg = "Port Database Changed"; 4427 isp_prt(isp, ISP_LOGINFO, 4428 "Chan %d %s (nphdl 0x%x state 0x%x reason 0x%x)", 4429 bus, msg, nphdl, nlstate, reason); 4430 } else if (evt == ISPASYNC_CHANGE_SNS) { 4431 msg = "Name Server Database Changed"; 4432 isp_prt(isp, ISP_LOGINFO, "Chan %d %s (PortID 0x%06x)", 4433 bus, msg, portid); 4434 } else { 4435 msg = "Other Change Notify"; 4436 isp_prt(isp, ISP_LOGINFO, "Chan %d %s", bus, msg); 4437 } 4438 4439 /* 4440 * If the loop down timer is running, cancel it. 4441 */ 4442 if (fc->ready && callout_active(&fc->ldt)) { 4443 isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGDEBUG0, "Stopping Loop Down Timer @ %lu", (unsigned long) time_uptime); 4444 callout_stop(&fc->ldt); 4445 } 4446 if (FCPARAM(isp, bus)->role & ISP_ROLE_INITIATOR) { 4447 isp_freeze_loopdown(isp, bus, msg); 4448 } 4449 wakeup(fc); 4450 break; 4451 } 4452 #ifdef ISP_TARGET_MODE 4453 case ISPASYNC_TARGET_NOTIFY: 4454 { 4455 isp_notify_t *notify; 4456 va_start(ap, cmd); 4457 notify = va_arg(ap, isp_notify_t *); 4458 va_end(ap); 4459 switch (notify->nt_ncode) { 4460 case NT_ABORT_TASK: 4461 case NT_ABORT_TASK_SET: 4462 case NT_CLEAR_ACA: 4463 case NT_CLEAR_TASK_SET: 4464 case NT_LUN_RESET: 4465 case NT_TARGET_RESET: 4466 case NT_QUERY_TASK_SET: 4467 case NT_QUERY_ASYNC_EVENT: 4468 /* 4469 * These are task management functions. 4470 */ 4471 isp_handle_platform_target_tmf(isp, notify); 4472 break; 4473 case NT_BUS_RESET: 4474 case NT_LIP_RESET: 4475 case NT_LINK_UP: 4476 case NT_LINK_DOWN: 4477 case NT_HBA_RESET: 4478 /* 4479 * No action need be taken here. 4480 */ 4481 break; 4482 case NT_GLOBAL_LOGOUT: 4483 case NT_LOGOUT: 4484 /* 4485 * This is device arrival/departure notification 4486 */ 4487 isp_handle_platform_target_notify_ack(isp, notify); 4488 break; 4489 default: 4490 isp_prt(isp, ISP_LOGALL, "target notify code 0x%x", notify->nt_ncode); 4491 isp_handle_platform_target_notify_ack(isp, notify); 4492 break; 4493 } 4494 break; 4495 } 4496 case ISPASYNC_TARGET_NOTIFY_ACK: 4497 { 4498 void *inot; 4499 va_start(ap, cmd); 4500 inot = va_arg(ap, void *); 4501 va_end(ap); 4502 if (isp_notify_ack(isp, inot)) { 4503 isp_tna_t *tp = malloc(sizeof (*tp), M_DEVBUF, M_NOWAIT); 4504 if (tp) { 4505 tp->isp = isp; 4506 if (inot) { 4507 memcpy(tp->data, inot, sizeof (tp->data)); 4508 tp->not = tp->data; 4509 } else { 4510 tp->not = NULL; 4511 } 4512 callout_init_mtx(&tp->timer, &isp->isp_lock, 0); 4513 callout_reset(&tp->timer, 5, 4514 isp_refire_notify_ack, tp); 4515 } else { 4516 isp_prt(isp, ISP_LOGERR, "you lose- cannot allocate a notify refire"); 4517 } 4518 } 4519 break; 4520 } 4521 case ISPASYNC_TARGET_ACTION: 4522 { 4523 isphdr_t *hp; 4524 4525 va_start(ap, cmd); 4526 hp = va_arg(ap, isphdr_t *); 4527 va_end(ap); 4528 switch (hp->rqs_entry_type) { 4529 default: 4530 isp_prt(isp, ISP_LOGWARN, "%s: unhandled target action 0x%x", __func__, hp->rqs_entry_type); 4531 break; 4532 case RQSTYPE_NOTIFY: 4533 if (IS_24XX(isp)) { 4534 isp_handle_platform_notify_24xx(isp, (in_fcentry_24xx_t *) hp); 4535 } else { 4536 isp_handle_platform_notify_fc(isp, (in_fcentry_t *) hp); 4537 } 4538 break; 4539 case RQSTYPE_ATIO: 4540 isp_handle_platform_atio7(isp, (at7_entry_t *) hp); 4541 break; 4542 case RQSTYPE_ATIO2: 4543 isp_handle_platform_atio2(isp, (at2_entry_t *) hp); 4544 break; 4545 case RQSTYPE_CTIO7: 4546 case RQSTYPE_CTIO3: 4547 case RQSTYPE_CTIO2: 4548 case RQSTYPE_CTIO: 4549 isp_handle_platform_ctio(isp, hp); 4550 break; 4551 case RQSTYPE_ABTS_RCVD: 4552 { 4553 abts_t *abts = (abts_t *)hp; 4554 isp_notify_t notify, *nt = ¬ify; 4555 tstate_t *tptr; 4556 fcportdb_t *lp; 4557 uint16_t chan; 4558 uint32_t sid, did; 4559 4560 did = (abts->abts_did_hi << 16) | abts->abts_did_lo; 4561 sid = (abts->abts_sid_hi << 16) | abts->abts_sid_lo; 4562 ISP_MEMZERO(nt, sizeof (isp_notify_t)); 4563 4564 nt->nt_hba = isp; 4565 nt->nt_did = did; 4566 nt->nt_nphdl = abts->abts_nphdl; 4567 nt->nt_sid = sid; 4568 isp_find_chan_by_did(isp, did, &chan); 4569 if (chan == ISP_NOCHAN) { 4570 nt->nt_tgt = TGT_ANY; 4571 } else { 4572 nt->nt_tgt = FCPARAM(isp, chan)->isp_wwpn; 4573 if (isp_find_pdb_by_handle(isp, chan, abts->abts_nphdl, &lp)) { 4574 nt->nt_wwn = lp->port_wwn; 4575 } else { 4576 nt->nt_wwn = INI_ANY; 4577 } 4578 } 4579 /* 4580 * Try hard to find the lun for this command. 4581 */ 4582 tptr = get_lun_statep_from_tag(isp, chan, abts->abts_rxid_task); 4583 if (tptr) { 4584 nt->nt_lun = tptr->ts_lun; 4585 rls_lun_statep(isp, tptr); 4586 } else { 4587 nt->nt_lun = LUN_ANY; 4588 } 4589 nt->nt_need_ack = 1; 4590 nt->nt_tagval = abts->abts_rxid_task; 4591 nt->nt_tagval |= (((uint64_t) abts->abts_rxid_abts) << 32); 4592 if (abts->abts_rxid_task == ISP24XX_NO_TASK) { 4593 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)", 4594 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rx_id, abts->abts_ox_id); 4595 } else { 4596 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)", 4597 abts->abts_rxid_abts, abts->abts_nphdl, sid, abts->abts_rxid_task, abts->abts_rx_id, abts->abts_ox_id); 4598 } 4599 nt->nt_channel = chan; 4600 nt->nt_ncode = NT_ABORT_TASK; 4601 nt->nt_lreserved = hp; 4602 isp_handle_platform_target_tmf(isp, nt); 4603 break; 4604 } 4605 } 4606 break; 4607 } 4608 #endif 4609 case ISPASYNC_FW_CRASH: 4610 { 4611 uint16_t mbox1, mbox6; 4612 mbox1 = ISP_READ(isp, OUTMAILBOX1); 4613 if (IS_DUALBUS(isp)) { 4614 mbox6 = ISP_READ(isp, OUTMAILBOX6); 4615 } else { 4616 mbox6 = 0; 4617 } 4618 isp_prt(isp, ISP_LOGERR, "Internal Firmware Error on bus %d @ RISC Address 0x%x", mbox6, mbox1); 4619 mbox1 = isp->isp_osinfo.mbox_sleep_ok; 4620 isp->isp_osinfo.mbox_sleep_ok = 0; 4621 isp_reinit(isp, 1); 4622 isp->isp_osinfo.mbox_sleep_ok = mbox1; 4623 isp_async(isp, ISPASYNC_FW_RESTARTED, NULL); 4624 break; 4625 } 4626 default: 4627 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd); 4628 break; 4629 } 4630 } 4631 4632 4633 /* 4634 * Locks are held before coming here. 4635 */ 4636 void 4637 isp_uninit(ispsoftc_t *isp) 4638 { 4639 if (IS_24XX(isp)) { 4640 ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET); 4641 } else { 4642 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 4643 } 4644 ISP_DISABLE_INTS(isp); 4645 } 4646 4647 /* 4648 * When we want to get the 'default' WWNs (when lacking NVRAM), we pick them 4649 * up from our platform default (defww{p|n}n) and morph them based upon 4650 * channel. 4651 * 4652 * When we want to get the 'active' WWNs, we get NVRAM WWNs and then morph them 4653 * based upon channel. 4654 */ 4655 4656 uint64_t 4657 isp_default_wwn(ispsoftc_t * isp, int chan, int isactive, int iswwnn) 4658 { 4659 uint64_t seed; 4660 struct isp_fc *fc = ISP_FC_PC(isp, chan); 4661 4662 /* 4663 * If we're asking for a active WWN, the default overrides get 4664 * returned, otherwise the NVRAM value is picked. 4665 * 4666 * If we're asking for a default WWN, we just pick the default override. 4667 */ 4668 if (isactive) { 4669 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn; 4670 if (seed) { 4671 return (seed); 4672 } 4673 seed = iswwnn ? FCPARAM(isp, chan)->isp_wwnn_nvram : FCPARAM(isp, chan)->isp_wwpn_nvram; 4674 if (seed) { 4675 return (seed); 4676 } 4677 return (0x400000007F000009ull); 4678 } 4679 4680 seed = iswwnn ? fc->def_wwnn : fc->def_wwpn; 4681 4682 /* 4683 * For channel zero just return what we have. For either ACTIVE or 4684 * DEFAULT cases, we depend on default override of NVRAM values for 4685 * channel zero. 4686 */ 4687 if (chan == 0) { 4688 return (seed); 4689 } 4690 4691 /* 4692 * For other channels, we are doing one of three things: 4693 * 4694 * 1. If what we have now is non-zero, return it. Otherwise we morph 4695 * values from channel 0. 2. If we're here for a WWPN we synthesize 4696 * it if Channel 0's wwpn has a type 2 NAA. 3. If we're here for a 4697 * WWNN we synthesize it if Channel 0's wwnn has a type 2 NAA. 4698 */ 4699 4700 if (seed) { 4701 return (seed); 4702 } 4703 seed = iswwnn ? ISP_FC_PC(isp, 0)->def_wwnn : ISP_FC_PC(isp, 0)->def_wwpn; 4704 if (seed == 0) 4705 seed = iswwnn ? FCPARAM(isp, 0)->isp_wwnn_nvram : FCPARAM(isp, 0)->isp_wwpn_nvram; 4706 4707 if (((seed >> 60) & 0xf) == 2) { 4708 /* 4709 * The type 2 NAA fields for QLogic cards appear be laid out 4710 * thusly: 4711 * 4712 * bits 63..60 NAA == 2 bits 59..57 unused/zero bit 56 4713 * port (1) or node (0) WWN distinguishor bit 48 4714 * physical port on dual-port chips (23XX/24XX) 4715 * 4716 * This is somewhat nutty, particularly since bit 48 is 4717 * irrelevant as they assign separate serial numbers to 4718 * different physical ports anyway. 4719 * 4720 * We'll stick our channel number plus one first into bits 4721 * 57..59 and thence into bits 52..55 which allows for 8 bits 4722 * of channel which is comfortably more than our maximum 4723 * (126) now. 4724 */ 4725 seed &= ~0x0FF0000000000000ULL; 4726 if (iswwnn == 0) { 4727 seed |= ((uint64_t) (chan + 1) & 0xf) << 56; 4728 seed |= ((uint64_t) ((chan + 1) >> 4) & 0xf) << 52; 4729 } 4730 } else { 4731 seed = 0; 4732 } 4733 return (seed); 4734 } 4735 4736 void 4737 isp_prt(ispsoftc_t *isp, int level, const char *fmt, ...) 4738 { 4739 int loc; 4740 char lbuf[200]; 4741 va_list ap; 4742 4743 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 4744 return; 4745 } 4746 snprintf(lbuf, sizeof (lbuf), "%s: ", device_get_nameunit(isp->isp_dev)); 4747 loc = strlen(lbuf); 4748 va_start(ap, fmt); 4749 vsnprintf(&lbuf[loc], sizeof (lbuf) - loc - 1, fmt, ap); 4750 va_end(ap); 4751 printf("%s\n", lbuf); 4752 } 4753 4754 void 4755 isp_xs_prt(ispsoftc_t *isp, XS_T *xs, int level, const char *fmt, ...) 4756 { 4757 va_list ap; 4758 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 4759 return; 4760 } 4761 xpt_print_path(xs->ccb_h.path); 4762 va_start(ap, fmt); 4763 vprintf(fmt, ap); 4764 va_end(ap); 4765 printf("\n"); 4766 } 4767 4768 uint64_t 4769 isp_nanotime_sub(struct timespec *b, struct timespec *a) 4770 { 4771 uint64_t elapsed; 4772 struct timespec x = *b; 4773 timespecsub(&x, a); 4774 elapsed = GET_NANOSEC(&x); 4775 if (elapsed == 0) 4776 elapsed++; 4777 return (elapsed); 4778 } 4779 4780 int 4781 isp_mbox_acquire(ispsoftc_t *isp) 4782 { 4783 if (isp->isp_osinfo.mboxbsy) { 4784 return (1); 4785 } else { 4786 isp->isp_osinfo.mboxcmd_done = 0; 4787 isp->isp_osinfo.mboxbsy = 1; 4788 return (0); 4789 } 4790 } 4791 4792 void 4793 isp_mbox_wait_complete(ispsoftc_t *isp, mbreg_t *mbp) 4794 { 4795 unsigned int usecs = mbp->timeout; 4796 unsigned int max, olim, ilim; 4797 4798 if (usecs == 0) { 4799 usecs = MBCMD_DEFAULT_TIMEOUT; 4800 } 4801 max = isp->isp_mbxwrk0 + 1; 4802 4803 if (isp->isp_osinfo.mbox_sleep_ok) { 4804 unsigned int ms = (usecs + 999) / 1000; 4805 4806 isp->isp_osinfo.mbox_sleep_ok = 0; 4807 isp->isp_osinfo.mbox_sleeping = 1; 4808 for (olim = 0; olim < max; olim++) { 4809 msleep(&isp->isp_mbxworkp, &isp->isp_osinfo.lock, PRIBIO, "ispmbx_sleep", isp_mstohz(ms)); 4810 if (isp->isp_osinfo.mboxcmd_done) { 4811 break; 4812 } 4813 } 4814 isp->isp_osinfo.mbox_sleep_ok = 1; 4815 isp->isp_osinfo.mbox_sleeping = 0; 4816 } else { 4817 for (olim = 0; olim < max; olim++) { 4818 for (ilim = 0; ilim < usecs; ilim += 100) { 4819 uint16_t isr, sema, info; 4820 if (isp->isp_osinfo.mboxcmd_done) { 4821 break; 4822 } 4823 if (ISP_READ_ISR(isp, &isr, &sema, &info)) { 4824 isp_intr(isp, isr, sema, info); 4825 if (isp->isp_osinfo.mboxcmd_done) { 4826 break; 4827 } 4828 } 4829 ISP_DELAY(100); 4830 } 4831 if (isp->isp_osinfo.mboxcmd_done) { 4832 break; 4833 } 4834 } 4835 } 4836 if (isp->isp_osinfo.mboxcmd_done == 0) { 4837 isp_prt(isp, ISP_LOGWARN, "%s Mailbox Command (0x%x) Timeout (%uus) (started @ %s:%d)", 4838 isp->isp_osinfo.mbox_sleep_ok? "Interrupting" : "Polled", isp->isp_lastmbxcmd, usecs, mbp->func, mbp->lineno); 4839 mbp->param[0] = MBOX_TIMEOUT; 4840 isp->isp_osinfo.mboxcmd_done = 1; 4841 } 4842 } 4843 4844 void 4845 isp_mbox_notify_done(ispsoftc_t *isp) 4846 { 4847 if (isp->isp_osinfo.mbox_sleeping) { 4848 wakeup(&isp->isp_mbxworkp); 4849 } 4850 isp->isp_osinfo.mboxcmd_done = 1; 4851 } 4852 4853 void 4854 isp_mbox_release(ispsoftc_t *isp) 4855 { 4856 isp->isp_osinfo.mboxbsy = 0; 4857 } 4858 4859 int 4860 isp_fc_scratch_acquire(ispsoftc_t *isp, int chan) 4861 { 4862 int ret = 0; 4863 if (isp->isp_osinfo.pc.fc[chan].fcbsy) { 4864 ret = -1; 4865 } else { 4866 isp->isp_osinfo.pc.fc[chan].fcbsy = 1; 4867 } 4868 return (ret); 4869 } 4870 4871 int 4872 isp_mstohz(int ms) 4873 { 4874 int hz; 4875 struct timeval t; 4876 t.tv_sec = ms / 1000; 4877 t.tv_usec = (ms % 1000) * 1000; 4878 hz = tvtohz(&t); 4879 if (hz < 0) { 4880 hz = 0x7fffffff; 4881 } 4882 if (hz == 0) { 4883 hz = 1; 4884 } 4885 return (hz); 4886 } 4887 4888 void 4889 isp_platform_intr(void *arg) 4890 { 4891 ispsoftc_t *isp = arg; 4892 uint16_t isr, sema, info; 4893 4894 ISP_LOCK(isp); 4895 isp->isp_intcnt++; 4896 if (ISP_READ_ISR(isp, &isr, &sema, &info)) 4897 isp_intr(isp, isr, sema, info); 4898 else 4899 isp->isp_intbogus++; 4900 ISP_UNLOCK(isp); 4901 } 4902 4903 void 4904 isp_common_dmateardown(ispsoftc_t *isp, struct ccb_scsiio *csio, uint32_t hdl) 4905 { 4906 if ((csio->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 4907 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTREAD); 4908 } else { 4909 bus_dmamap_sync(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap, BUS_DMASYNC_POSTWRITE); 4910 } 4911 bus_dmamap_unload(isp->isp_osinfo.dmat, PISP_PCMD(csio)->dmap); 4912 } 4913 4914 /* 4915 * Reset the command reference number for all LUNs on a specific target 4916 * (needed when a target arrives again) or for all targets on a port 4917 * (needed for events like a LIP). 4918 */ 4919 void 4920 isp_fcp_reset_crn(ispsoftc_t *isp, int chan, uint32_t tgt, int tgt_set) 4921 { 4922 struct isp_fc *fc = ISP_FC_PC(isp, chan); 4923 struct isp_nexus *nxp; 4924 int i; 4925 4926 if (tgt_set == 0) 4927 isp_prt(isp, ISP_LOGDEBUG0, 4928 "Chan %d resetting CRN on all targets", chan); 4929 else 4930 isp_prt(isp, ISP_LOGDEBUG0, 4931 "Chan %d resetting CRN on target %u", chan, tgt); 4932 4933 for (i = 0; i < NEXUS_HASH_WIDTH; i++) { 4934 for (nxp = fc->nexus_hash[i]; nxp != NULL; nxp = nxp->next) { 4935 if (tgt_set == 0 || tgt == nxp->tgt) 4936 nxp->crnseed = 0; 4937 } 4938 } 4939 } 4940 4941 int 4942 isp_fcp_next_crn(ispsoftc_t *isp, uint8_t *crnp, XS_T *cmd) 4943 { 4944 lun_id_t lun; 4945 uint32_t chan, tgt; 4946 struct isp_fc *fc; 4947 struct isp_nexus *nxp; 4948 int idx; 4949 4950 if (IS_2100(isp)) 4951 return (0); 4952 4953 chan = XS_CHANNEL(cmd); 4954 tgt = XS_TGT(cmd); 4955 lun = XS_LUN(cmd); 4956 fc = &isp->isp_osinfo.pc.fc[chan]; 4957 idx = NEXUS_HASH(tgt, lun); 4958 nxp = fc->nexus_hash[idx]; 4959 4960 while (nxp) { 4961 if (nxp->tgt == tgt && nxp->lun == lun) 4962 break; 4963 nxp = nxp->next; 4964 } 4965 if (nxp == NULL) { 4966 nxp = fc->nexus_free_list; 4967 if (nxp == NULL) { 4968 nxp = malloc(sizeof (struct isp_nexus), M_DEVBUF, M_ZERO|M_NOWAIT); 4969 if (nxp == NULL) { 4970 return (-1); 4971 } 4972 } else { 4973 fc->nexus_free_list = nxp->next; 4974 } 4975 nxp->tgt = tgt; 4976 nxp->lun = lun; 4977 nxp->next = fc->nexus_hash[idx]; 4978 fc->nexus_hash[idx] = nxp; 4979 } 4980 if (nxp->crnseed == 0) 4981 nxp->crnseed = 1; 4982 PISP_PCMD(cmd)->crn = nxp->crnseed; 4983 *crnp = nxp->crnseed++; 4984 return (0); 4985 } 4986 4987 /* 4988 * We enter with the lock held 4989 */ 4990 void 4991 isp_timer(void *arg) 4992 { 4993 ispsoftc_t *isp = arg; 4994 #ifdef ISP_TARGET_MODE 4995 isp_tmcmd_restart(isp); 4996 #endif 4997 callout_reset(&isp->isp_osinfo.tmo, isp_timer_count, isp_timer, isp); 4998 } 4999 5000 isp_ecmd_t * 5001 isp_get_ecmd(ispsoftc_t *isp) 5002 { 5003 isp_ecmd_t *ecmd = isp->isp_osinfo.ecmd_free; 5004 if (ecmd) { 5005 isp->isp_osinfo.ecmd_free = ecmd->next; 5006 } 5007 return (ecmd); 5008 } 5009 5010 void 5011 isp_put_ecmd(ispsoftc_t *isp, isp_ecmd_t *ecmd) 5012 { 5013 ecmd->next = isp->isp_osinfo.ecmd_free; 5014 isp->isp_osinfo.ecmd_free = ecmd; 5015 } 5016