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 struct ccb_scsiio *cso = &ccb->csio; 691 u_int32_t *hp, save_handle; 692 u_int16_t iptr, optr; 693 694 if (isp_getrqentry(isp, &iptr, &optr, &qe)) { 695 xpt_print_path(ccb->ccb_h.path); 696 printf("Request Queue Overflow in isp_target_start_ctio\n"); 697 return (CAM_RESRC_UNAVAIL); 698 } 699 bzero(qe, QENTRY_LEN); 700 701 /* 702 * We're either moving data or completing a command here. 703 */ 704 705 if (IS_FC(isp)) { 706 ct2_entry_t *cto = qe; 707 u_int16_t *ssptr = NULL; 708 709 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO2; 710 cto->ct_header.rqs_entry_count = 1; 711 cto->ct_iid = cso->init_id; 712 #ifndef ISP2100_SCCLUN 713 cto->ct_lun = ccb->ccb_h.target_lun; 714 #endif 715 cto->ct_rxid = cso->tag_id; 716 cto->ct_flags = CT2_CCINCR; 717 if (cso->dxfer_len == 0) { 718 cto->ct_flags |= CT2_FLAG_MODE1 | CT2_NO_DATA; 719 KASSERT(ccb->ccb_h.flags & CAM_SEND_STATUS, 720 ("a CTIO with no data and no status?")); 721 cto->ct_flags |= CT2_SENDSTATUS; 722 ssptr = &cto->rsp.m1.ct_scsi_status; 723 *ssptr = cso->scsi_status; 724 if ((ccb->ccb_h.flags & CAM_SEND_SENSE) != 0) { 725 int m = min(cso->sense_len, MAXRESPLEN); 726 bcopy(&cso->sense_data, cto->rsp.m1.ct_resp, m); 727 cto->rsp.m1.ct_senselen = m; 728 cto->rsp.m1.ct_scsi_status |= CT2_SNSLEN_VALID; 729 } 730 } else { 731 cto->ct_flags |= CT2_FLAG_MODE0; 732 if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 733 cto->ct_flags |= CT2_DATA_IN; 734 } else { 735 cto->ct_flags |= CT2_DATA_OUT; 736 } 737 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 738 ssptr = &cto->rsp.m0.ct_scsi_status; 739 cto->ct_flags |= CT2_SENDSTATUS; 740 cto->rsp.m0.ct_scsi_status = cso->scsi_status; 741 } 742 ccb->ccb_h.flags &= ~CAM_SEND_SENSE; 743 } 744 if (ssptr && cso->resid) { 745 cto->ct_resid = cso->resid; 746 if (cso->resid < 0) 747 *ssptr |= CT2_DATA_OVER; 748 else 749 *ssptr |= CT2_DATA_UNDER; 750 } 751 if (isp_tdebug > 1 && ssptr && 752 (cso->scsi_status != SCSI_STATUS_OK || cso->resid)) { 753 printf("%s:CTIO2 RX_ID 0x%x SCSI STATUS 0x%x " 754 "resid %d\n", isp->isp_name, cto->ct_rxid, 755 cso->scsi_status, cso->resid); 756 } 757 hp = &cto->ct_reserved; 758 } else { 759 ct_entry_t *cto = qe; 760 761 cto->ct_header.rqs_entry_type = RQSTYPE_CTIO; 762 cto->ct_header.rqs_entry_count = 1; 763 cto->ct_iid = cso->init_id; 764 cto->ct_tgt = ccb->ccb_h.target_id; 765 cto->ct_lun = ccb->ccb_h.target_lun; 766 cto->ct_tag_type = cso->tag_action; 767 cto->ct_tag_val = cso->tag_id; 768 cto->ct_flags = CT_CCINCR; 769 if (cso->dxfer_len) { 770 cto->ct_flags |= CT_NO_DATA; 771 } else if ((cso->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { 772 cto->ct_flags |= CT_DATA_IN; 773 } else { 774 cto->ct_flags |= CT_DATA_OUT; 775 } 776 if ((ccb->ccb_h.flags & CAM_SEND_STATUS) != 0) { 777 cto->ct_flags |= CT_SENDSTATUS; 778 cto->ct_scsi_status = cso->scsi_status; 779 cto->ct_resid = cso->resid; 780 } 781 if (isp_tdebug > 1 && 782 (cso->scsi_status != SCSI_STATUS_OK || cso->resid)) { 783 printf("%s:CTIO SCSI STATUS 0x%x resid %d\n", 784 isp->isp_name, cso->scsi_status, cso->resid); 785 } 786 hp = &cto->ct_reserved; 787 ccb->ccb_h.flags &= ~CAM_SEND_SENSE; 788 } 789 790 if (isp_save_xs(isp, (ISP_SCSI_XFER_T *)ccb, hp)) { 791 xpt_print_path(ccb->ccb_h.path); 792 printf("No XFLIST pointers for isp_target_start_ctio\n"); 793 return (CAM_RESRC_UNAVAIL); 794 } 795 796 797 /* 798 * Call the dma setup routines for this entry (and any subsequent 799 * CTIOs) if there's data to move, and then tell the f/w it's got 800 * new things to play with. As with ispscsicmd's usage of DMA setup, 801 * any swizzling is done in the machine dependent layer. Because 802 * of this, we put the request onto the queue area first in native 803 * format. 804 */ 805 806 save_handle = *hp; 807 switch (ISP_DMASETUP(isp, cso, qe, &iptr, optr)) { 808 case CMD_QUEUED: 809 MemoryBarrier(); 810 ISP_ADD_REQUEST(isp, iptr); 811 return (CAM_REQ_INPROG); 812 813 case CMD_EAGAIN: 814 ccb->ccb_h.status = CAM_RESRC_UNAVAIL; 815 isp_destroy_handle(isp, save_handle); 816 return (CAM_RESRC_UNAVAIL); 817 818 default: 819 isp_destroy_handle(isp, save_handle); 820 return (ccb->ccb_h.spriv_field0); 821 } 822 } 823 824 /* 825 * Handle ATIO stuff that the generic code can't. 826 * This means handling CDBs. 827 */ 828 829 static int 830 isp_handle_platform_atio(struct ispsoftc *isp, at_entry_t *aep) 831 { 832 tstate_t *tptr; 833 int status; 834 struct ccb_accept_tio *atiop; 835 836 /* 837 * The firmware status (except for the QLTM_SVALID bit) 838 * indicates why this ATIO was sent to us. 839 * 840 * If QLTM_SVALID is set, the firware has recommended Sense Data. 841 * 842 * If the DISCONNECTS DISABLED bit is set in the flags field, 843 * we're still connected on the SCSI bus - i.e. the initiator 844 * did not set DiscPriv in the identify message. We don't care 845 * about this so it's ignored. 846 */ 847 status = aep->at_status; 848 if ((status & ~QLTM_SVALID) == AT_PHASE_ERROR) { 849 /* 850 * Bus Phase Sequence error. We should have sense data 851 * suggested by the f/w. I'm not sure quite yet what 852 * to do about this for CAM. 853 */ 854 printf("%s: PHASE ERROR\n", isp->isp_name); 855 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 856 return (0); 857 } 858 if ((status & ~QLTM_SVALID) != AT_CDB) { 859 printf("%s: bogus atio (0x%x) leaked to platform\n", 860 isp->isp_name, status); 861 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 862 return (0); 863 } 864 865 tptr = get_lun_statep(isp, aep->at_lun); 866 if (tptr == NULL) { 867 tptr = get_lun_statep(isp, CAM_LUN_WILDCARD); 868 } 869 870 if (tptr == NULL) { 871 /* 872 * Because we can't autofeed sense data back with 873 * a command for parallel SCSI, we can't give back 874 * a CHECK CONDITION. We'll give back a BUSY status 875 * instead. This works out okay because the only 876 * time we should, in fact, get this, is in the 877 * case that somebody configured us without the 878 * blackhole driver, so they get what they deserve. 879 */ 880 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 881 return (0); 882 } 883 884 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 885 if (atiop == NULL) { 886 /* 887 * Because we can't autofeed sense data back with 888 * a command for parallel SCSI, we can't give back 889 * a CHECK CONDITION. We'll give back a QUEUE FULL status 890 * instead. This works out okay because the only time we 891 * should, in fact, get this, is in the case that we've 892 * run out of ATIOS. 893 */ 894 xpt_print_path(tptr->owner); 895 printf("no ATIOS for lun %d from initiator %d\n", 896 aep->at_lun, aep->at_iid); 897 rls_lun_statep(isp, tptr); 898 if (aep->at_flags & AT_TQAE) 899 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0); 900 else 901 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 902 return (0); 903 } 904 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 905 if (tptr == &isp->isp_osinfo.tsdflt) { 906 atiop->ccb_h.target_id = aep->at_tgt; 907 atiop->ccb_h.target_lun = aep->at_lun; 908 } 909 if (aep->at_flags & AT_NODISC) { 910 xpt_print_path(tptr->owner); 911 printf("incoming command that cannot disconnect\n"); 912 } 913 914 915 atiop->init_id = aep->at_iid; 916 atiop->cdb_len = aep->at_cdblen; 917 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, aep->at_cdblen); 918 atiop->ccb_h.status = CAM_CDB_RECVD; 919 if ((atiop->tag_action = aep->at_tag_type) != 0) { 920 atiop->tag_id = aep->at_tag_val; 921 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; 922 } 923 xpt_done((union ccb*)atiop); 924 if (isp_tdebug > 1) { 925 printf("%s:ATIO CDB=0x%x iid%d->lun%d tag 0x%x ttype 0x%x\n", 926 isp->isp_name, aep->at_cdb[0] & 0xff, aep->at_iid, 927 aep->at_lun, aep->at_tag_val & 0xff, aep->at_tag_type); 928 } 929 rls_lun_statep(isp, tptr); 930 return (0); 931 } 932 933 static int 934 isp_handle_platform_atio2(struct ispsoftc *isp, at2_entry_t *aep) 935 { 936 lun_id_t lun; 937 tstate_t *tptr; 938 struct ccb_accept_tio *atiop; 939 940 /* 941 * The firmware status (except for the QLTM_SVALID bit) 942 * indicates why this ATIO was sent to us. 943 * 944 * If QLTM_SVALID is set, the firware has recommended Sense Data. 945 */ 946 if ((aep->at_status & ~QLTM_SVALID) != AT_CDB) { 947 printf("%s: bogus atio (0x%x) leaked to platform\n", 948 isp->isp_name, aep->at_status); 949 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 950 return (0); 951 } 952 953 #ifdef ISP2100_SCCLUN 954 lun = aep->at_scclun; 955 #else 956 lun = aep->at_lun; 957 #endif 958 tptr = get_lun_statep(isp, lun); 959 if (tptr == NULL) { 960 tptr = get_lun_statep(isp, CAM_LUN_WILDCARD); 961 } 962 963 if (tptr == NULL) { 964 #if 0 965 /* XXX WE REALLY NEED A HARDWIRED SENSE/INQ CTIO TO USE XXX */ 966 u_int32_t ccode = SCSI_STATUS_CHECK_COND | ECMD_SVALID; 967 #if NTARGBH > 0 968 /* Not Ready, Unit Not Self-Configured yet.... */ 969 ccode |= (SSD_KEY_NOT_READY << 8) | (0x3E << 24); 970 #else 971 /* Illegal Request, Unit Not Self-Configured yet.... */ 972 ccode |= (SSD_KEY_ILLEGAL_REQUEST << 8) | (0x25 << 24); 973 #endif 974 #else 975 u_int32_t ccode = SCSI_STATUS_BUSY; 976 #endif 977 978 /* 979 * Because we can't autofeed sense data back with 980 * a command for parallel SCSI, we can't give back 981 * a CHECK CONDITION. We'll give back a BUSY status 982 * instead. This works out okay because the only 983 * time we should, in fact, get this, is in the 984 * case that somebody configured us without the 985 * blackhole driver, so they get what they deserve. 986 */ 987 isp_endcmd(isp, aep, ccode, 0); 988 return (0); 989 } 990 991 atiop = (struct ccb_accept_tio *) SLIST_FIRST(&tptr->atios); 992 if (atiop == NULL) { 993 /* 994 * Because we can't autofeed sense data back with 995 * a command for parallel SCSI, we can't give back 996 * a CHECK CONDITION. We'll give back a QUEUE FULL status 997 * instead. This works out okay because the only time we 998 * should, in fact, get this, is in the case that we've 999 * run out of ATIOS. 1000 */ 1001 xpt_print_path(tptr->owner); 1002 printf("no ATIOS for lun %d from initiator %d\n", 1003 lun, aep->at_iid); 1004 rls_lun_statep(isp, tptr); 1005 if (aep->at_flags & AT_TQAE) 1006 isp_endcmd(isp, aep, SCSI_STATUS_QUEUE_FULL, 0); 1007 else 1008 isp_endcmd(isp, aep, SCSI_STATUS_BUSY, 0); 1009 return (0); 1010 } 1011 SLIST_REMOVE_HEAD(&tptr->atios, sim_links.sle); 1012 if (tptr == &isp->isp_osinfo.tsdflt) { 1013 atiop->ccb_h.target_id = 1014 ((fcparam *)isp->isp_param)->isp_loopid; 1015 atiop->ccb_h.target_lun = lun; 1016 } 1017 atiop->init_id = aep->at_iid; 1018 atiop->cdb_len = ATIO2_CDBLEN; 1019 MEMCPY(atiop->cdb_io.cdb_bytes, aep->at_cdb, ATIO2_CDBLEN); 1020 atiop->ccb_h.status = CAM_CDB_RECVD; 1021 atiop->tag_id = aep->at_rxid; 1022 switch (aep->at_taskflags & ATIO2_TC_ATTR_MASK) { 1023 case ATIO2_TC_ATTR_SIMPLEQ: 1024 atiop->tag_action = MSG_SIMPLE_Q_TAG; 1025 break; 1026 case ATIO2_TC_ATTR_HEADOFQ: 1027 atiop->tag_action = MSG_HEAD_OF_Q_TAG; 1028 break; 1029 case ATIO2_TC_ATTR_ORDERED: 1030 atiop->tag_action = MSG_ORDERED_Q_TAG; 1031 break; 1032 case ATIO2_TC_ATTR_ACAQ: /* ?? */ 1033 case ATIO2_TC_ATTR_UNTAGGED: 1034 default: 1035 atiop->tag_action = 0; 1036 break; 1037 } 1038 if (atiop->tag_action != 0) { 1039 atiop->ccb_h.status |= CAM_TAG_ACTION_VALID; 1040 } 1041 xpt_done((union ccb*)atiop); 1042 if (isp_tdebug > 1) { 1043 printf("%s:ATIO2 RX_ID 0x%x CDB=0x%x iid%d->lun%d tattr 0x%x\n", 1044 isp->isp_name, aep->at_rxid & 0xffff, aep->at_cdb[0] & 0xff, 1045 aep->at_iid, lun, aep->at_taskflags); 1046 } 1047 rls_lun_statep(isp, tptr); 1048 return (0); 1049 } 1050 1051 static int 1052 isp_handle_platform_ctio(struct ispsoftc *isp, void * arg) 1053 { 1054 union ccb *ccb; 1055 int sentstatus, ok; 1056 1057 /* 1058 * CTIO and CTIO2 are close enough.... 1059 */ 1060 1061 ccb = (union ccb *) isp_find_xs(isp, ((ct_entry_t *)arg)->ct_reserved); 1062 KASSERT((ccb != NULL), ("null ccb in isp_handle_platform_ctio")); 1063 isp_destroy_handle(isp, ((ct_entry_t *)arg)->ct_reserved); 1064 1065 if (IS_FC(isp)) { 1066 ct2_entry_t *ct = arg; 1067 sentstatus = ct->ct_flags & CT2_SENDSTATUS; 1068 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 1069 if (ok && ccb->ccb_h.flags & CAM_SEND_SENSE) { 1070 ccb->ccb_h.status |= CAM_SENT_SENSE; 1071 } 1072 if (isp_tdebug > 1) { 1073 printf("%s:CTIO2 RX_ID 0x%x sts 0x%x flg 0x%x sns " 1074 "%d FIN\n", isp->isp_name, ct->ct_rxid, 1075 ct->ct_status, ct->ct_flags, 1076 (ccb->ccb_h.status & CAM_SENT_SENSE) != 0); 1077 } 1078 } else { 1079 ct_entry_t *ct = arg; 1080 sentstatus = ct->ct_flags & CT_SENDSTATUS; 1081 ok = (ct->ct_status & ~QLTM_SVALID) == CT_OK; 1082 if (isp_tdebug > 1) { 1083 printf("%s:CTIO tag 0x%x sts 0x%x flg 0x%x FIN\n", 1084 isp->isp_name, ct->ct_tag_val, ct->ct_status, 1085 ct->ct_flags); 1086 } 1087 } 1088 1089 /* 1090 * We're here either because data transfers are done (and 1091 * it's time to send a final status CTIO) or because the final 1092 * status CTIO is done. We don't get called for all intermediate 1093 * CTIOs that happen for a large data transfer. 1094 * 1095 * In any case, for this platform, the upper layers figure out 1096 * what to do next, so all we do here is collect status and 1097 * pass information along. 1098 */ 1099 1100 if (sentstatus) { 1101 /* 1102 * Data transfer done. See if all went okay. 1103 */ 1104 if (ok) { 1105 ccb->csio.resid = 0; 1106 } else { 1107 ccb->csio.resid = ccb->csio.dxfer_len; 1108 } 1109 } 1110 1111 1112 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_INPROG) { 1113 ccb->ccb_h.status |= CAM_REQ_CMP; 1114 } 1115 ccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1116 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 1117 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 1118 if (isp->isp_osinfo.simqfrozen == 0) { 1119 if ((ccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1120 IDPRINTF(3, ("%s: isp_done -> relsimq\n", 1121 isp->isp_name)); 1122 ccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1123 } else { 1124 IDPRINTF(3, ("%s: isp_done -> devq frozen\n", 1125 isp->isp_name)); 1126 } 1127 } else { 1128 IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n", 1129 isp->isp_name, isp->isp_osinfo.simqfrozen)); 1130 } 1131 } 1132 xpt_done(ccb); 1133 return (0); 1134 } 1135 #endif 1136 1137 static void 1138 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg) 1139 { 1140 struct cam_sim *sim; 1141 struct ispsoftc *isp; 1142 1143 sim = (struct cam_sim *)cbarg; 1144 isp = (struct ispsoftc *) cam_sim_softc(sim); 1145 switch (code) { 1146 case AC_LOST_DEVICE: 1147 if (IS_SCSI(isp)) { 1148 u_int16_t oflags, nflags; 1149 sdparam *sdp = isp->isp_param; 1150 int s, rvf, tgt; 1151 1152 tgt = xpt_path_target_id(path); 1153 rvf = ISP_FW_REVX(isp->isp_fwrev); 1154 s = splcam(); 1155 sdp += cam_sim_bus(sim); 1156 isp->isp_update |= (1 << cam_sim_bus(sim)); 1157 nflags = DPARM_SAFE_DFLT; 1158 if (rvf >= ISP_FW_REV(7, 55, 0) || 1159 (ISP_FW_REV(4, 55, 0) <= rvf && 1160 (rvf < ISP_FW_REV(5, 0, 0)))) { 1161 nflags |= DPARM_NARROW | DPARM_ASYNC; 1162 } 1163 oflags = sdp->isp_devparam[tgt].dev_flags; 1164 sdp->isp_devparam[tgt].dev_flags = nflags; 1165 sdp->isp_devparam[tgt].dev_update = 1; 1166 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL); 1167 sdp->isp_devparam[tgt].dev_flags = oflags; 1168 (void) splx(s); 1169 } 1170 break; 1171 default: 1172 printf("%s: isp_attach Async Code 0x%x\n", isp->isp_name, code); 1173 break; 1174 } 1175 } 1176 1177 static void 1178 isp_poll(struct cam_sim *sim) 1179 { 1180 isp_intr((struct ispsoftc *) cam_sim_softc(sim)); 1181 } 1182 1183 static void 1184 isp_relsim(void *arg) 1185 { 1186 struct ispsoftc *isp = arg; 1187 int s = splcam(); 1188 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED) { 1189 int wasfrozen = isp->isp_osinfo.simqfrozen & SIMQFRZ_TIMED; 1190 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_TIMED; 1191 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { 1192 xpt_release_simq(isp->isp_sim, 1); 1193 IDPRINTF(3, ("%s: timed relsimq\n", isp->isp_name)); 1194 } 1195 } 1196 splx(s); 1197 } 1198 1199 static void 1200 isp_action(struct cam_sim *sim, union ccb *ccb) 1201 { 1202 int s, bus, tgt, error; 1203 struct ispsoftc *isp; 1204 struct ccb_trans_settings *cts; 1205 1206 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 1207 1208 isp = (struct ispsoftc *)cam_sim_softc(sim); 1209 ccb->ccb_h.sim_priv.entries[0].field = 0; 1210 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 1211 if (isp->isp_state != ISP_RUNSTATE && 1212 ccb->ccb_h.func_code == XPT_SCSI_IO) { 1213 s = splcam(); 1214 DISABLE_INTS(isp); 1215 isp_init(isp); 1216 if (isp->isp_state != ISP_INITSTATE) { 1217 (void) splx(s); 1218 /* 1219 * Lie. Say it was a selection timeout. 1220 */ 1221 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 1222 ccb->ccb_h.status |= CAM_DEV_QFRZN; 1223 xpt_freeze_devq(ccb->ccb_h.path, 1); 1224 xpt_done(ccb); 1225 return; 1226 } 1227 isp->isp_state = ISP_RUNSTATE; 1228 ENABLE_INTS(isp); 1229 (void) splx(s); 1230 } 1231 IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name, 1232 ccb->ccb_h.func_code)); 1233 1234 switch (ccb->ccb_h.func_code) { 1235 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 1236 /* 1237 * Do a couple of preliminary checks... 1238 */ 1239 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 1240 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 1241 ccb->ccb_h.status = CAM_REQ_INVALID; 1242 xpt_done(ccb); 1243 break; 1244 } 1245 } 1246 #ifdef DIAGNOSTIC 1247 if (ccb->ccb_h.target_id > (ISP_MAX_TARGETS(isp) - 1)) { 1248 ccb->ccb_h.status = CAM_PATH_INVALID; 1249 } else if (ccb->ccb_h.target_lun > (ISP_MAX_LUNS(isp) - 1)) { 1250 ccb->ccb_h.status = CAM_PATH_INVALID; 1251 } 1252 if (ccb->ccb_h.status == CAM_PATH_INVALID) { 1253 printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n", 1254 isp->isp_name, ccb->ccb_h.target_id, 1255 ccb->ccb_h.target_lun); 1256 xpt_done(ccb); 1257 break; 1258 } 1259 #endif 1260 ((struct ccb_scsiio *) ccb)->scsi_status = SCSI_STATUS_OK; 1261 s = splcam(); 1262 DISABLE_INTS(isp); 1263 error = ispscsicmd((ISP_SCSI_XFER_T *) ccb); 1264 ENABLE_INTS(isp); 1265 splx(s); 1266 switch (error) { 1267 case CMD_QUEUED: 1268 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1269 break; 1270 case CMD_RQLATER: 1271 if (isp->isp_osinfo.simqfrozen == 0) { 1272 IDPRINTF(3, ("%s: RQLATER freeze simq\n", 1273 isp->isp_name)); 1274 isp->isp_osinfo.simqfrozen |= SIMQFRZ_TIMED; 1275 timeout(isp_relsim, isp, 500); 1276 xpt_freeze_simq(sim, 1); 1277 } 1278 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1279 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1280 xpt_done(ccb); 1281 break; 1282 case CMD_EAGAIN: 1283 if (isp->isp_osinfo.simqfrozen == 0) { 1284 xpt_freeze_simq(sim, 1); 1285 IDPRINTF(3, ("%s: EAGAIN freeze simq\n", 1286 isp->isp_name)); 1287 } 1288 isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; 1289 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1290 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1291 xpt_done(ccb); 1292 break; 1293 case CMD_COMPLETE: 1294 isp_done((struct ccb_scsiio *) ccb); 1295 break; 1296 default: 1297 printf("%s: What's this? 0x%x at %d in file %s\n", 1298 isp->isp_name, error, __LINE__, __FILE__); 1299 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1300 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 1301 xpt_done(ccb); 1302 } 1303 break; 1304 1305 #ifdef ISP_TARGET_MODE 1306 case XPT_EN_LUN: /* Enable LUN as a target */ 1307 isp_en_lun(isp, ccb); 1308 xpt_done(ccb); 1309 break; 1310 1311 case XPT_NOTIFY_ACK: /* recycle notify ack */ 1312 xpt_print_path(ccb->ccb_h.path); 1313 printf("notify ack\n"); 1314 case XPT_IMMED_NOTIFY: /* Add Immediate Notify Resource */ 1315 case XPT_ACCEPT_TARGET_IO: /* Add Accept Target IO Resource */ 1316 { 1317 tstate_t *tptr = get_lun_statep(isp, ccb->ccb_h.target_lun); 1318 if (tptr == NULL) { 1319 ccb->ccb_h.status = CAM_LUN_INVALID; 1320 xpt_done(ccb); 1321 break; 1322 } 1323 s = splsoftcam(); 1324 if (ccb->ccb_h.func_code == XPT_ACCEPT_TARGET_IO) { 1325 SLIST_INSERT_HEAD(&tptr->atios, 1326 &ccb->ccb_h, sim_links.sle); 1327 } else { 1328 SLIST_INSERT_HEAD(&tptr->inots, &ccb->ccb_h, 1329 sim_links.sle); 1330 } 1331 splx(s); 1332 rls_lun_statep(isp, tptr); 1333 ccb->ccb_h.status = CAM_REQ_INPROG; 1334 break; 1335 } 1336 case XPT_CONT_TARGET_IO: 1337 { 1338 s = splcam(); 1339 ccb->ccb_h.status = isp_target_start_ctio(isp, ccb); 1340 if (ccb->ccb_h.status != CAM_REQ_INPROG) { 1341 if (isp->isp_osinfo.simqfrozen == 0) { 1342 xpt_freeze_simq(sim, 1); 1343 xpt_print_path(ccb->ccb_h.path); 1344 printf("XPT_CONT_TARGET_IO freeze simq\n"); 1345 } 1346 isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; 1347 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 1348 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 1349 xpt_done(ccb); 1350 } else { 1351 ccb->ccb_h.status |= CAM_SIM_QUEUED; 1352 } 1353 splx(s); 1354 break; 1355 } 1356 #endif 1357 case XPT_RESET_DEV: /* BDR the specified SCSI device */ 1358 1359 bus = cam_sim_bus(xpt_path_sim(ccb->ccb_h.path)); 1360 tgt = ccb->ccb_h.target_id; 1361 tgt |= (bus << 16); 1362 1363 s = splcam(); 1364 error = isp_control(isp, ISPCTL_RESET_DEV, &tgt); 1365 (void) splx(s); 1366 if (error) { 1367 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1368 } else { 1369 ccb->ccb_h.status = CAM_REQ_CMP; 1370 } 1371 xpt_done(ccb); 1372 break; 1373 case XPT_ABORT: /* Abort the specified CCB */ 1374 { 1375 union ccb *accb = ccb->cab.abort_ccb; 1376 switch (accb->ccb_h.func_code) { 1377 #ifdef ISP_TARGET_MODE 1378 case XPT_ACCEPT_TARGET_IO: 1379 case XPT_IMMED_NOTIFY: 1380 ccb->ccb_h.status = isp_abort_tgt_ccb(isp, ccb); 1381 break; 1382 case XPT_CONT_TARGET_IO: 1383 PRINTF("%s: cannot abort CTIOs yet\n", isp->isp_name); 1384 ccb->ccb_h.status = CAM_UA_ABORT; 1385 break; 1386 #endif 1387 case XPT_SCSI_IO: 1388 s = splcam(); 1389 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb); 1390 (void) splx(s); 1391 if (error) { 1392 ccb->ccb_h.status = CAM_UA_ABORT; 1393 } else { 1394 ccb->ccb_h.status = CAM_REQ_CMP; 1395 } 1396 break; 1397 default: 1398 ccb->ccb_h.status = CAM_REQ_INVALID; 1399 break; 1400 } 1401 xpt_done(ccb); 1402 break; 1403 } 1404 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */ 1405 1406 cts = &ccb->cts; 1407 tgt = cts->ccb_h.target_id; 1408 s = splcam(); 1409 if (IS_SCSI(isp)) { 1410 sdparam *sdp = isp->isp_param; 1411 u_int16_t *dptr; 1412 1413 bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 1414 1415 sdp += bus; 1416 #if 0 1417 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) 1418 dptr = &sdp->isp_devparam[tgt].cur_dflags; 1419 else 1420 dptr = &sdp->isp_devparam[tgt].dev_flags; 1421 #else 1422 /* 1423 * We always update (internally) from dev_flags 1424 * so any request to change settings just gets 1425 * vectored to that location. 1426 */ 1427 dptr = &sdp->isp_devparam[tgt].dev_flags; 1428 #endif 1429 1430 /* 1431 * Note that these operations affect the 1432 * the goal flags (dev_flags)- not 1433 * the current state flags. Then we mark 1434 * things so that the next operation to 1435 * this HBA will cause the update to occur. 1436 */ 1437 if (cts->valid & CCB_TRANS_DISC_VALID) { 1438 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) { 1439 *dptr |= DPARM_DISC; 1440 } else { 1441 *dptr &= ~DPARM_DISC; 1442 } 1443 } 1444 if (cts->valid & CCB_TRANS_TQ_VALID) { 1445 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) { 1446 *dptr |= DPARM_TQING; 1447 } else { 1448 *dptr &= ~DPARM_TQING; 1449 } 1450 } 1451 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) { 1452 switch (cts->bus_width) { 1453 case MSG_EXT_WDTR_BUS_16_BIT: 1454 *dptr |= DPARM_WIDE; 1455 break; 1456 default: 1457 *dptr &= ~DPARM_WIDE; 1458 } 1459 } 1460 /* 1461 * Any SYNC RATE of nonzero and SYNC_OFFSET 1462 * of nonzero will cause us to go to the 1463 * selected (from NVRAM) maximum value for 1464 * this device. At a later point, we'll 1465 * allow finer control. 1466 */ 1467 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) && 1468 (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) && 1469 (cts->sync_offset > 0)) { 1470 *dptr |= DPARM_SYNC; 1471 } else { 1472 *dptr &= ~DPARM_SYNC; 1473 } 1474 *dptr |= DPARM_SAFE_DFLT; 1475 if (bootverbose || isp->isp_dblev >= 3) 1476 printf("%s: %d.%d set %s period 0x%x offset " 1477 "0x%x flags 0x%x\n", isp->isp_name, bus, 1478 tgt, 1479 (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 1480 "current" : "user", 1481 sdp->isp_devparam[tgt].sync_period, 1482 sdp->isp_devparam[tgt].sync_offset, 1483 sdp->isp_devparam[tgt].dev_flags); 1484 sdp->isp_devparam[tgt].dev_update = 1; 1485 isp->isp_update |= (1 << bus); 1486 } 1487 (void) splx(s); 1488 ccb->ccb_h.status = CAM_REQ_CMP; 1489 xpt_done(ccb); 1490 break; 1491 1492 case XPT_GET_TRAN_SETTINGS: 1493 1494 cts = &ccb->cts; 1495 tgt = cts->ccb_h.target_id; 1496 if (IS_FC(isp)) { 1497 /* 1498 * a lot of normal SCSI things don't make sense. 1499 */ 1500 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB; 1501 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1502 /* 1503 * How do you measure the width of a high 1504 * speed serial bus? Well, in bytes. 1505 * 1506 * Offset and period make no sense, though, so we set 1507 * (above) a 'base' transfer speed to be gigabit. 1508 */ 1509 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1510 } else { 1511 sdparam *sdp = isp->isp_param; 1512 u_int16_t dval, pval, oval; 1513 int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 1514 1515 sdp += bus; 1516 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) { 1517 s = splcam(); 1518 sdp->isp_devparam[tgt].dev_refresh = 1; 1519 isp->isp_update |= (1 << bus); 1520 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, 1521 NULL); 1522 (void) splx(s); 1523 dval = sdp->isp_devparam[tgt].cur_dflags; 1524 oval = sdp->isp_devparam[tgt].cur_offset; 1525 pval = sdp->isp_devparam[tgt].cur_period; 1526 } else { 1527 dval = sdp->isp_devparam[tgt].dev_flags; 1528 oval = sdp->isp_devparam[tgt].sync_offset; 1529 pval = sdp->isp_devparam[tgt].sync_period; 1530 } 1531 1532 s = splcam(); 1533 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 1534 1535 if (dval & DPARM_DISC) { 1536 cts->flags |= CCB_TRANS_DISC_ENB; 1537 } 1538 if (dval & DPARM_TQING) { 1539 cts->flags |= CCB_TRANS_TAG_ENB; 1540 } 1541 if (dval & DPARM_WIDE) { 1542 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1543 } else { 1544 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1545 } 1546 cts->valid = CCB_TRANS_BUS_WIDTH_VALID | 1547 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1548 1549 if ((dval & DPARM_SYNC) && oval != 0) { 1550 cts->sync_period = pval; 1551 cts->sync_offset = oval; 1552 cts->valid |= 1553 CCB_TRANS_SYNC_RATE_VALID | 1554 CCB_TRANS_SYNC_OFFSET_VALID; 1555 } 1556 splx(s); 1557 if (bootverbose || isp->isp_dblev >= 3) 1558 printf("%s: %d.%d get %s period 0x%x offset " 1559 "0x%x flags 0x%x\n", isp->isp_name, bus, 1560 tgt, 1561 (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 1562 "current" : "user", pval, oval, dval); 1563 } 1564 ccb->ccb_h.status = CAM_REQ_CMP; 1565 xpt_done(ccb); 1566 break; 1567 1568 case XPT_CALC_GEOMETRY: 1569 { 1570 struct ccb_calc_geometry *ccg; 1571 u_int32_t secs_per_cylinder; 1572 u_int32_t size_mb; 1573 1574 ccg = &ccb->ccg; 1575 if (ccg->block_size == 0) { 1576 printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n", 1577 isp->isp_name, ccg->ccb_h.target_id, 1578 ccg->ccb_h.target_lun); 1579 ccb->ccb_h.status = CAM_REQ_INVALID; 1580 xpt_done(ccb); 1581 break; 1582 } 1583 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size); 1584 if (size_mb > 1024) { 1585 ccg->heads = 255; 1586 ccg->secs_per_track = 63; 1587 } else { 1588 ccg->heads = 64; 1589 ccg->secs_per_track = 32; 1590 } 1591 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1592 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1593 ccb->ccb_h.status = CAM_REQ_CMP; 1594 xpt_done(ccb); 1595 break; 1596 } 1597 case XPT_RESET_BUS: /* Reset the specified bus */ 1598 bus = cam_sim_bus(sim); 1599 s = splcam(); 1600 error = isp_control(isp, ISPCTL_RESET_BUS, &bus); 1601 (void) splx(s); 1602 if (error) 1603 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1604 else { 1605 if (cam_sim_bus(sim) && isp->isp_path2 != NULL) 1606 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 1607 else if (isp->isp_path != NULL) 1608 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 1609 ccb->ccb_h.status = CAM_REQ_CMP; 1610 } 1611 xpt_done(ccb); 1612 break; 1613 1614 case XPT_TERM_IO: /* Terminate the I/O process */ 1615 /* Does this need to be implemented? */ 1616 ccb->ccb_h.status = CAM_REQ_INVALID; 1617 xpt_done(ccb); 1618 break; 1619 1620 case XPT_PATH_INQ: /* Path routing inquiry */ 1621 { 1622 struct ccb_pathinq *cpi = &ccb->cpi; 1623 1624 cpi->version_num = 1; 1625 #ifdef ISP_TARGET_MODE 1626 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 1627 #else 1628 cpi->target_sprt = 0; 1629 #endif 1630 cpi->hba_eng_cnt = 0; 1631 cpi->max_target = ISP_MAX_TARGETS(isp) - 1; 1632 cpi->max_lun = ISP_MAX_LUNS(isp) - 1; 1633 cpi->bus_id = cam_sim_bus(sim); 1634 if (IS_FC(isp)) { 1635 cpi->hba_misc = PIM_NOBUSRESET; 1636 /* 1637 * Because our loop ID can shift from time to time, 1638 * make our initiator ID out of range of our bus. 1639 */ 1640 cpi->initiator_id = cpi->max_target + 1; 1641 1642 /* 1643 * Set base transfer capabilities for Fibre Channel. 1644 * Technically not correct because we don't know 1645 * what media we're running on top of- but we'll 1646 * look good if we always say 100MB/s. 1647 */ 1648 cpi->base_transfer_speed = 100000; 1649 cpi->hba_inquiry = PI_TAG_ABLE; 1650 } else { 1651 sdparam *sdp = isp->isp_param; 1652 sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path)); 1653 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 1654 cpi->hba_misc = 0; 1655 cpi->initiator_id = sdp->isp_initiator_id; 1656 cpi->base_transfer_speed = 3300; 1657 } 1658 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1659 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 1660 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1661 cpi->unit_number = cam_sim_unit(sim); 1662 cpi->ccb_h.status = CAM_REQ_CMP; 1663 xpt_done(ccb); 1664 break; 1665 } 1666 default: 1667 ccb->ccb_h.status = CAM_REQ_INVALID; 1668 xpt_done(ccb); 1669 break; 1670 } 1671 } 1672 1673 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 1674 void 1675 isp_done(struct ccb_scsiio *sccb) 1676 { 1677 struct ispsoftc *isp = XS_ISP(sccb); 1678 1679 if (XS_NOERR(sccb)) 1680 XS_SETERR(sccb, CAM_REQ_CMP); 1681 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 1682 sccb->ccb_h.status |= sccb->ccb_h.spriv_field0; 1683 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && 1684 (sccb->scsi_status != SCSI_STATUS_OK)) { 1685 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 1686 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && 1687 (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) { 1688 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; 1689 } else { 1690 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1691 } 1692 } 1693 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1694 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1695 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1696 sccb->ccb_h.status |= CAM_DEV_QFRZN; 1697 xpt_freeze_devq(sccb->ccb_h.path, 1); 1698 if (sccb->scsi_status != SCSI_STATUS_OK) 1699 IDPRINTF(3, ("%s: fdevq %d.%d %x %x\n", 1700 isp->isp_name, sccb->ccb_h.target_id, 1701 sccb->ccb_h.target_lun, sccb->ccb_h.status, 1702 sccb->scsi_status)); 1703 } 1704 } 1705 /* 1706 * If we were frozen waiting resources, clear that we were frozen 1707 * waiting for resources. If we are no longer frozen, and the devq 1708 * isn't frozen, mark the completing CCB to have the XPT layer 1709 * release the simq. 1710 */ 1711 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 1712 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 1713 if (isp->isp_osinfo.simqfrozen == 0) { 1714 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1715 IDPRINTF(3, ("%s: isp_done -> relsimq\n", 1716 isp->isp_name)); 1717 sccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1718 } else { 1719 IDPRINTF(3, ("%s: isp_done -> devq frozen\n", 1720 isp->isp_name)); 1721 } 1722 } else { 1723 IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n", 1724 isp->isp_name, isp->isp_osinfo.simqfrozen)); 1725 } 1726 } 1727 if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) && 1728 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1729 xpt_print_path(sccb->ccb_h.path); 1730 printf("cam completion status 0x%x\n", sccb->ccb_h.status); 1731 } 1732 xpt_done((union ccb *) sccb); 1733 } 1734 1735 int 1736 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg) 1737 { 1738 int bus, rv = 0; 1739 switch (cmd) { 1740 case ISPASYNC_NEW_TGT_PARAMS: 1741 { 1742 int flags, tgt; 1743 sdparam *sdp = isp->isp_param; 1744 struct ccb_trans_settings neg; 1745 struct cam_path *tmppath; 1746 1747 tgt = *((int *)arg); 1748 bus = (tgt >> 16) & 0xffff; 1749 tgt &= 0xffff; 1750 sdp += bus; 1751 if (xpt_create_path(&tmppath, NULL, 1752 cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim), 1753 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1754 xpt_print_path(isp->isp_path); 1755 printf("isp_async cannot make temp path for " 1756 "target %d bus %d\n", tgt, bus); 1757 rv = -1; 1758 break; 1759 } 1760 flags = sdp->isp_devparam[tgt].cur_dflags; 1761 neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1762 if (flags & DPARM_DISC) { 1763 neg.flags |= CCB_TRANS_DISC_ENB; 1764 } 1765 if (flags & DPARM_TQING) { 1766 neg.flags |= CCB_TRANS_TAG_ENB; 1767 } 1768 neg.valid |= CCB_TRANS_BUS_WIDTH_VALID; 1769 neg.bus_width = (flags & DPARM_WIDE)? 1770 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT; 1771 neg.sync_period = sdp->isp_devparam[tgt].cur_period; 1772 neg.sync_offset = sdp->isp_devparam[tgt].cur_offset; 1773 if (flags & DPARM_SYNC) { 1774 neg.valid |= 1775 CCB_TRANS_SYNC_RATE_VALID | 1776 CCB_TRANS_SYNC_OFFSET_VALID; 1777 } 1778 IDPRINTF(3, ("%s: NEW_TGT_PARAMS bus %d tgt %d period " 1779 "0x%x offset 0x%x flags 0x%x\n", isp->isp_name, 1780 bus, tgt, neg.sync_period, neg.sync_offset, flags)); 1781 xpt_setup_ccb(&neg.ccb_h, tmppath, 1); 1782 xpt_async(AC_TRANSFER_NEG, tmppath, &neg); 1783 xpt_free_path(tmppath); 1784 break; 1785 } 1786 case ISPASYNC_BUS_RESET: 1787 bus = *((int *)arg); 1788 printf("%s: SCSI bus reset on bus %d detected\n", 1789 isp->isp_name, bus); 1790 if (bus > 0 && isp->isp_path2) { 1791 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 1792 } else if (isp->isp_path) { 1793 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 1794 } 1795 break; 1796 case ISPASYNC_LOOP_DOWN: 1797 if (isp->isp_path) { 1798 if (isp->isp_osinfo.simqfrozen == 0) { 1799 IDPRINTF(3, ("%s: loop down freeze simq\n", 1800 isp->isp_name)); 1801 xpt_freeze_simq(isp->isp_sim, 1); 1802 } 1803 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN; 1804 } 1805 printf("%s: Loop DOWN\n", isp->isp_name); 1806 break; 1807 case ISPASYNC_LOOP_UP: 1808 if (isp->isp_path) { 1809 int wasfrozen = 1810 isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN; 1811 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN; 1812 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { 1813 xpt_release_simq(isp->isp_sim, 1); 1814 IDPRINTF(3, ("%s: loop up release simq\n", 1815 isp->isp_name)); 1816 } 1817 } 1818 printf("%s: Loop UP\n", isp->isp_name); 1819 break; 1820 case ISPASYNC_PDB_CHANGED: 1821 { 1822 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x " 1823 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n"; 1824 const static char *roles[4] = { 1825 "(none)", "Target", "Initiator", "Target/Initiator" 1826 }; 1827 char *ptr; 1828 fcparam *fcp = isp->isp_param; 1829 int tgt = *((int *) arg); 1830 struct lportdb *lp = &fcp->portdb[tgt]; 1831 1832 if (lp->valid) { 1833 ptr = "arrived"; 1834 } else { 1835 ptr = "disappeared"; 1836 } 1837 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid, 1838 roles[lp->roles & 0x3], ptr, 1839 (u_int32_t) (lp->port_wwn >> 32), 1840 (u_int32_t) (lp->port_wwn & 0xffffffffLL), 1841 (u_int32_t) (lp->node_wwn >> 32), 1842 (u_int32_t) (lp->node_wwn & 0xffffffffLL)); 1843 break; 1844 } 1845 case ISPASYNC_CHANGE_NOTIFY: 1846 printf("%s: Name Server Database Changed\n", isp->isp_name); 1847 break; 1848 #ifdef ISP2100_FABRIC 1849 case ISPASYNC_FABRIC_DEV: 1850 { 1851 int target; 1852 struct lportdb *lp; 1853 sns_scrsp_t *resp = (sns_scrsp_t *) arg; 1854 u_int32_t portid; 1855 u_int64_t wwn; 1856 fcparam *fcp = isp->isp_param; 1857 1858 rv = -1; 1859 1860 portid = 1861 (((u_int32_t) resp->snscb_port_id[0]) << 16) | 1862 (((u_int32_t) resp->snscb_port_id[1]) << 8) | 1863 (((u_int32_t) resp->snscb_port_id[2])); 1864 wwn = 1865 (((u_int64_t)resp->snscb_portname[0]) << 56) | 1866 (((u_int64_t)resp->snscb_portname[1]) << 48) | 1867 (((u_int64_t)resp->snscb_portname[2]) << 40) | 1868 (((u_int64_t)resp->snscb_portname[3]) << 32) | 1869 (((u_int64_t)resp->snscb_portname[4]) << 24) | 1870 (((u_int64_t)resp->snscb_portname[5]) << 16) | 1871 (((u_int64_t)resp->snscb_portname[6]) << 8) | 1872 (((u_int64_t)resp->snscb_portname[7])); 1873 printf("%s: type 0x%x@portid 0x%x 0x%08x%08x\n", isp->isp_name, 1874 resp->snscb_port_type, portid, 1875 ((u_int32_t) (wwn >> 32)), ((u_int32_t) wwn)); 1876 if (resp->snscb_port_type != 2) { 1877 rv = 0; 1878 break; 1879 } 1880 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) { 1881 lp = &fcp->portdb[target]; 1882 if (lp->port_wwn == wwn) 1883 break; 1884 } 1885 if (target < MAX_FC_TARG) { 1886 rv = 0; 1887 break; 1888 } 1889 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) { 1890 lp = &fcp->portdb[target]; 1891 if (lp->port_wwn == 0) 1892 break; 1893 } 1894 if (target == MAX_FC_TARG) { 1895 printf("%s: no more space for fabric devices\n", 1896 isp->isp_name); 1897 break; 1898 } 1899 lp->port_wwn = lp->node_wwn = wwn; 1900 lp->portid = portid; 1901 rv = 0; 1902 break; 1903 } 1904 #endif 1905 #ifdef ISP_TARGET_MODE 1906 case ISPASYNC_TARGET_MESSAGE: 1907 { 1908 tmd_msg_t *mp = arg; 1909 ITDEBUG(2, ("%s: bus %d iid %d tgt %d lun %d ttype %x tval %x" 1910 " msg[0]=0x%x\n", isp->isp_name, mp->nt_bus, 1911 (int) mp->nt_iid, (int) mp->nt_tgt, (int) mp->nt_lun, 1912 mp->nt_tagtype, mp->nt_tagval, mp->nt_msg[0])); 1913 break; 1914 } 1915 case ISPASYNC_TARGET_EVENT: 1916 { 1917 tmd_event_t *ep = arg; 1918 ITDEBUG(2, ("%s: bus %d event code 0x%x\n", isp->isp_name, 1919 ep->ev_bus, ep->ev_event)); 1920 break; 1921 } 1922 case ISPASYNC_TARGET_ACTION: 1923 switch (((isphdr_t *)arg)->rqs_entry_type) { 1924 default: 1925 printf("%s: event 0x%x for unhandled target action\n", 1926 isp->isp_name, ((isphdr_t *)arg)->rqs_entry_type); 1927 break; 1928 case RQSTYPE_ATIO: 1929 rv = isp_handle_platform_atio(isp, (at_entry_t *) arg); 1930 break; 1931 case RQSTYPE_ATIO2: 1932 rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg); 1933 break; 1934 case RQSTYPE_CTIO2: 1935 case RQSTYPE_CTIO: 1936 rv = isp_handle_platform_ctio(isp, arg); 1937 break; 1938 case RQSTYPE_ENABLE_LUN: 1939 case RQSTYPE_MODIFY_LUN: 1940 isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status); 1941 break; 1942 } 1943 break; 1944 #endif 1945 default: 1946 PRINTF("%s: unknown isp_async event %d\n", isp->isp_name, cmd); 1947 rv = -1; 1948 break; 1949 } 1950 return (rv); 1951 } 1952 1953 1954 /* 1955 * Locks are held before coming here. 1956 */ 1957 void 1958 isp_uninit(struct ispsoftc *isp) 1959 { 1960 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 1961 DISABLE_INTS(isp); 1962 } 1963