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