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