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 && 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 && 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) { 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) { 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) { 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) { 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 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL); 1487 } 1488 (void) splx(s); 1489 ccb->ccb_h.status = CAM_REQ_CMP; 1490 xpt_done(ccb); 1491 break; 1492 1493 case XPT_GET_TRAN_SETTINGS: 1494 1495 cts = &ccb->cts; 1496 tgt = cts->ccb_h.target_id; 1497 if (IS_FC(isp)) { 1498 /* 1499 * a lot of normal SCSI things don't make sense. 1500 */ 1501 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB; 1502 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1503 /* 1504 * How do you measure the width of a high 1505 * speed serial bus? Well, in bytes. 1506 * 1507 * Offset and period make no sense, though, so we set 1508 * (above) a 'base' transfer speed to be gigabit. 1509 */ 1510 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1511 } else { 1512 sdparam *sdp = isp->isp_param; 1513 u_int16_t dval, pval, oval; 1514 int bus = cam_sim_bus(xpt_path_sim(cts->ccb_h.path)); 1515 1516 sdp += bus; 1517 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) { 1518 s = splcam(); 1519 /* 1520 * First do a refresh to see if things 1521 * have changed recently! 1522 */ 1523 sdp->isp_devparam[tgt].dev_refresh = 1; 1524 isp->isp_update |= (1 << bus); 1525 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, 1526 NULL); 1527 (void) splx(s); 1528 dval = sdp->isp_devparam[tgt].cur_dflags; 1529 oval = sdp->isp_devparam[tgt].cur_offset; 1530 pval = sdp->isp_devparam[tgt].cur_period; 1531 } else { 1532 dval = sdp->isp_devparam[tgt].dev_flags; 1533 oval = sdp->isp_devparam[tgt].sync_offset; 1534 pval = sdp->isp_devparam[tgt].sync_period; 1535 } 1536 1537 s = splcam(); 1538 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 1539 1540 if (dval & DPARM_DISC) { 1541 cts->flags |= CCB_TRANS_DISC_ENB; 1542 } 1543 if (dval & DPARM_TQING) { 1544 cts->flags |= CCB_TRANS_TAG_ENB; 1545 } 1546 if (dval & DPARM_WIDE) { 1547 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 1548 } else { 1549 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 1550 } 1551 cts->valid = CCB_TRANS_BUS_WIDTH_VALID | 1552 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1553 1554 if ((dval & DPARM_SYNC) && oval != 0) { 1555 cts->sync_period = pval; 1556 cts->sync_offset = oval; 1557 cts->valid |= 1558 CCB_TRANS_SYNC_RATE_VALID | 1559 CCB_TRANS_SYNC_OFFSET_VALID; 1560 } 1561 splx(s); 1562 if (bootverbose || isp->isp_dblev >= 3) 1563 printf("%s: %d.%d get %s period 0x%x offset " 1564 "0x%x flags 0x%x\n", isp->isp_name, bus, 1565 tgt, 1566 (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 1567 "current" : "user", pval, oval, dval); 1568 } 1569 ccb->ccb_h.status = CAM_REQ_CMP; 1570 xpt_done(ccb); 1571 break; 1572 1573 case XPT_CALC_GEOMETRY: 1574 { 1575 struct ccb_calc_geometry *ccg; 1576 u_int32_t secs_per_cylinder; 1577 u_int32_t size_mb; 1578 1579 ccg = &ccb->ccg; 1580 if (ccg->block_size == 0) { 1581 printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n", 1582 isp->isp_name, ccg->ccb_h.target_id, 1583 ccg->ccb_h.target_lun); 1584 ccb->ccb_h.status = CAM_REQ_INVALID; 1585 xpt_done(ccb); 1586 break; 1587 } 1588 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size); 1589 if (size_mb > 1024) { 1590 ccg->heads = 255; 1591 ccg->secs_per_track = 63; 1592 } else { 1593 ccg->heads = 64; 1594 ccg->secs_per_track = 32; 1595 } 1596 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 1597 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 1598 ccb->ccb_h.status = CAM_REQ_CMP; 1599 xpt_done(ccb); 1600 break; 1601 } 1602 case XPT_RESET_BUS: /* Reset the specified bus */ 1603 bus = cam_sim_bus(sim); 1604 s = splcam(); 1605 error = isp_control(isp, ISPCTL_RESET_BUS, &bus); 1606 (void) splx(s); 1607 if (error) 1608 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 1609 else { 1610 if (cam_sim_bus(sim) && isp->isp_path2 != NULL) 1611 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 1612 else if (isp->isp_path != NULL) 1613 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 1614 ccb->ccb_h.status = CAM_REQ_CMP; 1615 } 1616 xpt_done(ccb); 1617 break; 1618 1619 case XPT_TERM_IO: /* Terminate the I/O process */ 1620 /* Does this need to be implemented? */ 1621 ccb->ccb_h.status = CAM_REQ_INVALID; 1622 xpt_done(ccb); 1623 break; 1624 1625 case XPT_PATH_INQ: /* Path routing inquiry */ 1626 { 1627 struct ccb_pathinq *cpi = &ccb->cpi; 1628 1629 cpi->version_num = 1; 1630 #ifdef ISP_TARGET_MODE 1631 cpi->target_sprt = PIT_PROCESSOR | PIT_DISCONNECT | PIT_TERM_IO; 1632 #else 1633 cpi->target_sprt = 0; 1634 #endif 1635 cpi->hba_eng_cnt = 0; 1636 cpi->max_target = ISP_MAX_TARGETS(isp) - 1; 1637 cpi->max_lun = ISP_MAX_LUNS(isp) - 1; 1638 cpi->bus_id = cam_sim_bus(sim); 1639 if (IS_FC(isp)) { 1640 cpi->hba_misc = PIM_NOBUSRESET; 1641 /* 1642 * Because our loop ID can shift from time to time, 1643 * make our initiator ID out of range of our bus. 1644 */ 1645 cpi->initiator_id = cpi->max_target + 1; 1646 1647 /* 1648 * Set base transfer capabilities for Fibre Channel. 1649 * Technically not correct because we don't know 1650 * what media we're running on top of- but we'll 1651 * look good if we always say 100MB/s. 1652 */ 1653 cpi->base_transfer_speed = 100000; 1654 cpi->hba_inquiry = PI_TAG_ABLE; 1655 } else { 1656 sdparam *sdp = isp->isp_param; 1657 sdp += cam_sim_bus(xpt_path_sim(cpi->ccb_h.path)); 1658 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 1659 cpi->hba_misc = 0; 1660 cpi->initiator_id = sdp->isp_initiator_id; 1661 cpi->base_transfer_speed = 3300; 1662 } 1663 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 1664 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 1665 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 1666 cpi->unit_number = cam_sim_unit(sim); 1667 cpi->ccb_h.status = CAM_REQ_CMP; 1668 xpt_done(ccb); 1669 break; 1670 } 1671 default: 1672 ccb->ccb_h.status = CAM_REQ_INVALID; 1673 xpt_done(ccb); 1674 break; 1675 } 1676 } 1677 1678 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 1679 void 1680 isp_done(struct ccb_scsiio *sccb) 1681 { 1682 struct ispsoftc *isp = XS_ISP(sccb); 1683 1684 if (XS_NOERR(sccb)) 1685 XS_SETERR(sccb, CAM_REQ_CMP); 1686 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 1687 sccb->ccb_h.status |= sccb->ccb_h.spriv_field0; 1688 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && 1689 (sccb->scsi_status != SCSI_STATUS_OK)) { 1690 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 1691 if ((sccb->scsi_status == SCSI_STATUS_CHECK_COND) && 1692 (sccb->ccb_h.status & CAM_AUTOSNS_VALID) == 0) { 1693 sccb->ccb_h.status |= CAM_AUTOSENSE_FAIL; 1694 } else { 1695 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 1696 } 1697 } 1698 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 1699 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1700 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1701 sccb->ccb_h.status |= CAM_DEV_QFRZN; 1702 xpt_freeze_devq(sccb->ccb_h.path, 1); 1703 if (sccb->scsi_status != SCSI_STATUS_OK) 1704 IDPRINTF(3, ("%s: fdevq %d.%d %x %x\n", 1705 isp->isp_name, sccb->ccb_h.target_id, 1706 sccb->ccb_h.target_lun, sccb->ccb_h.status, 1707 sccb->scsi_status)); 1708 } 1709 } 1710 /* 1711 * If we were frozen waiting resources, clear that we were frozen 1712 * waiting for resources. If we are no longer frozen, and the devq 1713 * isn't frozen, mark the completing CCB to have the XPT layer 1714 * release the simq. 1715 */ 1716 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 1717 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 1718 if (isp->isp_osinfo.simqfrozen == 0) { 1719 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 1720 IDPRINTF(3, ("%s: isp_done -> relsimq\n", 1721 isp->isp_name)); 1722 sccb->ccb_h.status |= CAM_RELEASE_SIMQ; 1723 } else { 1724 IDPRINTF(3, ("%s: isp_done -> devq frozen\n", 1725 isp->isp_name)); 1726 } 1727 } else { 1728 IDPRINTF(3, ("%s: isp_done -> simqfrozen = %x\n", 1729 isp->isp_name, isp->isp_osinfo.simqfrozen)); 1730 } 1731 } 1732 if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) && 1733 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 1734 xpt_print_path(sccb->ccb_h.path); 1735 printf("cam completion status 0x%x\n", sccb->ccb_h.status); 1736 } 1737 xpt_done((union ccb *) sccb); 1738 } 1739 1740 int 1741 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg) 1742 { 1743 int bus, rv = 0; 1744 switch (cmd) { 1745 case ISPASYNC_NEW_TGT_PARAMS: 1746 { 1747 int flags, tgt; 1748 sdparam *sdp = isp->isp_param; 1749 struct ccb_trans_settings neg; 1750 struct cam_path *tmppath; 1751 1752 tgt = *((int *)arg); 1753 bus = (tgt >> 16) & 0xffff; 1754 tgt &= 0xffff; 1755 sdp += bus; 1756 if (xpt_create_path(&tmppath, NULL, 1757 cam_sim_path(bus? isp->isp_sim2 : isp->isp_sim), 1758 tgt, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 1759 xpt_print_path(isp->isp_path); 1760 printf("isp_async cannot make temp path for " 1761 "target %d bus %d\n", tgt, bus); 1762 rv = -1; 1763 break; 1764 } 1765 flags = sdp->isp_devparam[tgt].cur_dflags; 1766 neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 1767 if (flags & DPARM_DISC) { 1768 neg.flags |= CCB_TRANS_DISC_ENB; 1769 } 1770 if (flags & DPARM_TQING) { 1771 neg.flags |= CCB_TRANS_TAG_ENB; 1772 } 1773 neg.valid |= CCB_TRANS_BUS_WIDTH_VALID; 1774 neg.bus_width = (flags & DPARM_WIDE)? 1775 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT; 1776 neg.sync_period = sdp->isp_devparam[tgt].cur_period; 1777 neg.sync_offset = sdp->isp_devparam[tgt].cur_offset; 1778 if (flags & DPARM_SYNC) { 1779 neg.valid |= 1780 CCB_TRANS_SYNC_RATE_VALID | 1781 CCB_TRANS_SYNC_OFFSET_VALID; 1782 } 1783 IDPRINTF(3, ("%s: NEW_TGT_PARAMS bus %d tgt %d period " 1784 "0x%x offset 0x%x flags 0x%x\n", isp->isp_name, 1785 bus, tgt, neg.sync_period, neg.sync_offset, flags)); 1786 xpt_setup_ccb(&neg.ccb_h, tmppath, 1); 1787 xpt_async(AC_TRANSFER_NEG, tmppath, &neg); 1788 xpt_free_path(tmppath); 1789 break; 1790 } 1791 case ISPASYNC_BUS_RESET: 1792 bus = *((int *)arg); 1793 printf("%s: SCSI bus reset on bus %d detected\n", 1794 isp->isp_name, bus); 1795 if (bus > 0 && isp->isp_path2) { 1796 xpt_async(AC_BUS_RESET, isp->isp_path2, NULL); 1797 } else if (isp->isp_path) { 1798 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 1799 } 1800 break; 1801 case ISPASYNC_LOOP_DOWN: 1802 if (isp->isp_path) { 1803 if (isp->isp_osinfo.simqfrozen == 0) { 1804 IDPRINTF(3, ("%s: loop down freeze simq\n", 1805 isp->isp_name)); 1806 xpt_freeze_simq(isp->isp_sim, 1); 1807 } 1808 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN; 1809 } 1810 printf("%s: Loop DOWN\n", isp->isp_name); 1811 break; 1812 case ISPASYNC_LOOP_UP: 1813 if (isp->isp_path) { 1814 int wasfrozen = 1815 isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN; 1816 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN; 1817 if (wasfrozen && isp->isp_osinfo.simqfrozen == 0) { 1818 xpt_release_simq(isp->isp_sim, 1); 1819 IDPRINTF(3, ("%s: loop up release simq\n", 1820 isp->isp_name)); 1821 } 1822 } 1823 printf("%s: Loop UP\n", isp->isp_name); 1824 break; 1825 case ISPASYNC_PDB_CHANGED: 1826 { 1827 const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x " 1828 "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n"; 1829 const static char *roles[4] = { 1830 "(none)", "Target", "Initiator", "Target/Initiator" 1831 }; 1832 char *ptr; 1833 fcparam *fcp = isp->isp_param; 1834 int tgt = *((int *) arg); 1835 struct lportdb *lp = &fcp->portdb[tgt]; 1836 1837 if (lp->valid) { 1838 ptr = "arrived"; 1839 } else { 1840 ptr = "disappeared"; 1841 } 1842 printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid, 1843 roles[lp->roles & 0x3], ptr, 1844 (u_int32_t) (lp->port_wwn >> 32), 1845 (u_int32_t) (lp->port_wwn & 0xffffffffLL), 1846 (u_int32_t) (lp->node_wwn >> 32), 1847 (u_int32_t) (lp->node_wwn & 0xffffffffLL)); 1848 break; 1849 } 1850 case ISPASYNC_CHANGE_NOTIFY: 1851 printf("%s: Name Server Database Changed\n", isp->isp_name); 1852 break; 1853 #ifdef ISP2100_FABRIC 1854 case ISPASYNC_FABRIC_DEV: 1855 { 1856 int target; 1857 struct lportdb *lp; 1858 sns_scrsp_t *resp = (sns_scrsp_t *) arg; 1859 u_int32_t portid; 1860 u_int64_t wwn; 1861 fcparam *fcp = isp->isp_param; 1862 1863 rv = -1; 1864 1865 portid = 1866 (((u_int32_t) resp->snscb_port_id[0]) << 16) | 1867 (((u_int32_t) resp->snscb_port_id[1]) << 8) | 1868 (((u_int32_t) resp->snscb_port_id[2])); 1869 wwn = 1870 (((u_int64_t)resp->snscb_portname[0]) << 56) | 1871 (((u_int64_t)resp->snscb_portname[1]) << 48) | 1872 (((u_int64_t)resp->snscb_portname[2]) << 40) | 1873 (((u_int64_t)resp->snscb_portname[3]) << 32) | 1874 (((u_int64_t)resp->snscb_portname[4]) << 24) | 1875 (((u_int64_t)resp->snscb_portname[5]) << 16) | 1876 (((u_int64_t)resp->snscb_portname[6]) << 8) | 1877 (((u_int64_t)resp->snscb_portname[7])); 1878 printf("%s: type 0x%x@portid 0x%x 0x%08x%08x\n", isp->isp_name, 1879 resp->snscb_port_type, portid, 1880 ((u_int32_t) (wwn >> 32)), ((u_int32_t) wwn)); 1881 if (resp->snscb_port_type != 2) { 1882 rv = 0; 1883 break; 1884 } 1885 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) { 1886 lp = &fcp->portdb[target]; 1887 if (lp->port_wwn == wwn) 1888 break; 1889 } 1890 if (target < MAX_FC_TARG) { 1891 rv = 0; 1892 break; 1893 } 1894 for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) { 1895 lp = &fcp->portdb[target]; 1896 if (lp->port_wwn == 0) 1897 break; 1898 } 1899 if (target == MAX_FC_TARG) { 1900 printf("%s: no more space for fabric devices\n", 1901 isp->isp_name); 1902 break; 1903 } 1904 lp->port_wwn = lp->node_wwn = wwn; 1905 lp->portid = portid; 1906 rv = 0; 1907 break; 1908 } 1909 #endif 1910 #ifdef ISP_TARGET_MODE 1911 case ISPASYNC_TARGET_MESSAGE: 1912 { 1913 tmd_msg_t *mp = arg; 1914 ITDEBUG(1, ("%s: bus %d iid %d tgt %d lun %d ttype %x tval %x" 1915 " msg[0]=0x%x\n", isp->isp_name, mp->nt_bus, 1916 (int) mp->nt_iid, (int) mp->nt_tgt, (int) mp->nt_lun, 1917 mp->nt_tagtype, mp->nt_tagval, mp->nt_msg[0])); 1918 break; 1919 } 1920 case ISPASYNC_TARGET_EVENT: 1921 { 1922 tmd_event_t *ep = arg; 1923 ITDEBUG(1, ("%s: bus %d event code 0x%x\n", isp->isp_name, 1924 ep->ev_bus, ep->ev_event)); 1925 break; 1926 } 1927 case ISPASYNC_TARGET_ACTION: 1928 switch (((isphdr_t *)arg)->rqs_entry_type) { 1929 default: 1930 printf("%s: event 0x%x for unhandled target action\n", 1931 isp->isp_name, ((isphdr_t *)arg)->rqs_entry_type); 1932 break; 1933 case RQSTYPE_ATIO: 1934 rv = isp_handle_platform_atio(isp, (at_entry_t *) arg); 1935 break; 1936 case RQSTYPE_ATIO2: 1937 rv = isp_handle_platform_atio2(isp, (at2_entry_t *)arg); 1938 break; 1939 case RQSTYPE_CTIO2: 1940 case RQSTYPE_CTIO: 1941 rv = isp_handle_platform_ctio(isp, arg); 1942 break; 1943 case RQSTYPE_ENABLE_LUN: 1944 case RQSTYPE_MODIFY_LUN: 1945 isp_cv_signal_rqe(isp, ((lun_entry_t *)arg)->le_status); 1946 break; 1947 } 1948 break; 1949 #endif 1950 default: 1951 PRINTF("%s: unknown isp_async event %d\n", isp->isp_name, cmd); 1952 rv = -1; 1953 break; 1954 } 1955 return (rv); 1956 } 1957 1958 1959 /* 1960 * Locks are held before coming here. 1961 */ 1962 void 1963 isp_uninit(struct ispsoftc *isp) 1964 { 1965 ISP_WRITE(isp, HCCR, HCCR_CMD_RESET); 1966 DISABLE_INTS(isp); 1967 } 1968