1 /* $FreeBSD$ */ 2 /* 3 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. 4 * 5 * Copyright (c) 1997, 1998, 1999, 2000, 2001 by Matthew Jacob 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice immediately at the beginning of the file, without modification, 12 * this list of conditions, and the following disclaimer. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 #include <dev/isp/isp_freebsd.h> 29 #include <machine/stdarg.h> /* for use by isp_prt below */ 30 31 static void isp_intr_enable(void *); 32 static void isp_cam_async(void *, u_int32_t, struct cam_path *, void *); 33 static void isp_poll(struct cam_sim *); 34 static void isp_relsim(void *); 35 static timeout_t isp_watchdog; 36 static void isp_action(struct cam_sim *, union ccb *); 37 38 39 static struct ispsoftc *isplist = NULL; 40 41 void 42 isp_attach(struct ispsoftc *isp) 43 { 44 int primary, secondary; 45 struct ccb_setasync csa; 46 struct cam_devq *devq; 47 struct cam_sim *sim; 48 struct cam_path *path; 49 50 /* 51 * Establish (in case of 12X0) which bus is the primary. 52 */ 53 54 primary = 0; 55 secondary = 1; 56 57 /* 58 * Create the device queue for our SIM(s). 59 */ 60 devq = cam_simq_alloc(isp->isp_maxcmds); 61 if (devq == NULL) { 62 return; 63 } 64 65 /* 66 * Construct our SIM entry. 67 */ 68 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, 69 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq); 70 if (sim == NULL) { 71 cam_simq_free(devq); 72 return; 73 } 74 75 isp->isp_osinfo.ehook.ich_func = isp_intr_enable; 76 isp->isp_osinfo.ehook.ich_arg = isp; 77 if (config_intrhook_establish(&isp->isp_osinfo.ehook) != 0) { 78 isp_prt(isp, ISP_LOGERR, 79 "could not establish interrupt enable hook"); 80 cam_sim_free(sim, TRUE); 81 return; 82 } 83 84 if (xpt_bus_register(sim, primary) != CAM_SUCCESS) { 85 cam_sim_free(sim, TRUE); 86 return; 87 } 88 89 if (xpt_create_path(&path, NULL, cam_sim_path(sim), 90 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 91 xpt_bus_deregister(cam_sim_path(sim)); 92 cam_sim_free(sim, TRUE); 93 return; 94 } 95 96 xpt_setup_ccb(&csa.ccb_h, path, 5); 97 csa.ccb_h.func_code = XPT_SASYNC_CB; 98 csa.event_enable = AC_LOST_DEVICE; 99 csa.callback = isp_cam_async; 100 csa.callback_arg = sim; 101 xpt_action((union ccb *)&csa); 102 isp->isp_sim = sim; 103 isp->isp_path = path; 104 105 /* 106 * If we have a second channel, construct SIM entry for that. 107 */ 108 if (IS_DUALBUS(isp)) { 109 sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, 110 device_get_unit(isp->isp_dev), 1, isp->isp_maxcmds, devq); 111 if (sim == NULL) { 112 xpt_bus_deregister(cam_sim_path(isp->isp_sim)); 113 xpt_free_path(isp->isp_path); 114 cam_simq_free(devq); 115 return; 116 } 117 if (xpt_bus_register(sim, secondary) != CAM_SUCCESS) { 118 xpt_bus_deregister(cam_sim_path(isp->isp_sim)); 119 xpt_free_path(isp->isp_path); 120 cam_sim_free(sim, TRUE); 121 return; 122 } 123 124 if (xpt_create_path(&path, NULL, cam_sim_path(sim), 125 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 126 xpt_bus_deregister(cam_sim_path(isp->isp_sim)); 127 xpt_free_path(isp->isp_path); 128 xpt_bus_deregister(cam_sim_path(sim)); 129 cam_sim_free(sim, TRUE); 130 return; 131 } 132 133 xpt_setup_ccb(&csa.ccb_h, path, 5); 134 csa.ccb_h.func_code = XPT_SASYNC_CB; 135 csa.event_enable = AC_LOST_DEVICE; 136 csa.callback = isp_cam_async; 137 csa.callback_arg = sim; 138 xpt_action((union ccb *)&csa); 139 isp->isp_sim2 = sim; 140 isp->isp_path2 = path; 141 } 142 if (isp->isp_role != ISP_ROLE_NONE) { 143 isp->isp_state = ISP_RUNSTATE; 144 ENABLE_INTS(isp); 145 } 146 if (isplist == NULL) { 147 isplist = isp; 148 } else { 149 struct ispsoftc *tmp = isplist; 150 while (tmp->isp_osinfo.next) { 151 tmp = tmp->isp_osinfo.next; 152 } 153 tmp->isp_osinfo.next = isp; 154 } 155 } 156 157 static void 158 isp_intr_enable(void *arg) 159 { 160 struct ispsoftc *isp = arg; 161 if (isp->isp_role != ISP_ROLE_NONE) { 162 ENABLE_INTS(isp); 163 isp->isp_osinfo.intsok = 1; 164 } 165 /* Release our hook so that the boot can continue. */ 166 config_intrhook_disestablish(&isp->isp_osinfo.ehook); 167 } 168 169 /* 170 * Put the target mode functions here, because some are inlines 171 */ 172 173 #ifdef ISP_TARGET_MODE 174 175 static __inline int is_lun_enabled(struct ispsoftc *, lun_id_t); 176 static __inline int are_any_luns_enabled(struct ispsoftc *); 177 static __inline tstate_t *get_lun_statep(struct ispsoftc *, lun_id_t); 178 static __inline void rls_lun_statep(struct ispsoftc *, tstate_t *); 179 static __inline int isp_psema_sig_rqe(struct ispsoftc *); 180 static __inline int isp_cv_wait_timed_rqe(struct ispsoftc *, int); 181 static __inline void isp_cv_signal_rqe(struct ispsoftc *, int); 182 static __inline void isp_vsema_rqe(struct ispsoftc *); 183 static cam_status 184 create_lun_state(struct ispsoftc *, struct cam_path *, tstate_t **); 185 static void destroy_lun_state(struct ispsoftc *, tstate_t *); 186 static void isp_en_lun(struct ispsoftc *, union ccb *); 187 static cam_status isp_abort_tgt_ccb(struct ispsoftc *, union ccb *); 188 static cam_status isp_target_start_ctio(struct ispsoftc *, union ccb *); 189 static cam_status isp_target_putback_atio(struct ispsoftc *, union ccb *); 190 static timeout_t isp_refire_putback_atio; 191 192 static int isp_handle_platform_atio(struct ispsoftc *, at_entry_t *); 193 static int isp_handle_platform_atio2(struct ispsoftc *, at2_entry_t *); 194 static int isp_handle_platform_ctio(struct ispsoftc *, void *); 195 static void isp_handle_platform_ctio_part2(struct ispsoftc *, union ccb *); 196 197 static __inline int 198 is_lun_enabled(struct ispsoftc *isp, lun_id_t lun) 199 { 200 tstate_t *tptr; 201 ISP_LOCK(isp); 202 if ((tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)]) == NULL) { 203 ISP_UNLOCK(isp); 204 return (0); 205 } 206 do { 207 if (tptr->lun == (lun_id_t) lun) { 208 ISP_UNLOCK(isp); 209 return (1); 210 } 211 } while ((tptr = tptr->next) != NULL); 212 ISP_UNLOCK(isp); 213 return (0); 214 } 215 216 static __inline int 217 are_any_luns_enabled(struct ispsoftc *isp) 218 { 219 int i; 220 for (i = 0; i < LUN_HASH_SIZE; i++) { 221 if (isp->isp_osinfo.lun_hash[i]) { 222 return (1); 223 } 224 } 225 return (0); 226 } 227 228 static __inline tstate_t * 229 get_lun_statep(struct ispsoftc *isp, lun_id_t lun) 230 { 231 tstate_t *tptr; 232 233 ISP_LOCK(isp); 234 if (lun == CAM_LUN_WILDCARD) { 235 tptr = &isp->isp_osinfo.tsdflt; 236 tptr->hold++; 237 ISP_UNLOCK(isp); 238 return (tptr); 239 } else { 240 tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)]; 241 } 242 if (tptr == NULL) { 243 ISP_UNLOCK(isp); 244 return (NULL); 245 } 246 247 do { 248 if (tptr->lun == lun) { 249 tptr->hold++; 250 ISP_UNLOCK(isp); 251 return (tptr); 252 } 253 } while ((tptr = tptr->next) != NULL); 254 ISP_UNLOCK(isp); 255 return (tptr); 256 } 257 258 static __inline void 259 rls_lun_statep(struct ispsoftc *isp, tstate_t *tptr) 260 { 261 if (tptr->hold) 262 tptr->hold--; 263 } 264 265 static __inline int 266 isp_psema_sig_rqe(struct ispsoftc *isp) 267 { 268 ISP_LOCK(isp); 269 while (isp->isp_osinfo.tmflags & TM_BUSY) { 270 isp->isp_osinfo.tmflags |= TM_WANTED; 271 if (tsleep(&isp->isp_osinfo.tmflags, PRIBIO|PCATCH, "i0", 0)) { 272 ISP_UNLOCK(isp); 273 return (-1); 274 } 275 isp->isp_osinfo.tmflags |= TM_BUSY; 276 } 277 ISP_UNLOCK(isp); 278 return (0); 279 } 280 281 static __inline int 282 isp_cv_wait_timed_rqe(struct ispsoftc *isp, int timo) 283 { 284 ISP_LOCK(isp); 285 if (tsleep(&isp->isp_osinfo.rstatus, PRIBIO, "qt1", timo)) { 286 ISP_UNLOCK(isp); 287 return (-1); 288 } 289 ISP_UNLOCK(isp); 290 return (0); 291 } 292 293 static __inline void 294 isp_cv_signal_rqe(struct ispsoftc *isp, int status) 295 { 296 isp->isp_osinfo.rstatus = status; 297 wakeup(&isp->isp_osinfo.rstatus); 298 } 299 300 static __inline void 301 isp_vsema_rqe(struct ispsoftc *isp) 302 { 303 ISP_LOCK(isp); 304 if (isp->isp_osinfo.tmflags & TM_WANTED) { 305 isp->isp_osinfo.tmflags &= ~TM_WANTED; 306 wakeup(&isp->isp_osinfo.tmflags); 307 } 308 isp->isp_osinfo.tmflags &= ~TM_BUSY; 309 ISP_UNLOCK(isp); 310 } 311 312 static cam_status 313 create_lun_state(struct ispsoftc *isp, struct cam_path *path, tstate_t **rslt) 314 { 315 cam_status status; 316 lun_id_t lun; 317 tstate_t *tptr, *new; 318 319 lun = xpt_path_lun_id(path); 320 if (lun < 0) { 321 return (CAM_LUN_INVALID); 322 } 323 if (is_lun_enabled(isp, lun)) { 324 return (CAM_LUN_ALRDY_ENA); 325 } 326 new = (tstate_t *) malloc(sizeof (tstate_t), M_DEVBUF, M_NOWAIT|M_ZERO); 327 if (new == NULL) { 328 return (CAM_RESRC_UNAVAIL); 329 } 330 331 status = xpt_create_path(&new->owner, NULL, xpt_path_path_id(path), 332 xpt_path_target_id(path), xpt_path_lun_id(path)); 333 if (status != CAM_REQ_CMP) { 334 free(new, M_DEVBUF); 335 return (status); 336 } 337 new->lun = lun; 338 SLIST_INIT(&new->atios); 339 SLIST_INIT(&new->inots); 340 new->hold = 1; 341 342 ISP_LOCK(isp); 343 if ((tptr = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)]) == NULL) { 344 isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(lun)] = new; 345 } else { 346 while (tptr->next) 347 tptr = tptr->next; 348 tptr->next = new; 349 } 350 ISP_UNLOCK(isp); 351 *rslt = new; 352 return (CAM_REQ_CMP); 353 } 354 355 static __inline void 356 destroy_lun_state(struct ispsoftc *isp, tstate_t *tptr) 357 { 358 tstate_t *lw, *pw; 359 360 ISP_LOCK(isp); 361 if (tptr->hold) { 362 ISP_UNLOCK(isp); 363 return; 364 } 365 pw = isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(tptr->lun)]; 366 if (pw == NULL) { 367 ISP_UNLOCK(isp); 368 return; 369 } else if (pw->lun == tptr->lun) { 370 isp->isp_osinfo.lun_hash[LUN_HASH_FUNC(tptr->lun)] = pw->next; 371 } else { 372 lw = pw; 373 pw = lw->next; 374 while (pw) { 375 if (pw->lun == tptr->lun) { 376 lw->next = pw->next; 377 break; 378 } 379 lw = pw; 380 pw = pw->next; 381 } 382 if (pw == NULL) { 383 ISP_UNLOCK(isp); 384 return; 385 } 386 } 387 free(tptr, M_DEVBUF); 388 ISP_UNLOCK(isp); 389 } 390 391 static void 392 isp_en_lun(struct ispsoftc *isp, union ccb *ccb) 393 { 394 const char lfmt[] = "Lun now %sabled for target mode"; 395 struct ccb_en_lun *cel = &ccb->cel; 396 tstate_t *tptr; 397 u_int16_t rstat; 398 int bus, frozen = 0; 399 lun_id_t lun; 400 target_id_t tgt; 401 402 403 bus = XS_CHANNEL(ccb); 404 if (bus != 0) { 405 isp_prt(isp, ISP_LOGERR, 406 "second channel target mode not supported"); 407 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 408 return; 409 } 410 tgt = ccb->ccb_h.target_id; 411 lun = ccb->ccb_h.target_lun; 412 413 /* 414 * Do some sanity checking first. 415 */ 416 417 if ((lun != CAM_LUN_WILDCARD) && 418 (lun < 0 || lun >= (lun_id_t) isp->isp_maxluns)) { 419 ccb->ccb_h.status = CAM_LUN_INVALID; 420 return; 421 } 422 if (IS_SCSI(isp)) { 423 if (tgt != CAM_TARGET_WILDCARD && 424 tgt != SDPARAM(isp)->isp_initiator_id) { 425 ccb->ccb_h.status = CAM_TID_INVALID; 426 return; 427 } 428 } else { 429 if (tgt != CAM_TARGET_WILDCARD && 430 tgt != FCPARAM(isp)->isp_iid) { 431 ccb->ccb_h.status = CAM_TID_INVALID; 432 return; 433 } 434 } 435 436 if (tgt == CAM_TARGET_WILDCARD) { 437 if (lun != CAM_LUN_WILDCARD) { 438 ccb->ccb_h.status = CAM_LUN_INVALID; 439 return; 440 } 441 } 442 443 /* 444 * If Fibre Channel, stop and drain all activity to this bus. 445 */ 446 #if 0 447 if (IS_FC(isp)) { 448 ISP_LOCK(isp); 449 frozen = 1; 450 xpt_freeze_simq(isp->isp_sim, 1); 451 isp->isp_osinfo.drain = 1; 452 while (isp->isp_osinfo.drain) { 453 (void) msleep(&isp->isp_osinfo.drain, 454 &isp->isp_osinfo.lock, PRIBIO, 455 "ispdrain", 10 * hz); 456 } 457 ISP_UNLOCK(isp); 458 } 459 #endif 460 461 /* 462 * Check to see if we're enabling on fibre channel and 463 * don't yet have a notion of who the heck we are (no 464 * loop yet). 465 */ 466 if (IS_FC(isp) && cel->enable && 467 (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 468 fcparam *fcp = isp->isp_param; 469 int rv; 470 471 ISP_LOCK(isp); 472 rv = isp_fc_runstate(isp, 2 * 1000000); 473 ISP_UNLOCK(isp); 474 if (fcp->isp_fwstate != FW_READY || 475 fcp->isp_loopstate != LOOP_READY) { 476 xpt_print_path(ccb->ccb_h.path); 477 isp_prt(isp, ISP_LOGWARN, 478 "could not get a good port database read"); 479 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 480 if (frozen) 481 xpt_release_simq(isp->isp_sim, 1); 482 return; 483 } 484 } 485 486 487 /* 488 * Next check to see whether this is a target/lun wildcard action. 489 * 490 * If so, we enable/disable target mode but don't do any lun enabling. 491 */ 492 if (lun == CAM_LUN_WILDCARD && tgt == CAM_TARGET_WILDCARD) { 493 int av; 494 tptr = &isp->isp_osinfo.tsdflt; 495 if (cel->enable) { 496 if (isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) { 497 ccb->ccb_h.status = CAM_LUN_ALRDY_ENA; 498 if (frozen) 499 xpt_release_simq(isp->isp_sim, 1); 500 return; 501 } 502 ccb->ccb_h.status = 503 xpt_create_path(&tptr->owner, NULL, 504 xpt_path_path_id(ccb->ccb_h.path), 505 xpt_path_target_id(ccb->ccb_h.path), 506 xpt_path_lun_id(ccb->ccb_h.path)); 507 if (ccb->ccb_h.status != CAM_REQ_CMP) { 508 if (frozen) 509 xpt_release_simq(isp->isp_sim, 1); 510 return; 511 } 512 SLIST_INIT(&tptr->atios); 513 SLIST_INIT(&tptr->inots); 514 av = 1; 515 ISP_LOCK(isp); 516 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 517 if (av) { 518 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 519 xpt_free_path(tptr->owner); 520 ISP_UNLOCK(isp); 521 if (frozen) 522 xpt_release_simq(isp->isp_sim, 1); 523 return; 524 } 525 isp->isp_osinfo.tmflags |= TM_TMODE_ENABLED; 526 ISP_UNLOCK(isp); 527 } else { 528 if ((isp->isp_osinfo.tmflags & TM_TMODE_ENABLED) == 0) { 529 ccb->ccb_h.status = CAM_LUN_INVALID; 530 if (frozen) 531 xpt_release_simq(isp->isp_sim, 1); 532 return; 533 } 534 if (are_any_luns_enabled(isp)) { 535 ccb->ccb_h.status = CAM_SCSI_BUSY; 536 if (frozen) 537 xpt_release_simq(isp->isp_sim, 1); 538 return; 539 } 540 av = 0; 541 ISP_LOCK(isp); 542 av = isp_control(isp, ISPCTL_TOGGLE_TMODE, &av); 543 if (av) { 544 ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; 545 ISP_UNLOCK(isp); 546 if (frozen) 547 xpt_release_simq(isp->isp_sim, 1); 548 return; 549 } 550 isp->isp_osinfo.tmflags &= ~TM_TMODE_ENABLED; 551 ISP_UNLOCK(isp); 552 ccb->ccb_h.status = CAM_REQ_CMP; 553 } 554 xpt_print_path(ccb->ccb_h.path); 555 isp_prt(isp, ISP_LOGINFO, lfmt, (cel->enable) ? "en" : "dis"); 556 if (frozen) 557 xpt_release_simq(isp->isp_sim, 1); 558 return; 559 } 560 561 /* 562 * We can move along now... 563 */ 564 565 if (frozen) 566 xpt_release_simq(isp->isp_sim, 1); 567 568 569 if (cel->enable) { 570 ccb->ccb_h.status = 571 create_lun_state(isp, ccb->ccb_h.path, &tptr); 572 if (ccb->ccb_h.status != CAM_REQ_CMP) { 573 return; 574 } 575 } else { 576 tptr = get_lun_statep(isp, lun); 577 if (tptr == NULL) { 578 ccb->ccb_h.status = CAM_LUN_INVALID; 579 return; 580 } 581 } 582 583 if (isp_psema_sig_rqe(isp)) { 584 rls_lun_statep(isp, tptr); 585 if (cel->enable) 586 destroy_lun_state(isp, tptr); 587 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 588 return; 589 } 590 591 ISP_LOCK(isp); 592 if (cel->enable) { 593 u_int32_t seq = isp->isp_osinfo.rollinfo++; 594 rstat = LUN_ERR; 595 if (isp_lun_cmd(isp, RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) { 596 xpt_print_path(ccb->ccb_h.path); 597 isp_prt(isp, ISP_LOGWARN, "isp_lun_cmd failed"); 598 goto out; 599 } 600 if (isp_cv_wait_timed_rqe(isp, 30 * hz)) { 601 xpt_print_path(ccb->ccb_h.path); 602 isp_prt(isp, ISP_LOGERR, 603 "wait for ENABLE LUN timed out"); 604 goto out; 605 } 606 rstat = isp->isp_osinfo.rstatus; 607 if (rstat != LUN_OK) { 608 xpt_print_path(ccb->ccb_h.path); 609 isp_prt(isp, ISP_LOGERR, 610 "ENABLE LUN returned 0x%x", rstat); 611 goto out; 612 } 613 } else { 614 u_int32_t seq; 615 616 seq = isp->isp_osinfo.rollinfo++; 617 rstat = LUN_ERR; 618 619 if (isp_lun_cmd(isp, -RQSTYPE_MODIFY_LUN, bus, tgt, lun, seq)) { 620 xpt_print_path(ccb->ccb_h.path); 621 isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed"); 622 goto out; 623 } 624 if (isp_cv_wait_timed_rqe(isp, 30 * hz)) { 625 xpt_print_path(ccb->ccb_h.path); 626 isp_prt(isp, ISP_LOGERR, 627 "wait for MODIFY LUN timed out"); 628 goto out; 629 } 630 rstat = isp->isp_osinfo.rstatus; 631 if (rstat != LUN_OK) { 632 xpt_print_path(ccb->ccb_h.path); 633 isp_prt(isp, ISP_LOGERR, 634 "MODIFY LUN returned 0x%x", rstat); 635 goto out; 636 } 637 rstat = LUN_ERR; 638 seq = isp->isp_osinfo.rollinfo++; 639 640 if (isp_lun_cmd(isp, -RQSTYPE_ENABLE_LUN, bus, tgt, lun, seq)) { 641 xpt_print_path(ccb->ccb_h.path); 642 isp_prt(isp, ISP_LOGERR, "isp_lun_cmd failed"); 643 goto out; 644 } 645 if (isp_cv_wait_timed_rqe(isp, 30 * hz)) { 646 xpt_print_path(ccb->ccb_h.path); 647 isp_prt(isp, ISP_LOGERR, 648 "wait for ENABLE LUN timed out"); 649 goto out; 650 } 651 rstat = isp->isp_osinfo.rstatus; 652 if (rstat != LUN_OK) { 653 xpt_print_path(ccb->ccb_h.path); 654 isp_prt(isp, ISP_LOGWARN, 655 "ENABLE LUN returned 0x%x", rstat); 656 goto out; 657 } 658 } 659 out: 660 isp_vsema_rqe(isp); 661 ISP_UNLOCK(isp); 662 663 if (rstat != LUN_OK) { 664 xpt_print_path(ccb->ccb_h.path); 665 isp_prt(isp, ISP_LOGWARN, 666 "lun %sable failed", (cel->enable) ? "en" : "dis"); 667 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 668 rls_lun_statep(isp, tptr); 669 if (cel->enable) 670 destroy_lun_state(isp, tptr); 671 } else { 672 xpt_print_path(ccb->ccb_h.path); 673 isp_prt(isp, ISP_LOGINFO, lfmt, (cel->enable) ? "en" : "dis"); 674 rls_lun_statep(isp, tptr); 675 if (cel->enable == 0) { 676 destroy_lun_state(isp, tptr); 677 } 678 ccb->ccb_h.status = CAM_REQ_CMP; 679 } 680 } 681 682 static cam_status 683 isp_abort_tgt_ccb(struct ispsoftc *isp, union ccb *ccb) 684 { 685 tstate_t *tptr; 686 struct ccb_hdr_slist *lp; 687 struct ccb_hdr *curelm; 688 int found; 689 union ccb *accb = ccb->cab.abort_ccb; 690 691 if (accb->ccb_h.target_id != CAM_TARGET_WILDCARD) { 692 if (IS_FC(isp) && (accb->ccb_h.target_id != 693 ((fcparam *) isp->isp_param)->isp_loopid)) { 694 return (CAM_PATH_INVALID); 695 } else if (IS_SCSI(isp) && (accb->ccb_h.target_id != 696 ((sdparam *) isp->isp_param)->isp_initiator_id)) { 697 return (CAM_PATH_INVALID); 698 } 699 } 700 tptr = get_lun_statep(isp, accb->ccb_h.target_lun); 701 if (tptr == NULL) { 702 return (CAM_PATH_INVALID); 703 } 704 if (accb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 705 lp = &tptr->atios; 706 } else if (accb->ccb_h.func_code == XPT_IMMED_NOTIFY) { 707 lp = &tptr->inots; 708 } else { 709 rls_lun_statep(isp, tptr); 710 return (CAM_UA_ABORT); 711 } 712 curelm = SLIST_FIRST(lp); 713 found = 0; 714 if (curelm == &accb->ccb_h) { 715 found = 1; 716 SLIST_REMOVE_HEAD(lp, sim_links.sle); 717 } else { 718 while(curelm != NULL) { 719 struct ccb_hdr *nextelm; 720 721 nextelm = SLIST_NEXT(curelm, sim_links.sle); 722 if (nextelm == &accb->ccb_h) { 723 found = 1; 724 SLIST_NEXT(curelm, sim_links.sle) = 725 SLIST_NEXT(nextelm, sim_links.sle); 726 break; 727 } 728 curelm = nextelm; 729 } 730 } 731 rls_lun_statep(isp, tptr); 732 if (found) { 733 accb->ccb_h.status = CAM_REQ_ABORTED; 734 return (CAM_REQ_CMP); 735 } 736 return(CAM_PATH_INVALID); 737 } 738 739 static cam_status 740 isp_target_start_ctio(struct ispsoftc *isp, union ccb *ccb) 741 { 742 void *qe; 743 struct ccb_scsiio *cso = &ccb->csio; 744 u_int16_t *hp, save_handle; 745 u_int16_t iptr, optr; 746 747 748 if (isp_getrqentry(isp, &iptr, &optr, &qe)) { 749 xpt_print_path(ccb->ccb_h.path); 750 printf("Request Queue Overflow in isp_target_start_ctio\n"); 751 return (CAM_RESRC_UNAVAIL); 752 } 753 bzero(qe, QENTRY_LEN); 754 755 /* 756 * We're either moving data or completing a command here. 757 */ 758 759 if (IS_FC(isp)) { 760 struct ccb_accept_tio *atiop; 761 ct2_entry_t *cto = qe; 762 763 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 764 cto->ct_header.rqs_entry_count = 1; 765 cto->ct_iid = cso->init_id; 766 if (isp->isp_maxluns <= 16) { 767 cto->ct_lun = ccb->ccb_h.target_lun; 768 } 769 /* 770 * Start with a residual based on what the original datalength 771 * was supposed to be. Basically, we ignore what CAM has set 772 * for residuals. The data transfer routines will knock off 773 * the residual for each byte actually moved- and also will 774 * be responsible for setting the underrun flag. 775 */ 776 /* HACK! HACK! */ 777 if ((atiop = ccb->ccb_h.periph_priv.entries[1].ptr) != NULL) { 778 cto->ct_resid = atiop->ccb_h.spriv_field0; 779 } 780 781 /* 782 * We always have to use the tag_id- it has the responder 783 * exchange id in it. 784 */ 785 cto->ct_rxid = cso->tag_id; 786 if (cso->dxfer_len == 0) { 787 cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA; 788 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 789 cto->ct_flags |= CT2_SENDSTATUS; 790 cto->rsp.m1.ct_scsi_status = cso->scsi_status; 791 } 792 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) { 793 int m = min(cso->sense_len, MAXRESPLEN); 794 bcopy(&cso->sense_data, cto->rsp.m1.ct_resp, m); 795 cto->rsp.m1.ct_senselen = m; 796 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 797 } 798 } else { 799 cto->ct_flags |= CT2_FLAG_MODE0; 800 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 801 cto->ct_flags |= CT2_DATA_IN; 802 } else { 803 cto->ct_flags |= CT2_DATA_OUT; 804 } 805 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 806 cto->ct_flags |= CT2_SENDSTATUS; 807 cto->rsp.m0.ct_scsi_status = cso->scsi_status; 808 } 809 /* 810 * If we're sending data and status back together, 811 * we can't also send back sense data as well. 812 */ 813 ccb->ccb_h.flags &= ~CAM_SEND_SENSE; 814 } 815 if (cto->ct_flags & CAM_SEND_STATUS) { 816 isp_prt(isp, ISP_LOGTDEBUG2, 817 "CTIO2[%x] SCSI STATUS 0x%x datalength %u", 818 cto->ct_rxid, cso->scsi_status, cto->ct_resid); 819 } 820 hp = &cto->ct_syshandle; 821 } else { 822 ct_entry_t *cto = qe; 823 824 /* 825 * We always have to use the tag_id- it has the handle 826 * for this command. 827 */ 828 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 829 cto->ct_header.rqs_entry_count = 1; 830 cto->ct_iid = cso->init_id; 831 cto->ct_tgt = ccb->ccb_h.target_id; 832 cto->ct_lun = ccb->ccb_h.target_lun; 833 cto->ct_fwhandle = cso->tag_id >> 8; 834 if (cso->tag_id && cso->tag_action) { 835 /* 836 * We don't specify a tag type for regular SCSI. 837 * Just the tag value and set the flag. 838 */ 839 cto->ct_tag_val = cso->tag_id & 0xff; 840 cto->ct_flags |= CT_TQAE; 841 } 842 if (ccb->ccb_h.flags & CAM_DIS_DISCONNECT) { 843 cto->ct_flags |= CT_NODISC; 844 } 845 if (cso->dxfer_len == 0) { 846 cto->ct_flags |= CT_NO_DATA; 847 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 848 cto->ct_flags |= CT_DATA_IN; 849 } else { 850 cto->ct_flags |= CT_DATA_OUT; 851 } 852 if (ccb->ccb_h.flags & CAM_SEND_STATUS) { 853 cto->ct_flags |= CT_SENDSTATUS; 854 cto->ct_scsi_status = cso->scsi_status; 855 cto->ct_resid = cso->resid; 856 } 857 if (cto->ct_flags & CAM_SEND_STATUS) { 858 isp_prt(isp, ISP_LOGTDEBUG2, 859 "CTIO SCSI STATUS 0x%x resid %d", 860 cso->scsi_status, cso->resid); 861 } 862 hp = &cto->ct_syshandle; 863 ccb->ccb_h.flags &= ~CAM_SEND_SENSE; 864 } 865 866 if (isp_save_xs(isp, (XS_T *)ccb, hp)) { 867 xpt_print_path(ccb->ccb_h.path); 868 printf("No XFLIST pointers for isp_target_start_ctio\n"); 869 return (CAM_RESRC_UNAVAIL); 870 } 871 872 873 /* 874 * Call the dma setup routines for this entry (and any subsequent 875 * CTIOs) if there's data to move, and then tell the f/w it's got 876 * new things to play with. As with isp_start's usage of DMA setup, 877 * any swizzling is done in the machine dependent layer. Because 878 * of this, we put the request onto the queue area first in native 879 * format. 880 */ 881 882 save_handle = *hp; 883 switch (ISP_DMASETUP(isp, cso, qe, &iptr, optr)) { 884 case CMD_QUEUED: 885 ISP_ADD_REQUEST(isp, iptr); 886 return (CAM_REQ_INPROG); 887 888 case CMD_EAGAIN: 889 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 890 isp_destroy_handle(isp, save_handle); 891 return (CAM_RESRC_UNAVAIL); 892 893 default: 894 isp_destroy_handle(isp, save_handle); 895 return (XS_ERR(ccb)); 896 } 897 } 898 899 static cam_status 900 isp_target_putback_atio(struct ispsoftc *isp, union ccb *ccb) 901 { 902 void *qe; 903 struct ccb_accept_tio *atiop; 904 u_int16_t iptr, optr; 905 906 if (isp_getrqentry(isp, &iptr, &optr, &qe)) { 907 xpt_print_path(ccb->ccb_h.path); 908 printf("Request Queue Overflow in isp_target_putback_atio\n"); 909 return (CAM_RESRC_UNAVAIL); 910 } 911 bzero(qe, QENTRY_LEN); 912 atiop = (struct ccb_accept_tio *) ccb; 913 if (IS_FC(isp)) { 914 at2_entry_t *at = qe; 915 at->at_header.rqs_entry_type = RQSTYPE_ATIO2; 916 at->at_header.rqs_entry_count = 1; 917 if (isp->isp_maxluns > 16) { 918 at->at_scclun = (uint16_t) atiop->ccb_h.target_lun; 919 } else { 920 at->at_lun = (uint8_t) atiop->ccb_h.target_lun; 921 } 922 at->at_status = CT_OK; 923 at->at_rxid = atiop->tag_id; 924 ISP_SWIZ_ATIO2(isp, qe, qe); 925 } else { 926 at_entry_t *at = qe; 927 at->at_header.rqs_entry_type = RQSTYPE_ATIO; 928 at->at_header.rqs_entry_count = 1; 929 at->at_iid = atiop->init_id; 930 at->at_tgt = atiop->ccb_h.target_id; 931 at->at_lun = atiop->ccb_h.target_lun; 932 at->at_status = CT_OK; 933 if (atiop->ccb_h.status & CAM_TAG_ACTION_VALID) { 934 at->at_tag_type = atiop->tag_action; 935 } 936 at->at_tag_val = atiop->tag_id & 0xff; 937 at->at_handle = atiop->tag_id >> 8; 938 ISP_SWIZ_ATIO(isp, qe, qe); 939 } 940 ISP_TDQE(isp, "isp_target_putback_atio", (int) optr, qe); 941 ISP_ADD_REQUEST(isp, iptr); 942 return (CAM_REQ_CMP); 943 } 944 945 static void 946 isp_refire_putback_atio(void *arg) 947 { 948 union ccb *ccb = arg; 949 int s = splcam(); 950 if (isp_target_putback_atio(XS_ISP(ccb), ccb) != CAM_REQ_CMP) { 951 (void) timeout(isp_refire_putback_atio, ccb, 10); 952 } else { 953 isp_handle_platform_ctio_part2(XS_ISP(ccb), ccb); 954 } 955 splx(s); 956 } 957 958 /* 959 * Handle ATIO stuff that the generic code can't. 960 * This means handling CDBs. 961 */ 962 963 static int 964 isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep) 965 { 966 tstate_t *tptr; 967 int status; 968 struct ccb_accept_tio *atiop; 969 970 /* 971 * The firmware status (except for the QLTM_SVALID bit) 972 * indicates why this ATIO was sent to us. 973 * 974 * If QLTM_SVALID is set, the firware has recommended Sense Data. 975 * 976 * If the DISCONNECTS DISABLED bit is set in the flags field, 977 * we're still connected on the SCSI bus - i.e. the initiator 978 * did not set DiscPriv in the identify message. We don't care 979 * about this so it's ignored. 980 */ 981 status = aep->at_status; 982 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) { 983 /* 984 * Bus Phase Sequence error. We should have sense data 985 * suggested by the f/w. I'm not sure quite yet what 986 * to do about this for CAM. 987 */ 988 isp_prt(isp, ISP_LOGWARN, "PHASE ERROR"); 989 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 990 return (0); 991 } 992 if ((status & ~QLTM_SVALID) != AT_CDB) { 993 isp_prt(isp, 994 ISP_LOGWARN, "bogus atio (0x%x) leaked to platform", 995 status); 996 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 997 return (0); 998 } 999 1000 tptr = get_lun_statep(isp, aep->at_lun); 1001 if (tptr == NULL) { 1002 tptr = get_lun_statep(isp, CAM_LUN_WILDCARD); 1003 } 1004 1005 if (tptr == NULL) { 1006 /* 1007 * Because we can't autofeed sense data back with 1008 * a command for parallel SCSI, we can't give back 1009 * a CHECK CONDITION. We'll give back a BUSY status 1010 * instead. This works out okay because the only 1011 * time we should, in fact, get this, is in the 1012 * case that somebody configured us without the 1013 * blackhole driver, so they get what they deserve. 1014 */ 1015 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1016 return (0); 1017 } 1018 1019 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 1020 if (atiop == NULL) { 1021 /* 1022 * Because we can't autofeed sense data back with 1023 * a command for parallel SCSI, we can't give back 1024 * a CHECK CONDITION. We'll give back a QUEUE FULL status 1025 * instead. This works out okay because the only time we 1026 * should, in fact, get this, is in the case that we've 1027 * run out of ATIOS. 1028 */ 1029 xpt_print_path(tptr->owner); 1030 isp_prt(isp, ISP_LOGWARN, 1031 "no ATIOS for lun %d from initiator %d", 1032 aep->at_lun, aep->at_iid); 1033 rls_lun_statep(isp, tptr); 1034 if (aep->at_flags & AT_TQAE) 1035 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0); 1036 else 1037 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1038 return (0); 1039 } 1040 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1041 if (tptr == &isp->isp_osinfo.tsdflt) { 1042 atiop->ccb_h.target_id = aep->at_tgt; 1043 atiop->ccb_h.target_lun = aep->at_lun; 1044 } 1045 if (aep->at_flags & AT_NODISC) { 1046 atiop->ccb_h.flags = CAM_DIS_DISCONNECT; 1047 } else { 1048 atiop->ccb_h.flags = 0; 1049 } 1050 1051 if (status & QLTM_SVALID) { 1052 size_t amt = imin(QLTM_SENSELEN, sizeof (atiop->sense_data)); 1053 atiop->sense_len = amt; 1054 MEMCPY(&atiop->sense_data, aep->at_sense, amt); 1055 } else { 1056 atiop->sense_len = 0; 1057 } 1058 1059 atiop->init_id = aep->at_iid; 1060 atiop->cdb_len = aep->at_cdblen; 1061 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen); 1062 atiop->ccb_h.status = CAM_CDB_RECVD; 1063 atiop->tag_id = aep->at_tag_val | (aep->at_handle << 8); 1064 if ((atiop->tag_action = aep->at_tag_type) != 0) { 1065 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; 1066 } 1067 xpt_done((union ccb*)atiop); 1068 isp_prt(isp, ISP_LOGTDEBUG2, 1069 "ATIO[%x] CDB=0x%x iid%d->lun%d tag 0x%x ttype 0x%x %s", 1070 aep->at_handle, aep->at_cdb[0] & 0xff, aep->at_iid, aep->at_lun, 1071 aep->at_tag_val & 0xff, aep->at_tag_type, 1072 (aep->at_flags & AT_NODISC)? "nondisc" : "disconnecting"); 1073 rls_lun_statep(isp, tptr); 1074 return (0); 1075 } 1076 1077 static int 1078 isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep) 1079 { 1080 lun_id_t lun; 1081 tstate_t *tptr; 1082 struct ccb_accept_tio *atiop; 1083 1084 /* 1085 * The firmware status (except for the QLTM_SVALID bit) 1086 * indicates why this ATIO was sent to us. 1087 * 1088 * If QLTM_SVALID is set, the firware has recommended Sense Data. 1089 */ 1090 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) { 1091 isp_prt(isp, ISP_LOGWARN, 1092 "bogus atio (0x%x) leaked to platform", aep->at_status); 1093 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1094 return (0); 1095 } 1096 1097 if (isp->isp_maxluns > 16) { 1098 lun = aep->at_scclun; 1099 } else { 1100 lun = aep->at_lun; 1101 } 1102 tptr = get_lun_statep(isp, lun); 1103 if (tptr == NULL) { 1104 tptr = get_lun_statep(isp, CAM_LUN_WILDCARD); 1105 } 1106 1107 if (tptr == NULL) { 1108 /* 1109 * What we'd like to know is whether or not we have a listener 1110 * upstream that really hasn't configured yet. If we do, then 1111 * we can give a more sensible reply here. If not, then we can 1112 * reject this out of hand. 1113 * 1114 * Choices for what to send were 1115 * 1116 * Not Ready, Unit Not Self-Configured Yet 1117 * (0x2,0x3e,0x00) 1118 * 1119 * for the former and 1120 * 1121 * Illegal Request, Logical Unit Not Supported 1122 * (0x5,0x25,0x00) 1123 * 1124 * for the latter. 1125 * 1126 * We used to decide whether there was at least one listener 1127 * based upon whether the black hole driver was configured. 1128 * However, recent config(8) changes have made this hard to do 1129 * at this time. 1130 * 1131 */ 1132 u_int32_t ccode = SCSI_STATUS_BUSY; 1133 1134 /* 1135 * Because we can't autofeed sense data back with 1136 * a command for parallel SCSI, we can't give back 1137 * a CHECK CONDITION. We'll give back a BUSY status 1138 * instead. This works out okay because the only 1139 * time we should, in fact, get this, is in the 1140 * case that somebody configured us without the 1141 * blackhole driver, so they get what they deserve. 1142 */ 1143 isp_endcmd(isp, aep, ccode, 0); 1144 return (0); 1145 } 1146 1147 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 1148 if (atiop == NULL) { 1149 /* 1150 * Because we can't autofeed sense data back with 1151 * a command for parallel SCSI, we can't give back 1152 * a CHECK CONDITION. We'll give back a QUEUE FULL status 1153 * instead. This works out okay because the only time we 1154 * should, in fact, get this, is in the case that we've 1155 * run out of ATIOS. 1156 */ 1157 xpt_print_path(tptr->owner); 1158 isp_prt(isp, ISP_LOGWARN, 1159 "no ATIOS for lun %d from initiator %d", lun, aep->at_iid); 1160 rls_lun_statep(isp, tptr); 1161 if (aep->at_flags & AT_TQAE) 1162 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0); 1163 else 1164 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1165 return (0); 1166 } 1167 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1168 1169 if (tptr == &isp->isp_osinfo.tsdflt) { 1170 atiop->ccb_h.target_id = 1171 ((fcparam *)isp->isp_param)->isp_loopid; 1172 atiop->ccb_h.target_lun = lun; 1173 } 1174 /* 1175 * We don't get 'suggested' sense data as we do with SCSI cards. 1176 */ 1177 atiop->sense_len = 0; 1178 1179 atiop->init_id = aep->at_iid; 1180 atiop->cdb_len = ATIO2_CDBLEN; 1181 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN); 1182 atiop->ccb_h.status = CAM_CDB_RECVD; 1183 atiop->tag_id = aep->at_rxid; 1184 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) { 1185 case ATIO2_TC_ATTR_SIMPLEQ: 1186 atiop->tag_action = MSG_SIMPLE_Q_TAG; 1187 break; 1188 case ATIO2_TC_ATTR_HEADOFQ: 1189 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 1190 break; 1191 case ATIO2_TC_ATTR_ORDERED: 1192 atiop->tag_action = MSG_ORDERED_Q_TAG; 1193 break; 1194 case ATIO2_TC_ATTR_ACAQ: /* ?? */ 1195 case ATIO2_TC_ATTR_UNTAGGED: 1196 default: 1197 atiop->tag_action = 0; 1198 break; 1199 } 1200 if (atiop->tag_action != 0) { 1201 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; 1202 } 1203 1204 /* 1205 * Preserve overall command datalength in private field. 1206 */ 1207 atiop->ccb_h.spriv_field0 = aep->at_datalen; 1208 1209 xpt_done((union ccb*)atiop); 1210 isp_prt(isp, ISP_LOGTDEBUG2, 1211 "ATIO2[%x] CDB=0x%x iid%d->lun%d tattr 0x%x datalen %u", 1212 aep->at_rxid, aep->at_cdb[0] & 0xff, aep->at_iid, 1213 lun, aep->at_taskflags, aep->at_datalen); 1214 rls_lun_statep(isp, tptr); 1215 return (0); 1216 } 1217 1218 static int 1219 isp_handle_platform_ctio(struct ispsoftc *isp, void *arg) 1220 { 1221 union ccb *ccb; 1222 int sentstatus, ok, notify_cam; 1223 1224 /* 1225 * CTIO and CTIO2 are close enough.... 1226 */ 1227 1228 ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_syshandle); 1229 KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio")); 1230 isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_syshandle); 1231 1232 if (IS_FC(isp)) { 1233 ct2_entry_t *ct = arg; 1234 sentstatus = ct->ct_flags & CT2_SENDSTATUS; 1235 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 1236 if (ok && (ccb->ccb_h.flags & CAM_SEND_SENSE)) { 1237 ccb->ccb_h.status |= CAM_SENT_SENSE; 1238 } 1239 isp_prt(isp, ISP_LOGTDEBUG2, 1240 "CTIO2[%x] sts 0x%x flg 0x%x sns %d FIN", 1241 ct->ct_rxid, ct->ct_status, ct->ct_flags, 1242 (ccb->ccb_h.status & CAM_SENT_SENSE) != 0); 1243 notify_cam = ct->ct_header.rqs_seqno; 1244 } else { 1245 ct_entry_t *ct = arg; 1246 sentstatus = ct->ct_flags & CT_SENDSTATUS; 1247 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 1248 isp_prt(isp, ISP_LOGTDEBUG2, 1249 "CTIO tag 0x%x sts 0x%x flg 0x%x FIN", 1250 ct->ct_tag_val, ct->ct_status, ct->ct_flags); 1251 notify_cam = ct->ct_header.rqs_seqno; 1252 } 1253 1254 /* 1255 * We're here either because data transfers are done (and 1256 * it's time to send a final status CTIO) or because the final 1257 * status CTIO is done. We don't get called for all intermediate 1258 * CTIOs that happen for a large data transfer. 1259 * 1260 * In any case, for this platform, the upper layers figure out 1261 * what to do next, so all we do here is collect status and 1262 * pass information along. The exception is that we clear 1263 * the notion of handling a non-disconnecting command here. 1264 */ 1265 1266 if (sentstatus) { 1267 /* 1268 * Data transfer done. See if all went okay. 1269 */ 1270 if (ok) { 1271 ccb->csio.resid = 0; 1272 } else { 1273 ccb->csio.resid = ccb->csio.dxfer_len; 1274 } 1275 } 1276 1277 if (notify_cam == 0) { 1278 isp_prt(isp, ISP_LOGTDEBUG1, "Intermediate CTIO done"); 1279 return (0); 1280 } 1281 isp_prt(isp, ISP_LOGTDEBUG1, "Final CTIO done"); 1282 if (isp_target_putback_atio(isp, ccb) != CAM_REQ_CMP) { 1283 (void) timeout(isp_refire_putback_atio, ccb, 10); 1284 } else { 1285 isp_handle_platform_ctio_part2(isp, ccb); 1286 } 1287 return (0); 1288 } 1289 1290 static void 1291 isp_handle_platform_ctio_part2(struct ispsoftc *isp, union ccb *ccb) 1292 { 1293 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) { 1294 ccb->ccb_h.status |= CAM_REQ_CMP; 1295 } 1296 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1297 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 1298 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 1299 if (isp->isp_osinfo.simqfrozen == 0) { 1300 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1301 isp_prt(isp, ISP_LOGDEBUG2, "ctio->relsimq"); 1302 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1303 } else { 1304 isp_prt(isp, ISP_LOGDEBUG2, "ctio->devqfrozen"); 1305 } 1306 } else { 1307 isp_prt(isp, ISP_LOGDEBUG2, 1308 "ctio->simqfrozen(%x)", isp->isp_osinfo.simqfrozen); 1309 } 1310 } 1311 xpt_done(ccb); 1312 } 1313 #endif 1314 1315 static void 1316 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg) 1317 { 1318 struct cam_sim *sim; 1319 struct ispsoftc *isp; 1320 1321 sim = (struct cam_sim *)cbarg; 1322 isp = (struct ispsoftc *) cam_sim_softc(sim); 1323 switch (code) { 1324 case AC_LOST_DEVICE: 1325 if (IS_SCSI(isp)) { 1326 u_int16_t oflags, nflags; 1327 sdparam *sdp = isp->isp_param; 1328 int rvf, tgt; 1329 1330 tgt = xpt_path_target_id(path); 1331 rvf = ISP_FW_REVX(isp->isp_fwrev); 1332 ISP_LOCK(isp); 1333 sdp += cam_sim_bus(sim); 1334 isp->isp_update |= (1 << cam_sim_bus(sim)); 1335 nflags = DPARM_SAFE_DFLT; 1336 if (rvf >= ISP_FW_REV(7, 55, 0) || 1337 (ISP_FW_REV(4, 55, 0) <= rvf && 1338 (rvf < ISP_FW_REV(5, 0, 0)))) { 1339 nflags |= DPARM_NARROW | DPARM_ASYNC; 1340 } 1341 oflags = sdp->isp_devparam[tgt].dev_flags; 1342 sdp->isp_devparam[tgt].dev_flags = nflags; 1343 sdp->isp_devparam[tgt].dev_update = 1; 1344 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL); 1345 sdp->isp_devparam[tgt].dev_flags = oflags; 1346 ISP_UNLOCK(isp); 1347 } 1348 break; 1349 default: 1350 isp_prt(isp, ISP_LOGWARN, "isp_cam_async: Code 0x%x", code); 1351 break; 1352 } 1353 } 1354 1355 static void 1356 isp_poll(struct cam_sim *sim) 1357 { 1358 struct ispsoftc *isp = cam_sim_softc(sim); 1359 ISP_LOCK(isp); 1360 (void) isp_intr(isp); 1361 ISP_UNLOCK(isp); 1362 } 1363 1364 static void 1365 isp_relsim(void *arg) 1366 { 1367 struct ispsoftc *isp = arg; 1368 ISP_LOCK(isp); 1369 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED) { 1370 int wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED; 1371 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_TIMED; 1372 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { 1373 xpt_release_simq(isp->isp_sim, 1); 1374 isp_prt(isp, ISP_LOGDEBUG2, "timed relsimq"); 1375 } 1376 } 1377 ISP_UNLOCK(isp); 1378 } 1379 1380 static void 1381 isp_watchdog(void *arg) 1382 { 1383 XS_T *xs = arg; 1384 struct ispsoftc *isp = XS_ISP(xs); 1385 u_int32_t handle; 1386 1387 /* 1388 * We've decided this command is dead. Make sure we're not trying 1389 * to kill a command that's already dead by getting it's handle and 1390 * and seeing whether it's still alive. 1391 */ 1392 ISP_LOCK(isp); 1393 handle = isp_find_handle(isp, xs); 1394 if (handle) { 1395 u_int16_t r; 1396 1397 if (XS_CMD_DONE_P(xs)) { 1398 isp_prt(isp, ISP_LOGDEBUG1, 1399 "watchdog found done cmd (handle 0x%x)", handle); 1400 ISP_UNLOCK(isp); 1401 return; 1402 } 1403 1404 if (XS_CMD_WDOG_P(xs)) { 1405 isp_prt(isp, ISP_LOGDEBUG2, 1406 "recursive watchdog (handle 0x%x)", handle); 1407 ISP_UNLOCK(isp); 1408 return; 1409 } 1410 1411 XS_CMD_S_WDOG(xs); 1412 1413 r = ISP_READ(isp, BIU_ISR); 1414 1415 if (INT_PENDING(isp, r) && isp_intr(isp) && XS_CMD_DONE_P(xs)) { 1416 isp_prt(isp, ISP_LOGDEBUG2, 1417 "watchdog cleanup (%x, %x)", handle, r); 1418 xpt_done((union ccb *) xs); 1419 } else if (XS_CMD_GRACE_P(xs)) { 1420 /* 1421 * Make sure the command is *really* dead before we 1422 * release the handle (and DMA resources) for reuse. 1423 */ 1424 (void) isp_control(isp, ISPCTL_ABORT_CMD, arg); 1425 1426 /* 1427 * After this point, the comamnd is really dead. 1428 */ 1429 if (XS_XFRLEN(xs)) { 1430 ISP_DMAFREE(isp, xs, handle); 1431 } 1432 isp_destroy_handle(isp, handle); 1433 xpt_print_path(xs->ccb_h.path); 1434 isp_prt(isp, ISP_LOGWARN, 1435 "watchdog timeout (%x, %x)", handle, r); 1436 XS_SETERR(xs, CAM_CMD_TIMEOUT); 1437 XS_CMD_C_WDOG(xs); 1438 isp_done(xs); 1439 } else { 1440 u_int16_t iptr, optr; 1441 ispreq_t *mp; 1442 1443 XS_CMD_C_WDOG(xs); 1444 xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz); 1445 if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) { 1446 ISP_UNLOCK(isp); 1447 return; 1448 } 1449 XS_CMD_S_GRACE(xs); 1450 MEMZERO((void *) mp, sizeof (*mp)); 1451 mp->req_header.rqs_entry_count = 1; 1452 mp->req_header.rqs_entry_type = RQSTYPE_MARKER; 1453 mp->req_modifier = SYNC_ALL; 1454 mp->req_target = XS_CHANNEL(xs) << 7; 1455 ISP_SWIZZLE_REQUEST(isp, mp); 1456 ISP_ADD_REQUEST(isp, iptr); 1457 } 1458 } else { 1459 isp_prt(isp, ISP_LOGDEBUG2, "watchdog with no command"); 1460 } 1461 ISP_UNLOCK(isp); 1462 } 1463 1464 static void 1465 isp_action(struct cam_sim *sim, union ccb *ccb) 1466 { 1467 int bus, tgt, error; 1468 struct ispsoftc *isp; 1469 struct ccb_trans_settings *cts; 1470 1471 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 1472 1473 isp = (struct ispsoftc *)cam_sim_softc(sim); 1474 ccb->ccb_h.sim_priv.entries[0].field = 0; 1475 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 1476 if (isp->isp_state != ISP_RUNSTATE && 1477 ccb->ccb_h.func_code == XPT_SCSI_IO) { 1478 ISP_LOCK(isp); 1479 isp_init(isp); 1480 if (isp->isp_state != ISP_INITSTATE) { 1481 ISP_UNLOCK(isp); 1482 /* 1483 * Lie. Say it was a selection timeout. 1484 */ 1485 ccb->ccb_h.status = CAM_SEL_TIMEOUT | CAM_DEV_QFRZN; 1486 xpt_freeze_devq(ccb->ccb_h.path, 1); 1487 xpt_done(ccb); 1488 return; 1489 } 1490 isp->isp_state = ISP_RUNSTATE; 1491 ISP_UNLOCK(isp); 1492 } 1493 isp_prt(isp, ISP_LOGDEBUG2, "isp_action code %x", ccb->ccb_h.func_code); 1494 1495 switch (ccb->ccb_h.func_code) { 1496 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 1497 /* 1498 * Do a couple of preliminary checks... 1499 */ 1500 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 1501 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 1502 ccb->ccb_h.status = CAM_REQ_INVALID; 1503 xpt_done(ccb); 1504 break; 1505 } 1506 } 1507 #ifdef DIAGNOSTIC 1508 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) { 1509 ccb->ccb_h.status = CAM_PATH_INVALID; 1510 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) { 1511 ccb->ccb_h.status = CAM_PATH_INVALID; 1512 } 1513 if (ccb->ccb_h.status == CAM_PATH_INVALID) { 1514 isp_prt(isp, ISP_LOGERR, 1515 "invalid tgt/lun (%d.%d) in XPT_SCSI_IO", 1516 ccb->ccb_h.target_id, ccb->ccb_h.target_lun); 1517 xpt_done(ccb); 1518 break; 1519 } 1520 #endif 1521 ((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK; 1522 ISP_LOCK(isp); 1523 error = isp_start((XS_T *) ccb); 1524 ISP_UNLOCK(isp); 1525 switch (error) { 1526 case CMD_QUEUED: 1527 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1528 if (ccb->ccb_h.timeout != CAM_TIME_INFINITY) { 1529 u_int64_t ticks = (u_int64_t) hz; 1530 if (ccb->ccb_h.timeout == CAM_TIME_DEFAULT) 1531 ticks = 60 * 1000 * ticks; 1532 else 1533 ticks = ccb->ccb_h.timeout * hz; 1534 ticks = ((ticks + 999) / 1000) + hz + hz; 1535 if (ticks >= 0x80000000) { 1536 isp_prt(isp, ISP_LOGERR, 1537 "timeout overflow"); 1538 ticks = 0x80000000; 1539 } 1540 ccb->ccb_h.timeout_ch = timeout(isp_watchdog, 1541 (caddr_t)ccb, (int)ticks); 1542 } else { 1543 callout_handle_init(&ccb->ccb_h.timeout_ch); 1544 } 1545 break; 1546 case CMD_RQLATER: 1547 if (isp->isp_osinfo.simqfrozen == 0) { 1548 isp_prt(isp, ISP_LOGDEBUG2, 1549 "RQLATER freeze simq"); 1550 isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED; 1551 timeout(isp_relsim, isp, 500); 1552 xpt_freeze_simq(sim, 1); 1553 } 1554 XS_SETERR(ccb, CAM_REQUEUE_REQ); 1555 xpt_done(ccb); 1556 break; 1557 case CMD_EAGAIN: 1558 if (isp->isp_osinfo.simqfrozen == 0) { 1559 xpt_freeze_simq(sim, 1); 1560 isp_prt(isp, ISP_LOGDEBUG2, 1561 "EAGAIN freeze simq"); 1562 } 1563 isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; 1564 XS_SETERR(ccb, CAM_REQUEUE_REQ); 1565 xpt_done(ccb); 1566 break; 1567 case CMD_COMPLETE: 1568 ISP_LOCK(isp); 1569 isp_done((struct ccb_scsiio *) ccb); 1570 ISP_UNLOCK(isp); 1571 break; 1572 default: 1573 isp_prt(isp, ISP_LOGERR, 1574 "What's this? 0x%x at %d in file %s", 1575 error, __LINE__, __FILE__); 1576 XS_SETERR(ccb, CAM_REQ_CMP_ERR); 1577 xpt_done(ccb); 1578 } 1579 break; 1580 1581 #ifdef ISP_TARGET_MODE 1582 case XPT_EN_LUN: /* Enable LUN as a target */ 1583 isp_en_lun(isp, ccb); 1584 xpt_done(ccb); 1585 break; 1586 1587 case XPT_NOTIFY_ACK: /* recycle notify ack */ 1588 case XPT_IMMED_NOTIFY: /* Add Immediate Notify Resource */ 1589 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 1590 { 1591 tstate_t *tptr = get_lun_statep(isp, ccb->ccb_h.target_lun); 1592 if (tptr == NULL) { 1593 ccb->ccb_h.status = CAM_LUN_INVALID; 1594 xpt_done(ccb); 1595 break; 1596 } 1597 ccb->ccb_h.sim_priv.entries[0].field = 0; 1598 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 1599 ISP_LOCK(isp); 1600 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 1601 #if 0 1602 (void) isp_target_putback_atio(isp, ccb); 1603 #endif 1604 SLIST_INSERT_HEAD(&tptr->atios, 1605 &ccb->ccb_h, sim_links.sle); 1606 } else { 1607 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, 1608 sim_links.sle); 1609 } 1610 ISP_UNLOCK(isp); 1611 rls_lun_statep(isp, tptr); 1612 ccb->ccb_h.status = CAM_REQ_INPROG; 1613 break; 1614 } 1615 case XPT_CONT_TARGET_IO: 1616 { 1617 ISP_LOCK(isp); 1618 ccb->ccb_h.status = isp_target_start_ctio(isp, ccb); 1619 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1620 if (isp->isp_osinfo.simqfrozen == 0) { 1621 xpt_freeze_simq(sim, 1); 1622 xpt_print_path(ccb->ccb_h.path); 1623 isp_prt(isp, ISP_LOGINFO, 1624 "XPT_CONT_TARGET_IO freeze simq"); 1625 } 1626 isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; 1627 XS_SETERR(ccb, CAM_REQUEUE_REQ); 1628 xpt_done(ccb); 1629 } else { 1630 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1631 } 1632 ISP_UNLOCK(isp); 1633 break; 1634 } 1635 #endif 1636 case XPT_RESET_DEV: /* BDR the specified SCSI device */ 1637 1638 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)); 1639 tgt = ccb->ccb_h.target_id; 1640 tgt |= (bus << 16); 1641 1642 ISP_LOCK(isp); 1643 error = isp_control(isp, ISPCTL_RESET_DEV, &tgt); 1644 ISP_UNLOCK(isp); 1645 if (error) { 1646 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1647 } else { 1648 ccb->ccb_h.status = CAM_REQ_CMP; 1649 } 1650 xpt_done(ccb); 1651 break; 1652 case XPT_ABORT: /* Abort the specified CCB */ 1653 { 1654 union ccb *accb = ccb->cab.abort_ccb; 1655 switch (accb->ccb_h.func_code) { 1656 #ifdef ISP_TARGET_MODE 1657 case XPT_ACCEPT_TARGET_IO: 1658 case XPT_IMMED_NOTIFY: 1659 ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb); 1660 break; 1661 case XPT_CONT_TARGET_IO: 1662 isp_prt(isp, ISP_LOGERR, "cannot abort CTIOs yet"); 1663 ccb->ccb_h.status = CAM_UA_ABORT; 1664 break; 1665 #endif 1666 case XPT_SCSI_IO: 1667 ISP_LOCK(isp); 1668 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb); 1669 ISP_UNLOCK(isp); 1670 if (error) { 1671 ccb->ccb_h.status = CAM_UA_ABORT; 1672 } else { 1673 ccb->ccb_h.status = CAM_REQ_CMP; 1674 } 1675 break; 1676 default: 1677 ccb->ccb_h.status = CAM_REQ_INVALID; 1678 break; 1679 } 1680 xpt_done(ccb); 1681 break; 1682 } 1683 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */ 1684 1685 cts = &ccb->cts; 1686 tgt = cts->ccb_h.target_id; 1687 ISP_LOCK(isp); 1688 if (IS_SCSI(isp)) { 1689 sdparam *sdp = isp->isp_param; 1690 u_int16_t *dptr; 1691 1692 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 1693 1694 sdp += bus; 1695 #if 0 1696 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) 1697 dptr = &sdp->isp_devparam[tgt].cur_dflags; 1698 else 1699 dptr = &sdp->isp_devparam[tgt].dev_flags; 1700 #else 1701 /* 1702 * We always update (internally) from dev_flags 1703 * so any request to change settings just gets 1704 * vectored to that location. 1705 */ 1706 dptr = &sdp->isp_devparam[tgt].dev_flags; 1707 #endif 1708 1709 /* 1710 * Note that these operations affect the 1711 * the goal flags (dev_flags)- not 1712 * the current state flags. Then we mark 1713 * things so that the next operation to 1714 * this HBA will cause the update to occur. 1715 */ 1716 if (cts->valid & CCB_TRANS_DISC_VALID) { 1717 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) { 1718 *dptr |= DPARM_DISC; 1719 } else { 1720 *dptr &= ~DPARM_DISC; 1721 } 1722 } 1723 if (cts->valid & CCB_TRANS_TQ_VALID) { 1724 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) { 1725 *dptr |= DPARM_TQING; 1726 } else { 1727 *dptr &= ~DPARM_TQING; 1728 } 1729 } 1730 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) { 1731 switch (cts->bus_width) { 1732 case MSG_EXT_WDTR_BUS_16_BIT: 1733 *dptr |= DPARM_WIDE; 1734 break; 1735 default: 1736 *dptr &= ~DPARM_WIDE; 1737 } 1738 } 1739 /* 1740 * Any SYNC RATE of nonzero and SYNC_OFFSET 1741 * of nonzero will cause us to go to the 1742 * selected (from NVRAM) maximum value for 1743 * this device. At a later point, we'll 1744 * allow finer control. 1745 */ 1746 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) && 1747 (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) && 1748 (cts->sync_offset > 0)) { 1749 *dptr |= DPARM_SYNC; 1750 } else { 1751 *dptr &= ~DPARM_SYNC; 1752 } 1753 *dptr |= DPARM_SAFE_DFLT; 1754 isp_prt(isp, ISP_LOGDEBUG0, 1755 "%d.%d set %s period 0x%x offset 0x%x flags 0x%x", 1756 bus, tgt, (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 1757 "current" : "user", 1758 sdp->isp_devparam[tgt].sync_period, 1759 sdp->isp_devparam[tgt].sync_offset, 1760 sdp->isp_devparam[tgt].dev_flags); 1761 sdp->isp_devparam[tgt].dev_update = 1; 1762 isp->isp_update |= (1 << bus); 1763 } 1764 ISP_UNLOCK(isp); 1765 ccb->ccb_h.status = CAM_REQ_CMP; 1766 xpt_done(ccb); 1767 break; 1768 1769 case XPT_GET_TRAN_SETTINGS: 1770 1771 cts = &ccb->cts; 1772 tgt = cts->ccb_h.target_id; 1773 if (IS_FC(isp)) { 1774 /* 1775 * a lot of normal SCSI things don't make sense. 1776 */ 1777 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB; 1778 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1779 /* 1780 * How do you measure the width of a high 1781 * speed serial bus? Well, in bytes. 1782 * 1783 * Offset and period make no sense, though, so we set 1784 * (above) a 'base' transfer speed to be gigabit. 1785 */ 1786 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1787 } else { 1788 sdparam *sdp = isp->isp_param; 1789 u_int16_t dval, pval, oval; 1790 int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 1791 1792 sdp += bus; 1793 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) { 1794 ISP_LOCK(isp); 1795 sdp->isp_devparam[tgt].dev_refresh = 1; 1796 isp->isp_update |= (1 << bus); 1797 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, 1798 NULL); 1799 ISP_UNLOCK(isp); 1800 dval = sdp->isp_devparam[tgt].cur_dflags; 1801 oval = sdp->isp_devparam[tgt].cur_offset; 1802 pval = sdp->isp_devparam[tgt].cur_period; 1803 } else { 1804 dval = sdp->isp_devparam[tgt].dev_flags; 1805 oval = sdp->isp_devparam[tgt].sync_offset; 1806 pval = sdp->isp_devparam[tgt].sync_period; 1807 } 1808 1809 ISP_LOCK(isp); 1810 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 1811 1812 if (dval & DPARM_DISC) { 1813 cts->flags |= CCB_TRANS_DISC_ENB; 1814 } 1815 if (dval & DPARM_TQING) { 1816 cts->flags |= CCB_TRANS_TAG_ENB; 1817 } 1818 if (dval & DPARM_WIDE) { 1819 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1820 } else { 1821 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1822 } 1823 cts->valid = CCB_TRANS_BUS_WIDTH_VALID | 1824 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1825 1826 if ((dval & DPARM_SYNC) && oval != 0) { 1827 cts->sync_period = pval; 1828 cts->sync_offset = oval; 1829 cts->valid |= 1830 CCB_TRANS_SYNC_RATE_VALID | 1831 CCB_TRANS_SYNC_OFFSET_VALID; 1832 } 1833 ISP_UNLOCK(isp); 1834 isp_prt(isp, ISP_LOGDEBUG0, 1835 "%d.%d get %s period 0x%x offset 0x%x flags 0x%x", 1836 bus, tgt, (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 1837 "current" : "user", pval, oval, dval); 1838 } 1839 ccb->ccb_h.status = CAM_REQ_CMP; 1840 xpt_done(ccb); 1841 break; 1842 1843 case XPT_CALC_GEOMETRY: 1844 { 1845 struct ccb_calc_geometry *ccg; 1846 u_int32_t secs_per_cylinder; 1847 u_int32_t size_mb; 1848 1849 ccg = &ccb->ccg; 1850 if (ccg->block_size == 0) { 1851 isp_prt(isp, ISP_LOGERR, 1852 "%d.%d XPT_CALC_GEOMETRY block size 0?", 1853 ccg->ccb_h.target_id, ccg->ccb_h.target_lun); 1854 ccb->ccb_h.status = CAM_REQ_INVALID; 1855 xpt_done(ccb); 1856 break; 1857 } 1858 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size); 1859 if (size_mb > 1024) { 1860 ccg->heads = 255; 1861 ccg->secs_per_track = 63; 1862 } else { 1863 ccg->heads = 64; 1864 ccg->secs_per_track = 32; 1865 } 1866 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1867 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1868 ccb->ccb_h.status = CAM_REQ_CMP; 1869 xpt_done(ccb); 1870 break; 1871 } 1872 case XPT_RESET_BUS: /* Reset the specified bus */ 1873 bus = cam_sim_bus(sim); 1874 ISP_LOCK(isp); 1875 error = isp_control(isp, ISPCTL_RESET_BUS, &bus); 1876 ISP_UNLOCK(isp); 1877 if (error) 1878 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1879 else { 1880 if (cam_sim_bus(sim) && isp->isp_path2 != NULL) 1881 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 1882 else if (isp->isp_path != NULL) 1883 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 1884 ccb->ccb_h.status = CAM_REQ_CMP; 1885 } 1886 xpt_done(ccb); 1887 break; 1888 1889 case XPT_TERM_IO: /* Terminate the I/O process */ 1890 ccb->ccb_h.status = CAM_REQ_INVALID; 1891 xpt_done(ccb); 1892 break; 1893 1894 case XPT_PATH_INQ: /* Path routing inquiry */ 1895 { 1896 struct ccb_pathinq *cpi = &ccb->cpi; 1897 1898 cpi->version_num = 1; 1899 #ifdef ISP_TARGET_MODE 1900 /* XXX: we don't support 2nd bus target mode yet */ 1901 if (cam_sim_bus(sim) == 0) 1902 cpi->target_sprt = 1903 PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 1904 else 1905 cpi->target_sprt = 0; 1906 #else 1907 cpi->target_sprt = 0; 1908 #endif 1909 cpi->hba_eng_cnt = 0; 1910 cpi->max_target = ISP_MAX_TARGETS(isp) - 1; 1911 cpi->max_lun = ISP_MAX_LUNS(isp) - 1; 1912 cpi->bus_id = cam_sim_bus(sim); 1913 if (IS_FC(isp)) { 1914 cpi->hba_misc = PIM_NOBUSRESET; 1915 /* 1916 * Because our loop ID can shift from time to time, 1917 * make our initiator ID out of range of our bus. 1918 */ 1919 cpi->initiator_id = cpi->max_target + 1; 1920 1921 /* 1922 * Set base transfer capabilities for Fibre Channel. 1923 * Technically not correct because we don't know 1924 * what media we're running on top of- but we'll 1925 * look good if we always say 100MB/s. 1926 */ 1927 cpi->base_transfer_speed = 100000; 1928 cpi->hba_inquiry = PI_TAG_ABLE; 1929 } else { 1930 sdparam *sdp = isp->isp_param; 1931 sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path)); 1932 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 1933 cpi->hba_misc = 0; 1934 cpi->initiator_id = sdp->isp_initiator_id; 1935 cpi->base_transfer_speed = 3300; 1936 } 1937 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1938 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 1939 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1940 cpi->unit_number = cam_sim_unit(sim); 1941 cpi->ccb_h.status = CAM_REQ_CMP; 1942 xpt_done(ccb); 1943 break; 1944 } 1945 default: 1946 ccb->ccb_h.status = CAM_REQ_INVALID; 1947 xpt_done(ccb); 1948 break; 1949 } 1950 } 1951 1952 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 1953 void 1954 isp_done(struct ccb_scsiio *sccb) 1955 { 1956 struct ispsoftc *isp = XS_ISP(sccb); 1957 1958 if (XS_NOERR(sccb)) 1959 XS_SETERR(sccb, CAM_REQ_CMP); 1960 1961 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && 1962 (sccb->scsi_status != SCSI_STATUS_OK)) { 1963 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 1964 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && 1965 (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) { 1966 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; 1967 } else { 1968 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1969 } 1970 } 1971 1972 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1973 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1974 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1975 sccb->ccb_h.status |= CAM_DEV_QFRZN; 1976 xpt_freeze_devq(sccb->ccb_h.path, 1); 1977 if (sccb->scsi_status != SCSI_STATUS_OK) 1978 isp_prt(isp, ISP_LOGDEBUG2, 1979 "freeze devq %d.%d %x %x", 1980 sccb->ccb_h.target_id, 1981 sccb->ccb_h.target_lun, sccb->ccb_h.status, 1982 sccb->scsi_status); 1983 } 1984 } 1985 1986 /* 1987 * If we were frozen waiting resources, clear that we were frozen 1988 * waiting for resources. If we are no longer frozen, and the devq 1989 * isn't frozen, mark the completing CCB to have the XPT layer 1990 * release the simq. 1991 */ 1992 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 1993 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 1994 if (isp->isp_osinfo.simqfrozen == 0) { 1995 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1996 isp_prt(isp, ISP_LOGDEBUG2, 1997 "isp_done->relsimq"); 1998 sccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1999 } else { 2000 isp_prt(isp, ISP_LOGDEBUG2, 2001 "isp_done->devq frozen"); 2002 } 2003 } else { 2004 isp_prt(isp, ISP_LOGDEBUG2, 2005 "isp_done -> simqfrozen = %x", 2006 isp->isp_osinfo.simqfrozen); 2007 } 2008 } 2009 if ((CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB)) && 2010 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 2011 xpt_print_path(sccb->ccb_h.path); 2012 isp_prt(isp, ISP_LOGINFO, 2013 "cam completion status 0x%x", sccb->ccb_h.status); 2014 } 2015 2016 XS_CMD_S_DONE(sccb); 2017 if (XS_CMD_WDOG_P(sccb) == 0) { 2018 untimeout(isp_watchdog, (caddr_t)sccb, sccb->ccb_h.timeout_ch); 2019 if (XS_CMD_GRACE_P(sccb)) { 2020 isp_prt(isp, ISP_LOGDEBUG2, 2021 "finished command on borrowed time"); 2022 } 2023 XS_CMD_S_CLEAR(sccb); 2024 ISP_UNLOCK(isp); 2025 #ifdef ISP_SMPLOCK 2026 mtx_lock(&Giant); 2027 xpt_done((union ccb *) sccb); 2028 mtx_unlock(&Giant); 2029 #else 2030 xpt_done((union ccb *) sccb); 2031 #endif 2032 ISP_LOCK(isp); 2033 } 2034 } 2035 2036 int 2037 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg) 2038 { 2039 int bus, rv = 0; 2040 switch (cmd) { 2041 case ISPASYNC_NEW_TGT_PARAMS: 2042 { 2043 int flags, tgt; 2044 sdparam *sdp = isp->isp_param; 2045 struct ccb_trans_settings neg; 2046 struct cam_path *tmppath; 2047 2048 tgt = *((int *)arg); 2049 bus = (tgt >> 16) & 0xffff; 2050 tgt &= 0xffff; 2051 sdp += bus; 2052 if (xpt_create_path(&tmppath, NULL, 2053 cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim), 2054 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 2055 isp_prt(isp, ISP_LOGWARN, 2056 "isp_async cannot make temp path for %d.%d", 2057 tgt, bus); 2058 rv = -1; 2059 break; 2060 } 2061 flags = sdp->isp_devparam[tgt].cur_dflags; 2062 neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 2063 if (flags & DPARM_DISC) { 2064 neg.flags |= CCB_TRANS_DISC_ENB; 2065 } 2066 if (flags & DPARM_TQING) { 2067 neg.flags |= CCB_TRANS_TAG_ENB; 2068 } 2069 neg.valid |= CCB_TRANS_BUS_WIDTH_VALID; 2070 neg.bus_width = (flags & DPARM_WIDE)? 2071 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT; 2072 neg.sync_period = sdp->isp_devparam[tgt].cur_period; 2073 neg.sync_offset = sdp->isp_devparam[tgt].cur_offset; 2074 if (flags & DPARM_SYNC) { 2075 neg.valid |= 2076 CCB_TRANS_SYNC_RATE_VALID | 2077 CCB_TRANS_SYNC_OFFSET_VALID; 2078 } 2079 isp_prt(isp, ISP_LOGDEBUG2, 2080 "NEW_TGT_PARAMS bus %d tgt %d period %x offset %x flags %x", 2081 bus, tgt, neg.sync_period, neg.sync_offset, flags); 2082 xpt_setup_ccb(&neg.ccb_h, tmppath, 1); 2083 xpt_async(AC_TRANSFER_NEG, tmppath, &neg); 2084 xpt_free_path(tmppath); 2085 break; 2086 } 2087 case ISPASYNC_BUS_RESET: 2088 bus = *((int *)arg); 2089 isp_prt(isp, ISP_LOGINFO, "SCSI bus reset on bus %d detected", 2090 bus); 2091 if (bus > 0 && isp->isp_path2) { 2092 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 2093 } else if (isp->isp_path) { 2094 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 2095 } 2096 break; 2097 case ISPASYNC_LOOP_DOWN: 2098 if (isp->isp_path) { 2099 if (isp->isp_osinfo.simqfrozen == 0) { 2100 isp_prt(isp, ISP_LOGDEBUG2, 2101 "loop down freeze simq"); 2102 xpt_freeze_simq(isp->isp_sim, 1); 2103 } 2104 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN; 2105 } 2106 isp_prt(isp, ISP_LOGINFO, "Loop DOWN"); 2107 break; 2108 case ISPASYNC_LOOP_UP: 2109 if (isp->isp_path) { 2110 int wasfrozen = 2111 isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN; 2112 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN; 2113 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { 2114 xpt_release_simq(isp->isp_sim, 1); 2115 isp_prt(isp, ISP_LOGDEBUG2, 2116 "loop up release simq"); 2117 } 2118 } 2119 isp_prt(isp, ISP_LOGINFO, "Loop UP"); 2120 break; 2121 case ISPASYNC_PROMENADE: 2122 { 2123 const char *fmt = "Target %d (Loop 0x%x) Port ID 0x%x " 2124 "(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x"; 2125 static const char *roles[4] = { 2126 "(none)", "Target", "Initiator", "Target/Initiator" 2127 }; 2128 fcparam *fcp = isp->isp_param; 2129 int tgt = *((int *) arg); 2130 struct lportdb *lp = &fcp->portdb[tgt]; 2131 2132 isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid, 2133 roles[lp->roles & 0x3], 2134 (lp->valid)? "Arrived" : "Departed", 2135 (u_int32_t) (lp->port_wwn >> 32), 2136 (u_int32_t) (lp->port_wwn & 0xffffffffLL), 2137 (u_int32_t) (lp->node_wwn >> 32), 2138 (u_int32_t) (lp->node_wwn & 0xffffffffLL)); 2139 break; 2140 } 2141 case ISPASYNC_CHANGE_NOTIFY: 2142 if (arg == (void *) 1) { 2143 isp_prt(isp, ISP_LOGINFO, 2144 "Name Server Database Changed"); 2145 } else { 2146 isp_prt(isp, ISP_LOGINFO, 2147 "Name Server Database Changed"); 2148 } 2149 break; 2150 case ISPASYNC_FABRIC_DEV: 2151 { 2152 int target, lrange; 2153 struct lportdb *lp = NULL; 2154 char *pt; 2155 sns_ganrsp_t *resp = (sns_ganrsp_t *) arg; 2156 u_int32_t portid; 2157 u_int64_t wwpn, wwnn; 2158 fcparam *fcp = isp->isp_param; 2159 2160 portid = 2161 (((u_int32_t) resp->snscb_port_id[0]) << 16) | 2162 (((u_int32_t) resp->snscb_port_id[1]) << 8) | 2163 (((u_int32_t) resp->snscb_port_id[2])); 2164 2165 wwpn = 2166 (((u_int64_t)resp->snscb_portname[0]) << 56) | 2167 (((u_int64_t)resp->snscb_portname[1]) << 48) | 2168 (((u_int64_t)resp->snscb_portname[2]) << 40) | 2169 (((u_int64_t)resp->snscb_portname[3]) << 32) | 2170 (((u_int64_t)resp->snscb_portname[4]) << 24) | 2171 (((u_int64_t)resp->snscb_portname[5]) << 16) | 2172 (((u_int64_t)resp->snscb_portname[6]) << 8) | 2173 (((u_int64_t)resp->snscb_portname[7])); 2174 2175 wwnn = 2176 (((u_int64_t)resp->snscb_nodename[0]) << 56) | 2177 (((u_int64_t)resp->snscb_nodename[1]) << 48) | 2178 (((u_int64_t)resp->snscb_nodename[2]) << 40) | 2179 (((u_int64_t)resp->snscb_nodename[3]) << 32) | 2180 (((u_int64_t)resp->snscb_nodename[4]) << 24) | 2181 (((u_int64_t)resp->snscb_nodename[5]) << 16) | 2182 (((u_int64_t)resp->snscb_nodename[6]) << 8) | 2183 (((u_int64_t)resp->snscb_nodename[7])); 2184 if (portid == 0 || wwpn == 0) { 2185 break; 2186 } 2187 2188 switch (resp->snscb_port_type) { 2189 case 1: 2190 pt = " N_Port"; 2191 break; 2192 case 2: 2193 pt = " NL_Port"; 2194 break; 2195 case 3: 2196 pt = "F/NL_Port"; 2197 break; 2198 case 0x7f: 2199 pt = " Nx_Port"; 2200 break; 2201 case 0x81: 2202 pt = " F_port"; 2203 break; 2204 case 0x82: 2205 pt = " FL_Port"; 2206 break; 2207 case 0x84: 2208 pt = " E_port"; 2209 break; 2210 default: 2211 pt = "?"; 2212 break; 2213 } 2214 isp_prt(isp, ISP_LOGINFO, 2215 "%s @ 0x%x, Node 0x%08x%08x Port %08x%08x", 2216 pt, portid, ((u_int32_t) (wwnn >> 32)), ((u_int32_t) wwnn), 2217 ((u_int32_t) (wwpn >> 32)), ((u_int32_t) wwpn)); 2218 /* 2219 * We're only interested in SCSI_FCP types (for now) 2220 */ 2221 if ((resp->snscb_fc4_types[2] & 1) == 0) { 2222 break; 2223 } 2224 if (fcp->isp_topo != TOPO_F_PORT) 2225 lrange = FC_SNS_ID+1; 2226 else 2227 lrange = 0; 2228 /* 2229 * Is it already in our list? 2230 */ 2231 for (target = lrange; target < MAX_FC_TARG; target++) { 2232 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 2233 continue; 2234 } 2235 lp = &fcp->portdb[target]; 2236 if (lp->port_wwn == wwpn && lp->node_wwn == wwnn) { 2237 lp->fabric_dev = 1; 2238 break; 2239 } 2240 } 2241 if (target < MAX_FC_TARG) { 2242 break; 2243 } 2244 for (target = lrange; target < MAX_FC_TARG; target++) { 2245 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 2246 continue; 2247 } 2248 lp = &fcp->portdb[target]; 2249 if (lp->port_wwn == 0) { 2250 break; 2251 } 2252 } 2253 if (target == MAX_FC_TARG) { 2254 isp_prt(isp, ISP_LOGWARN, 2255 "no more space for fabric devices"); 2256 break; 2257 } 2258 lp->node_wwn = wwnn; 2259 lp->port_wwn = wwpn; 2260 lp->portid = portid; 2261 lp->fabric_dev = 1; 2262 break; 2263 } 2264 #ifdef ISP_TARGET_MODE 2265 case ISPASYNC_TARGET_MESSAGE: 2266 { 2267 tmd_msg_t *mp = arg; 2268 isp_prt(isp, ISP_LOGDEBUG2, 2269 "bus %d iid %d tgt %d lun %d ttype %x tval %x msg[0]=%x", 2270 mp->nt_bus, (int) mp->nt_iid, (int) mp->nt_tgt, 2271 (int) mp->nt_lun, mp->nt_tagtype, mp->nt_tagval, 2272 mp->nt_msg[0]); 2273 break; 2274 } 2275 case ISPASYNC_TARGET_EVENT: 2276 { 2277 tmd_event_t *ep = arg; 2278 isp_prt(isp, ISP_LOGDEBUG2, 2279 "bus %d event code 0x%x", ep->ev_bus, ep->ev_event); 2280 break; 2281 } 2282 case ISPASYNC_TARGET_ACTION: 2283 switch (((isphdr_t *)arg)->rqs_entry_type) { 2284 default: 2285 isp_prt(isp, ISP_LOGWARN, 2286 "event 0x%x for unhandled target action", 2287 ((isphdr_t *)arg)->rqs_entry_type); 2288 break; 2289 case RQSTYPE_ATIO: 2290 rv = isp_handle_platform_atio(isp, (at_entry_t *) arg); 2291 break; 2292 case RQSTYPE_ATIO2: 2293 rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg); 2294 break; 2295 case RQSTYPE_CTIO2: 2296 case RQSTYPE_CTIO: 2297 rv = isp_handle_platform_ctio(isp, arg); 2298 break; 2299 case RQSTYPE_ENABLE_LUN: 2300 case RQSTYPE_MODIFY_LUN: 2301 isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status); 2302 break; 2303 } 2304 break; 2305 #endif 2306 default: 2307 isp_prt(isp, ISP_LOGERR, "unknown isp_async event %d", cmd); 2308 rv = -1; 2309 break; 2310 } 2311 return (rv); 2312 } 2313 2314 2315 /* 2316 * Locks are held before coming here. 2317 */ 2318 void 2319 isp_uninit(struct ispsoftc *isp) 2320 { 2321 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 2322 DISABLE_INTS(isp); 2323 } 2324 2325 void 2326 isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...) 2327 { 2328 va_list ap; 2329 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 2330 return; 2331 } 2332 printf("%s: ", device_get_nameunit(isp->isp_dev)); 2333 va_start(ap, fmt); 2334 vprintf(fmt, ap); 2335 va_end(ap); 2336 printf("\n"); 2337 } 2338