1 /* $Id: isp_freebsd.c,v 1.15 1999/04/04 01:35:03 mjacob Exp $ */ 2 /* release_4_3_99 */ 3 /* 4 * Platform (FreeBSD) dependent common attachment code for Qlogic adapters. 5 * 6 *--------------------------------------- 7 * Copyright (c) 1997, 1998 by Matthew Jacob 8 * NASA/Ames Research Center 9 * All rights reserved. 10 *--------------------------------------- 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice immediately at the beginning of the file, without modification, 17 * this list of conditions, and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. The name of the author may not be used to endorse or promote products 22 * derived from this software without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 28 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 #include <dev/isp/isp_freebsd.h> 37 38 #if __FreeBSD_version >= 300004 39 40 static void isp_cam_async __P((void *, u_int32_t, struct cam_path *, void *)); 41 static void isp_poll __P((struct cam_sim *)); 42 static void isp_action __P((struct cam_sim *, union ccb *)); 43 44 void 45 isp_attach(struct ispsoftc *isp) 46 { 47 struct ccb_setasync csa; 48 struct cam_devq *devq; 49 50 /* 51 * Create the device queue for our SIM. 52 */ 53 devq = cam_simq_alloc(MAXISPREQUEST); 54 if (devq == NULL) { 55 return; 56 } 57 58 /* 59 * Construct our SIM entry 60 */ 61 isp->isp_sim = cam_sim_alloc(isp_action, isp_poll, "isp", isp, 62 isp->isp_unit, 1, MAXISPREQUEST, devq); 63 if (isp->isp_sim == NULL) { 64 cam_simq_free(devq); 65 return; 66 } 67 if (xpt_bus_register(isp->isp_sim, 0) != CAM_SUCCESS) { 68 cam_sim_free(isp->isp_sim, TRUE); 69 return; 70 } 71 72 if (xpt_create_path(&isp->isp_path, NULL, cam_sim_path(isp->isp_sim), 73 CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 74 xpt_bus_deregister(cam_sim_path(isp->isp_sim)); 75 cam_sim_free(isp->isp_sim, TRUE); 76 return; 77 } 78 79 xpt_setup_ccb(&csa.ccb_h, isp->isp_path, 5); 80 csa.ccb_h.func_code = XPT_SASYNC_CB; 81 csa.event_enable = AC_LOST_DEVICE; 82 csa.callback = isp_cam_async; 83 csa.callback_arg = isp->isp_sim; 84 xpt_action((union ccb *)&csa); 85 86 /* 87 * Set base transfer capabilities for Fibre Channel. 88 * Technically not correct because we don't know 89 * what media we're running on top of- but we'll 90 * look good if we always say 100MB/s. 91 */ 92 if (isp->isp_type & ISP_HA_FC) { 93 isp->isp_sim->base_transfer_speed = 100000; 94 } 95 if (isp->isp_state == ISP_INITSTATE) 96 isp->isp_state = ISP_RUNSTATE; 97 } 98 99 static void 100 isp_cam_async(void *cbarg, u_int32_t code, struct cam_path *path, void *arg) 101 { 102 struct cam_sim *sim; 103 struct ispsoftc *isp; 104 105 sim = (struct cam_sim *)cbarg; 106 isp = (struct ispsoftc *) cam_sim_softc(sim); 107 switch (code) { 108 case AC_LOST_DEVICE: 109 if (isp->isp_type & ISP_HA_SCSI) { 110 u_int16_t oflags, nflags; 111 sdparam *sdp = isp->isp_param; 112 int s, tgt = xpt_path_target_id(path); 113 114 nflags = DPARM_SAFE_DFLT; 115 if (ISP_FW_REVX(isp->isp_fwrev) >= 116 ISP_FW_REV(7, 55, 0)) { 117 nflags |= DPARM_NARROW | DPARM_ASYNC; 118 } 119 oflags = sdp->isp_devparam[tgt].dev_flags; 120 sdp->isp_devparam[tgt].dev_flags = nflags; 121 sdp->isp_devparam[tgt].dev_update = 1; 122 123 s = splcam(); 124 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL); 125 (void) splx(s); 126 sdp->isp_devparam[tgt].dev_flags = oflags; 127 } 128 break; 129 default: 130 break; 131 } 132 } 133 134 static void 135 isp_poll(struct cam_sim *sim) 136 { 137 isp_intr((struct ispsoftc *) cam_sim_softc(sim)); 138 } 139 140 141 static void 142 isp_action(struct cam_sim *sim, union ccb *ccb) 143 { 144 int s, tgt, error; 145 struct ispsoftc *isp; 146 struct ccb_trans_settings *cts; 147 148 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("isp_action\n")); 149 150 isp = (struct ispsoftc *)cam_sim_softc(sim); 151 ccb->ccb_h.sim_priv.entries[0].field = 0; 152 ccb->ccb_h.sim_priv.entries[1].ptr = isp; 153 /* 154 * This should only happen for Fibre Channel adapters. 155 * We want to pass through all but XPT_SCSI_IO (e.g., 156 * path inquiry) but fail if we can't get good Fibre 157 * Channel link status. 158 */ 159 if (ccb->ccb_h.func_code == XPT_SCSI_IO && 160 isp->isp_state != ISP_RUNSTATE) { 161 s = splcam(); 162 DISABLE_INTS(isp); 163 isp_init(isp); 164 if (isp->isp_state != ISP_INITSTATE) { 165 (void) splx(s); 166 /* 167 * Lie. Say it was a selection timeout. 168 */ 169 ccb->ccb_h.status = CAM_SEL_TIMEOUT; 170 xpt_done(ccb); 171 return; 172 } 173 isp->isp_state = ISP_RUNSTATE; 174 ENABLE_INTS(isp); 175 (void) splx(s); 176 } 177 178 IDPRINTF(4, ("%s: isp_action code %x\n", isp->isp_name, 179 ccb->ccb_h.func_code)); 180 181 switch (ccb->ccb_h.func_code) { 182 case XPT_SCSI_IO: /* Execute the requested I/O operation */ 183 /* 184 * Do a couple of preliminary checks... 185 */ 186 if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { 187 if ((ccb->ccb_h.flags & CAM_CDB_PHYS) != 0) { 188 ccb->ccb_h.status = CAM_REQ_INVALID; 189 xpt_done(ccb); 190 break; 191 } 192 } 193 194 195 if (isp->isp_type & ISP_HA_SCSI) { 196 if (ccb->ccb_h.target_id > (MAX_TARGETS-1)) { 197 ccb->ccb_h.status = CAM_PATH_INVALID; 198 } else if (ISP_FW_REVX(isp->isp_fwrev) >= 199 ISP_FW_REV(7, 55, 0)) { 200 /* 201 * Too much breakage. 202 */ 203 #if 0 204 if (ccb->ccb_h.target_lun > 31) { 205 ccb->ccb_h.status = CAM_PATH_INVALID; 206 } 207 #else 208 if (ccb->ccb_h.target_lun > 7) { 209 ccb->ccb_h.status = CAM_PATH_INVALID; 210 } 211 #endif 212 } else if (ccb->ccb_h.target_lun > 7) { 213 ccb->ccb_h.status = CAM_PATH_INVALID; 214 } 215 } else { 216 if (ccb->ccb_h.target_id > (MAX_FC_TARG-1)) { 217 ccb->ccb_h.status = CAM_PATH_INVALID; 218 #ifdef SCCLUN 219 } else if (ccb->ccb_h.target_lun > 15) { 220 ccb->ccb_h.status = CAM_PATH_INVALID; 221 #else 222 } else if (ccb->ccb_h.target_lun > 65535) { 223 ccb->ccb_h.status = CAM_PATH_INVALID; 224 #endif 225 } 226 } 227 if (ccb->ccb_h.status == CAM_PATH_INVALID) { 228 printf("%s: invalid tgt/lun (%d.%d) in XPT_SCSI_IO\n", 229 isp->isp_name, ccb->ccb_h.target_id, 230 ccb->ccb_h.target_lun); 231 xpt_done(ccb); 232 break; 233 } 234 235 CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_INFO, 236 ("cdb[0]=0x%x dlen%d\n", 237 (ccb->ccb_h.flags & CAM_CDB_POINTER)? 238 ccb->csio.cdb_io.cdb_ptr[0]: 239 ccb->csio.cdb_io.cdb_bytes[0], ccb->csio.dxfer_len)); 240 241 s = splcam(); 242 DISABLE_INTS(isp); 243 switch (ispscsicmd((ISP_SCSI_XFER_T *) ccb)) { 244 case CMD_QUEUED: 245 ccb->ccb_h.status |= CAM_SIM_QUEUED; 246 break; 247 case CMD_EAGAIN: 248 if (!(isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE)) { 249 xpt_freeze_simq(sim, 1); 250 isp->isp_osinfo.simqfrozen |= SIMQFRZ_RESOURCE; 251 } 252 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 253 ccb->ccb_h.status |= CAM_REQUEUE_REQ; 254 xpt_done(ccb); 255 break; 256 case CMD_COMPLETE: 257 /* 258 * Just make sure that we didn't get it returned 259 * as completed, but with the request still in 260 * progress. In theory, 'cannot happen'. 261 */ 262 if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 263 CAM_REQ_INPROG) { 264 ccb->ccb_h.status &= ~CAM_STATUS_MASK; 265 ccb->ccb_h.status |= CAM_REQ_CMP_ERR; 266 } 267 xpt_done(ccb); 268 break; 269 } 270 ENABLE_INTS(isp); 271 splx(s); 272 break; 273 274 case XPT_EN_LUN: /* Enable LUN as a target */ 275 case XPT_TARGET_IO: /* Execute target I/O request */ 276 case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ 277 case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ 278 ccb->ccb_h.status = CAM_REQ_INVALID; 279 xpt_done(ccb); 280 break; 281 282 case XPT_RESET_DEV: /* BDR the specified SCSI device */ 283 tgt = ccb->ccb_h.target_id; 284 s = splcam(); 285 error = 286 isp_control(isp, ISPCTL_RESET_DEV, (void *)(intptr_t) tgt); 287 (void) splx(s); 288 if (error) { 289 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 290 } else { 291 ccb->ccb_h.status = CAM_REQ_CMP; 292 } 293 xpt_done(ccb); 294 break; 295 case XPT_ABORT: /* Abort the specified CCB */ 296 s = splcam(); 297 error = isp_control(isp, ISPCTL_ABORT_CMD, ccb); 298 (void) splx(s); 299 if (error) { 300 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 301 } else { 302 ccb->ccb_h.status = CAM_REQ_CMP; 303 } 304 xpt_done(ccb); 305 break; 306 307 case XPT_SET_TRAN_SETTINGS: /* Nexus Settings */ 308 309 cts = &ccb->cts; 310 tgt = cts->ccb_h.target_id; 311 s = splcam(); 312 if (isp->isp_type & ISP_HA_FC) { 313 ; /* nothing to change */ 314 } else { 315 sdparam *sdp = isp->isp_param; 316 u_int16_t *dptr; 317 318 #if 0 319 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) 320 dptr = &sdp->isp_devparam[tgt].cur_dflags; 321 else 322 dptr = &sdp->isp_devparam[tgt].dev_flags; 323 #else 324 /* 325 * We always update (internally) from dev_flags 326 * so any request to change settings just gets 327 * vectored to that location. 328 */ 329 dptr = &sdp->isp_devparam[tgt].dev_flags; 330 #endif 331 332 /* 333 * Note that these operations affect the 334 * the goal flags (dev_flags)- not 335 * the current state flags. Then we mark 336 * things so that the next operation to 337 * this HBA will cause the update to occur. 338 */ 339 if (cts->valid & CCB_TRANS_DISC_VALID) { 340 if ((cts->flags & CCB_TRANS_DISC_ENB) != 0) { 341 *dptr |= DPARM_DISC; 342 } else { 343 *dptr &= ~DPARM_DISC; 344 } 345 } 346 if (cts->valid & CCB_TRANS_TQ_VALID) { 347 if ((cts->flags & CCB_TRANS_TAG_ENB) != 0) { 348 *dptr |= DPARM_TQING; 349 } else { 350 *dptr &= ~DPARM_TQING; 351 } 352 } 353 if (cts->valid & CCB_TRANS_BUS_WIDTH_VALID) { 354 switch (cts->bus_width) { 355 case MSG_EXT_WDTR_BUS_16_BIT: 356 *dptr |= DPARM_WIDE; 357 break; 358 default: 359 *dptr &= ~DPARM_WIDE; 360 } 361 } 362 /* 363 * Any SYNC RATE of nonzero and SYNC_OFFSET 364 * of nonzero will cause us to go to the 365 * selected (from NVRAM) maximum value for 366 * this device. At a later point, we'll 367 * allow finer control. 368 */ 369 if ((cts->valid & CCB_TRANS_SYNC_RATE_VALID) && 370 (cts->valid & CCB_TRANS_SYNC_OFFSET_VALID) && 371 (cts->sync_offset > 0)) { 372 *dptr |= DPARM_SYNC; 373 } else { 374 *dptr &= ~DPARM_SYNC; 375 } 376 IDPRINTF(3, ("%s: %d set %s period 0x%x offset 0x%x" 377 " flags 0x%x\n", isp->isp_name, tgt, 378 (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 379 "current" : "user", 380 sdp->isp_devparam[tgt].sync_period, 381 sdp->isp_devparam[tgt].sync_offset, 382 sdp->isp_devparam[tgt].dev_flags)); 383 s = splcam(); 384 sdp->isp_devparam[tgt].dev_update = 1; 385 isp->isp_update = 1; 386 (void) isp_control(isp, ISPCTL_UPDATE_PARAMS, NULL); 387 (void) splx(s); 388 } 389 (void) splx(s); 390 ccb->ccb_h.status = CAM_REQ_CMP; 391 xpt_done(ccb); 392 break; 393 394 case XPT_GET_TRAN_SETTINGS: 395 396 cts = &ccb->cts; 397 tgt = cts->ccb_h.target_id; 398 if (isp->isp_type & ISP_HA_FC) { 399 /* 400 * a lot of normal SCSI things don't make sense. 401 */ 402 cts->flags = CCB_TRANS_TAG_ENB | CCB_TRANS_DISC_ENB; 403 cts->valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 404 /* 405 * How do you measure the width of a high 406 * speed serial bus? Well, in bytes. 407 * 408 * Offset and period make no sense, though, so we set 409 * (above) a 'base' transfer speed to be gigabit. 410 */ 411 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 412 } else { 413 sdparam *sdp = isp->isp_param; 414 u_int16_t dval, pval, oval; 415 416 if (cts->flags & CCB_TRANS_CURRENT_SETTINGS) { 417 dval = sdp->isp_devparam[tgt].cur_dflags; 418 oval = sdp->isp_devparam[tgt].cur_offset; 419 pval = sdp->isp_devparam[tgt].cur_period; 420 } else { 421 dval = sdp->isp_devparam[tgt].dev_flags; 422 oval = sdp->isp_devparam[tgt].sync_offset; 423 pval = sdp->isp_devparam[tgt].sync_period; 424 } 425 426 s = splcam(); 427 cts->flags &= ~(CCB_TRANS_DISC_ENB|CCB_TRANS_TAG_ENB); 428 429 if (dval & DPARM_DISC) { 430 cts->flags |= CCB_TRANS_DISC_ENB; 431 } 432 if (dval & DPARM_TQING) { 433 cts->flags |= CCB_TRANS_TAG_ENB; 434 } 435 if (dval & DPARM_WIDE) { 436 cts->bus_width = MSG_EXT_WDTR_BUS_16_BIT; 437 } else { 438 cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; 439 } 440 cts->valid = CCB_TRANS_BUS_WIDTH_VALID | 441 CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 442 443 if ((dval & DPARM_SYNC) && oval != 0) { 444 cts->sync_period = pval; 445 cts->sync_offset = oval; 446 cts->valid |= 447 CCB_TRANS_SYNC_RATE_VALID | 448 CCB_TRANS_SYNC_OFFSET_VALID; 449 } 450 splx(s); 451 IDPRINTF(3, ("%s: %d get %s period 0x%x offset 0x%x" 452 " flags 0x%x\n", isp->isp_name, tgt, 453 (cts->flags & CCB_TRANS_CURRENT_SETTINGS)? 454 "current" : "user", pval, oval, dval)); 455 } 456 ccb->ccb_h.status = CAM_REQ_CMP; 457 xpt_done(ccb); 458 break; 459 460 case XPT_CALC_GEOMETRY: 461 { 462 struct ccb_calc_geometry *ccg; 463 u_int32_t secs_per_cylinder; 464 u_int32_t size_mb; 465 466 ccg = &ccb->ccg; 467 if (ccg->block_size == 0) { 468 printf("%s: %d.%d XPT_CALC_GEOMETRY block size 0?\n", 469 isp->isp_name, ccg->ccb_h.target_id, 470 ccg->ccb_h.target_lun); 471 ccb->ccb_h.status = CAM_REQ_INVALID; 472 xpt_done(ccb); 473 break; 474 } 475 size_mb = ccg->volume_size /((1024L * 1024L) / ccg->block_size); 476 if (size_mb > 1024) { 477 ccg->heads = 255; 478 ccg->secs_per_track = 63; 479 } else { 480 ccg->heads = 64; 481 ccg->secs_per_track = 32; 482 } 483 secs_per_cylinder = ccg->heads * ccg->secs_per_track; 484 ccg->cylinders = ccg->volume_size / secs_per_cylinder; 485 ccb->ccb_h.status = CAM_REQ_CMP; 486 xpt_done(ccb); 487 break; 488 } 489 case XPT_RESET_BUS: /* Reset the specified bus */ 490 s = splcam(); 491 error = isp_control(isp, ISPCTL_RESET_BUS, NULL); 492 (void) splx(s); 493 if (error) 494 ccb->ccb_h.status = CAM_REQ_CMP_ERR; 495 else { 496 if (isp->isp_path != NULL) 497 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 498 ccb->ccb_h.status = CAM_REQ_CMP; 499 } 500 xpt_done(ccb); 501 break; 502 503 case XPT_TERM_IO: /* Terminate the I/O process */ 504 /* Does this need to be implemented? */ 505 ccb->ccb_h.status = CAM_REQ_INVALID; 506 xpt_done(ccb); 507 break; 508 509 case XPT_PATH_INQ: /* Path routing inquiry */ 510 { 511 struct ccb_pathinq *cpi = &ccb->cpi; 512 513 cpi->version_num = 1; 514 cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE|PI_WIDE_16; 515 cpi->target_sprt = 0; 516 cpi->hba_eng_cnt = 0; 517 if (IS_FC(isp)) { 518 cpi->hba_misc = PIM_NOBUSRESET; 519 cpi->max_target = MAX_FC_TARG-1; 520 cpi->initiator_id = 521 ((fcparam *)isp->isp_param)->isp_loopid; 522 #ifdef SCCLUN 523 cpi->max_lun = (1 << 16) - 1; 524 #else 525 cpi->max_lun = (1 << 4) - 1; 526 #endif 527 } else { 528 cpi->hba_misc = 0; 529 cpi->initiator_id = 530 ((sdparam *)isp->isp_param)->isp_initiator_id; 531 cpi->max_target = MAX_TARGETS-1; 532 if (ISP_FW_REVX(isp->isp_fwrev) >= 533 ISP_FW_REV(7, 55, 0)) { 534 #if 0 535 /* 536 * Too much breakage. 537 */ 538 cpi->max_lun = (1 << 5) - 1; 539 #else 540 cpi->max_lun = (1 << 3) - 1; 541 #endif 542 } else { 543 cpi->max_lun = (1 << 3) - 1; 544 } 545 } 546 547 cpi->bus_id = cam_sim_bus(sim); 548 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); 549 strncpy(cpi->hba_vid, "Qlogic", HBA_IDLEN); 550 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); 551 cpi->unit_number = cam_sim_unit(sim); 552 cpi->ccb_h.status = CAM_REQ_CMP; 553 xpt_done(ccb); 554 break; 555 } 556 default: 557 ccb->ccb_h.status = CAM_REQ_INVALID; 558 xpt_done(ccb); 559 break; 560 } 561 } 562 563 #define ISPDDB (CAM_DEBUG_INFO|CAM_DEBUG_TRACE|CAM_DEBUG_CDB) 564 void 565 isp_done(struct ccb_scsiio *sccb) 566 { 567 struct ispsoftc *isp = XS_ISP(sccb); 568 569 if (XS_NOERR(sccb)) 570 XS_SETERR(sccb, CAM_REQ_CMP); 571 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 572 sccb->ccb_h.status |= sccb->ccb_h.spriv_field0; 573 if ((sccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && 574 (sccb->scsi_status != SCSI_STATUS_OK)) { 575 sccb->ccb_h.status &= ~CAM_STATUS_MASK; 576 sccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR; 577 } 578 if ((sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 579 if ((sccb->ccb_h.status & CAM_DEV_QFRZN) == 0) { 580 IDPRINTF(3, ("%s: freeze devq %d.%d ccbstat 0x%x\n", 581 isp->isp_name, sccb->ccb_h.target_id, 582 sccb->ccb_h.target_lun, sccb->ccb_h.status)); 583 xpt_freeze_devq(sccb->ccb_h.path, 1); 584 sccb->ccb_h.status |= CAM_DEV_QFRZN; 585 } 586 } 587 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_RESOURCE) { 588 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_RESOURCE; 589 sccb->ccb_h.status |= CAM_RELEASE_SIMQ; 590 xpt_release_simq(isp->isp_sim, 1); 591 } 592 sccb->ccb_h.status &= ~CAM_SIM_QUEUED; 593 if (CAM_DEBUGGED(sccb->ccb_h.path, ISPDDB) && 594 (sccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 595 xpt_print_path(sccb->ccb_h.path); 596 printf("cam completion status 0x%x\n", sccb->ccb_h.status); 597 } 598 xpt_done((union ccb *) sccb); 599 } 600 601 int 602 isp_async(isp, cmd, arg) 603 struct ispsoftc *isp; 604 ispasync_t cmd; 605 void *arg; 606 { 607 int rv = 0; 608 switch (cmd) { 609 case ISPASYNC_NEW_TGT_PARAMS: 610 if (isp->isp_type & ISP_HA_SCSI) { 611 int flags, tgt; 612 sdparam *sdp = isp->isp_param; 613 struct ccb_trans_settings neg; 614 struct cam_path *tmppath; 615 616 tgt = *((int *)arg); 617 if (xpt_create_path(&tmppath, NULL, 618 cam_sim_path(isp->isp_sim), tgt, 619 CAM_LUN_WILDCARD) != CAM_REQ_CMP) { 620 xpt_print_path(isp->isp_path); 621 printf("isp_async cannot make temp path for " 622 "target %d\n", tgt); 623 rv = -1; 624 break; 625 } 626 627 flags = sdp->isp_devparam[tgt].cur_dflags; 628 neg.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID; 629 if (flags & DPARM_DISC) { 630 neg.flags |= CCB_TRANS_DISC_ENB; 631 } 632 if (flags & DPARM_TQING) { 633 neg.flags |= CCB_TRANS_TAG_ENB; 634 } 635 neg.valid |= CCB_TRANS_BUS_WIDTH_VALID; 636 neg.bus_width = (flags & DPARM_WIDE)? 637 MSG_EXT_WDTR_BUS_8_BIT : MSG_EXT_WDTR_BUS_16_BIT; 638 neg.sync_period = sdp->isp_devparam[tgt].cur_period; 639 neg.sync_offset = sdp->isp_devparam[tgt].cur_offset; 640 if (flags & DPARM_SYNC) { 641 neg.valid |= 642 CCB_TRANS_SYNC_RATE_VALID | 643 CCB_TRANS_SYNC_OFFSET_VALID; 644 } 645 IDPRINTF(3, ("%s: New params tgt %d period 0x%x " 646 "offset 0x%x flags 0x%x\n", isp->isp_name, tgt, 647 neg.sync_period, neg.sync_offset, flags)); 648 xpt_setup_ccb(&neg.ccb_h, tmppath, 1); 649 xpt_async(AC_TRANSFER_NEG, tmppath, &neg); 650 xpt_free_path(tmppath); 651 } 652 break; 653 case ISPASYNC_BUS_RESET: 654 printf("%s: SCSI bus reset detected\n", isp->isp_name); 655 if (isp->isp_path) { 656 xpt_async(AC_BUS_RESET, isp->isp_path, NULL); 657 } 658 break; 659 case ISPASYNC_LOOP_DOWN: 660 if (isp->isp_path) { 661 /* 662 * We can get multiple LOOP downs, so only count one. 663 */ 664 if (!(isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN)) { 665 xpt_freeze_simq(isp->isp_sim, 1); 666 isp->isp_osinfo.simqfrozen |= SIMQFRZ_LOOPDOWN; 667 printf("%s: Loop DOWN- freezing SIMQ until Loop" 668 " comes up\n", isp->isp_name); 669 } 670 } else { 671 printf("%s: Loop DOWN\n", isp->isp_name); 672 } 673 break; 674 case ISPASYNC_LOOP_UP: 675 if (isp->isp_path) { 676 if (isp->isp_osinfo.simqfrozen & SIMQFRZ_LOOPDOWN) { 677 xpt_release_simq(isp->isp_sim, 1); 678 isp->isp_osinfo.simqfrozen &= ~SIMQFRZ_LOOPDOWN; 679 if (isp->isp_osinfo.simqfrozen) { 680 printf("%s: Loop UP- SIMQ still " 681 "frozen\n", isp->isp_name); 682 } else { 683 printf("%s: Loop UP-releasing frozen " 684 "SIMQ\n", isp->isp_name); 685 } 686 } 687 } else { 688 printf("%s: Loop UP\n", isp->isp_name); 689 } 690 break; 691 case ISPASYNC_PDB_CHANGE_COMPLETE: 692 if (IS_FC(isp)) { 693 long i = (long) arg; 694 static char *roles[4] = { 695 "No", "Target", "Initiator", "Target/Initiator" 696 }; 697 isp_pdb_t *pdbp = &((fcparam *)isp->isp_param)->isp_pdb[i]; 698 if (pdbp->pdb_options == INVALID_PDB_OPTIONS) { 699 break; 700 } 701 printf("%s: Loop ID %d, %s role\n", isp->isp_name, 702 pdbp->pdb_loopid, roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]); 703 printf(" Node Address 0x%x WWN 0x" 704 "%02x%02x%02x%02x%02x%02x%02x%02x\n", 705 BITS2WORD(pdbp->pdb_portid_bits), 706 pdbp->pdb_portname[0], pdbp->pdb_portname[1], 707 pdbp->pdb_portname[2], pdbp->pdb_portname[3], 708 pdbp->pdb_portname[4], pdbp->pdb_portname[5], 709 pdbp->pdb_portname[6], pdbp->pdb_portname[7]); 710 if (pdbp->pdb_options & PDB_OPTIONS_ADISC) 711 printf(" Hard Address 0x%x WWN 0x" 712 "%02x%02x%02x%02x%02x%02x%02x%02x\n", 713 BITS2WORD(pdbp->pdb_hardaddr_bits), 714 pdbp->pdb_nodename[0], pdbp->pdb_nodename[1], 715 pdbp->pdb_nodename[2], pdbp->pdb_nodename[3], 716 pdbp->pdb_nodename[4], pdbp->pdb_nodename[5], 717 pdbp->pdb_nodename[6], pdbp->pdb_nodename[7]); 718 switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) { 719 case SVC3_TGT_ROLE|SVC3_INI_ROLE: 720 printf(" Master State=%s, Slave State=%s\n", 721 isp2100_pdb_statename(pdbp->pdb_mstate), 722 isp2100_pdb_statename(pdbp->pdb_sstate)); 723 break; 724 case SVC3_TGT_ROLE: 725 printf(" Master State=%s\n", 726 isp2100_pdb_statename(pdbp->pdb_mstate)); 727 break; 728 case SVC3_INI_ROLE: 729 printf(" Slave State=%s\n", 730 isp2100_pdb_statename(pdbp->pdb_sstate)); 731 break; 732 default: 733 break; 734 } 735 break; 736 } 737 case ISPASYNC_CHANGE_NOTIFY: 738 printf("%s: Name Server Database Changed\n", isp->isp_name); 739 break; 740 default: 741 break; 742 } 743 return (rv); 744 } 745 746 747 /* 748 * Free any associated resources prior to decommissioning and 749 * set the card to a known state (so it doesn't wake up and kick 750 * us when we aren't expecting it to). 751 * 752 * Locks are held before coming here. 753 */ 754 void 755 isp_uninit(struct ispsoftc *isp) 756 { 757 DISABLE_INTS(isp); 758 } 759 #else 760 761 #define WATCH_INTERVAL 30 762 763 static void ispminphys __P((struct buf *)); 764 static u_int32_t isp_adapter_info __P((int)); 765 static int ispcmd __P((ISP_SCSI_XFER_T *)); 766 static void isp_watch __P((void *arg)); 767 768 static struct scsi_adapter isp_switch = { 769 ispcmd, ispminphys, 0, 0, isp_adapter_info, "isp", { 0, 0 } 770 }; 771 static struct scsi_device isp_dev = { 772 NULL, NULL, NULL, NULL, "isp", 0, { 0, 0 } 773 }; 774 static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int)); 775 776 777 /* 778 * Complete attachment of hardware, include subdevices. 779 */ 780 void 781 isp_attach(struct ispsoftc *isp) 782 { 783 struct scsibus_data *scbus; 784 785 scbus = scsi_alloc_bus(); 786 if(!scbus) { 787 return; 788 } 789 if (isp->isp_state == ISP_INITSTATE) 790 isp->isp_state = ISP_RUNSTATE; 791 792 timeout(isp_watch, isp, WATCH_INTERVAL * hz); 793 isp->isp_dogactive = 1; 794 795 isp->isp_osinfo._link.adapter_unit = isp->isp_osinfo.unit; 796 isp->isp_osinfo._link.adapter_softc = isp; 797 isp->isp_osinfo._link.adapter = &isp_switch; 798 isp->isp_osinfo._link.device = &isp_dev; 799 isp->isp_osinfo._link.flags = 0; 800 if (isp->isp_type & ISP_HA_FC) { 801 isp->isp_osinfo._link.adapter_targ = 802 ((fcparam *)isp->isp_param)->isp_loopid; 803 scbus->maxtarg = MAX_FC_TARG-1; 804 } else { 805 isp->isp_osinfo.delay_throttle_count = 1; 806 isp->isp_osinfo._link.adapter_targ = 807 ((sdparam *)isp->isp_param)->isp_initiator_id; 808 scbus->maxtarg = MAX_TARGETS-1; 809 (void) isp_control(isp, ISPCTL_RESET_BUS, NULL); 810 } 811 812 /* 813 * Prepare the scsibus_data area for the upperlevel scsi code. 814 */ 815 scbus->adapter_link = &isp->isp_osinfo._link; 816 817 /* 818 * ask the adapter what subunits are present 819 */ 820 scsi_attachdevs(scbus); 821 } 822 823 824 /* 825 * minphys our xfers 826 * 827 * Unfortunately, the buffer pointer describes the target device- not the 828 * adapter device, so we can't use the pointer to find out what kind of 829 * adapter we are and adjust accordingly. 830 */ 831 832 static void 833 ispminphys(struct buf *bp) 834 { 835 /* 836 * Only the 10X0 has a 24 bit limit. 837 */ 838 if (bp->b_bcount >= (1 << 24)) { 839 bp->b_bcount = (1 << 24); 840 } 841 } 842 843 static u_int32_t 844 isp_adapter_info(int unit) 845 { 846 /* 847 * XXX: FIND ISP BASED UPON UNIT AND GET REAL QUEUE LIMIT FROM THAT 848 */ 849 return (2); 850 } 851 852 static int 853 ispcmd(ISP_SCSI_XFER_T *xs) 854 { 855 struct ispsoftc *isp; 856 int r, s; 857 858 isp = XS_ISP(xs); 859 s = splbio(); 860 DISABLE_INTS(isp); 861 if (isp->isp_state != ISP_RUNSTATE) { 862 isp_init(isp); 863 if (isp->isp_state != ISP_INITSTATE) { 864 ENABLE_INTS(isp); 865 (void) splx(s); 866 XS_SETERR(xs, HBA_BOTCH); 867 return (CMD_COMPLETE); 868 } 869 isp->isp_state = ISP_RUNSTATE; 870 } 871 r = ispscsicmd(xs); 872 ENABLE_INTS(isp); 873 if (r != CMD_QUEUED || (xs->flags & SCSI_NOMASK) == 0) { 874 (void) splx(s); 875 return (r); 876 } 877 878 /* 879 * If we can't use interrupts, poll on completion. 880 */ 881 if (isp_poll(isp, xs, XS_TIME(xs))) { 882 /* 883 * If no other error occurred but we didn't finish, 884 * something bad happened. 885 */ 886 if (XS_IS_CMD_DONE(xs) == 0) { 887 isp->isp_nactive--; 888 if (isp->isp_nactive < 0) 889 isp->isp_nactive = 0; 890 if (XS_NOERR(xs)) { 891 isp_lostcmd(isp, xs); 892 XS_SETERR(xs, HBA_BOTCH); 893 } 894 } 895 } 896 (void) splx(s); 897 return (CMD_COMPLETE); 898 } 899 900 static int 901 isp_poll(struct ispsoftc *isp, ISP_SCSI_XFER_T *xs, int mswait) 902 { 903 904 while (mswait) { 905 /* Try the interrupt handling routine */ 906 (void)isp_intr((void *)isp); 907 908 /* See if the xs is now done */ 909 if (XS_IS_CMD_DONE(xs)) 910 return (0); 911 SYS_DELAY(1000); /* wait one millisecond */ 912 mswait--; 913 } 914 return (1); 915 } 916 917 static void 918 isp_watch(void *arg) 919 { 920 int i; 921 struct ispsoftc *isp = arg; 922 ISP_SCSI_XFER_T *xs; 923 int s; 924 925 /* 926 * Look for completely dead commands (but not polled ones). 927 */ 928 s = splbio(); 929 for (i = 0; i < RQUEST_QUEUE_LEN; i++) { 930 if ((xs = (ISP_SCSI_XFER_T *) isp->isp_xflist[i]) == NULL) { 931 continue; 932 } 933 if (XS_TIME(xs) == 0) { 934 continue; 935 } 936 XS_TIME(xs) -= (WATCH_INTERVAL * 1000); 937 938 /* 939 * Avoid later thinking that this 940 * transaction is not being timed. 941 * Then give ourselves to watchdog 942 * periods of grace. 943 */ 944 if (XS_TIME(xs) == 0) 945 XS_TIME(xs) = 1; 946 else if (XS_TIME(xs) > -(2 * WATCH_INTERVAL * 1000)) { 947 continue; 948 } 949 if (IS_SCSI(isp)) { 950 isp->isp_osinfo.delay_throttle_count = 1; 951 } 952 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) { 953 printf("%s: isp_watch failed to abort command\n", 954 isp->isp_name); 955 isp_restart(isp); 956 break; 957 } 958 } 959 if (isp->isp_osinfo.delay_throttle_count) { 960 if (--isp->isp_osinfo.delay_throttle_count == 0) { 961 sdparam *sdp = isp->isp_param; 962 for (i = 0; i < MAX_TARGETS; i++) { 963 sdp->isp_devparam[i].dev_flags |= 964 DPARM_WIDE|DPARM_SYNC|DPARM_TQING; 965 sdp->isp_devparam[i].dev_update = 1; 966 } 967 isp->isp_update = 1; 968 } 969 } 970 timeout(isp_watch, isp, WATCH_INTERVAL * hz); 971 isp->isp_dogactive = 1; 972 splx(s); 973 } 974 975 int 976 isp_async(isp, cmd, arg) 977 struct ispsoftc *isp; 978 ispasync_t cmd; 979 void *arg; 980 { 981 switch (cmd) { 982 case ISPASYNC_NEW_TGT_PARAMS: 983 if (isp->isp_type & ISP_HA_SCSI) { 984 sdparam *sdp = isp->isp_param; 985 char *wt; 986 int mhz, flags, tgt, period; 987 988 tgt = *((int *) arg); 989 990 flags = sdp->isp_devparam[tgt].cur_dflags; 991 period = sdp->isp_devparam[tgt].cur_period; 992 if ((flags & DPARM_SYNC) && period && 993 (sdp->isp_devparam[tgt].cur_offset) != 0) { 994 if (sdp->isp_lvdmode) { 995 switch (period) { 996 case 0xa: 997 mhz = 40; 998 break; 999 case 0xb: 1000 mhz = 33; 1001 break; 1002 case 0xc: 1003 mhz = 25; 1004 break; 1005 default: 1006 mhz = 1000 / (period * 4); 1007 break; 1008 } 1009 } else { 1010 mhz = 1000 / (period * 4); 1011 } 1012 } else { 1013 mhz = 0; 1014 } 1015 switch (flags & (DPARM_WIDE|DPARM_TQING)) { 1016 case DPARM_WIDE: 1017 wt = ", 16 bit wide\n"; 1018 break; 1019 case DPARM_TQING: 1020 wt = ", Tagged Queueing Enabled\n"; 1021 break; 1022 case DPARM_WIDE|DPARM_TQING: 1023 wt = ", 16 bit wide, Tagged Queueing Enabled\n"; 1024 break; 1025 default: 1026 wt = "\n"; 1027 break; 1028 } 1029 if (mhz) { 1030 printf("%s: Target %d at %dMHz Max Offset %d%s", 1031 isp->isp_name, tgt, mhz, 1032 sdp->isp_devparam[tgt].cur_offset, wt); 1033 } else { 1034 printf("%s: Target %d Async Mode%s", 1035 isp->isp_name, tgt, wt); 1036 } 1037 } 1038 break; 1039 case ISPASYNC_BUS_RESET: 1040 printf("%s: SCSI bus reset detected\n", isp->isp_name); 1041 break; 1042 case ISPASYNC_LOOP_DOWN: 1043 printf("%s: Loop DOWN\n", isp->isp_name); 1044 break; 1045 case ISPASYNC_LOOP_UP: 1046 printf("%s: Loop UP\n", isp->isp_name); 1047 break; 1048 case ISPASYNC_PDB_CHANGE_COMPLETE: 1049 if (isp->isp_type & ISP_HA_FC) { 1050 int i; 1051 static char *roles[4] = { 1052 "No", "Target", "Initiator", "Target/Initiator" 1053 }; 1054 for (i = 0; i < MAX_FC_TARG; i++) { 1055 isp_pdb_t *pdbp = 1056 &((fcparam *)isp->isp_param)->isp_pdb[i]; 1057 if (pdbp->pdb_options == INVALID_PDB_OPTIONS) 1058 continue; 1059 printf("%s: Loop ID %d, %s role\n", 1060 isp->isp_name, pdbp->pdb_loopid, 1061 roles[(pdbp->pdb_prli_svc3 >> 4) & 0x3]); 1062 printf(" Node Address 0x%x WWN 0x" 1063 "%02x%02x%02x%02x%02x%02x%02x%02x\n", 1064 BITS2WORD(pdbp->pdb_portid_bits), 1065 pdbp->pdb_portname[0], pdbp->pdb_portname[1], 1066 pdbp->pdb_portname[2], pdbp->pdb_portname[3], 1067 pdbp->pdb_portname[4], pdbp->pdb_portname[5], 1068 pdbp->pdb_portname[6], pdbp->pdb_portname[7]); 1069 if (pdbp->pdb_options & PDB_OPTIONS_ADISC) 1070 printf(" Hard Address 0x%x WWN 0x" 1071 "%02x%02x%02x%02x%02x%02x%02x%02x\n", 1072 BITS2WORD(pdbp->pdb_hardaddr_bits), 1073 pdbp->pdb_nodename[0], 1074 pdbp->pdb_nodename[1], 1075 pdbp->pdb_nodename[2], 1076 pdbp->pdb_nodename[3], 1077 pdbp->pdb_nodename[4], 1078 pdbp->pdb_nodename[5], 1079 pdbp->pdb_nodename[6], 1080 pdbp->pdb_nodename[7]); 1081 switch (pdbp->pdb_prli_svc3 & SVC3_ROLE_MASK) { 1082 case SVC3_TGT_ROLE|SVC3_INI_ROLE: 1083 printf(" Master State=%s, Slave State=%s\n", 1084 isp2100_pdb_statename(pdbp->pdb_mstate), 1085 isp2100_pdb_statename(pdbp->pdb_sstate)); 1086 break; 1087 case SVC3_TGT_ROLE: 1088 printf(" Master State=%s\n", 1089 isp2100_pdb_statename(pdbp->pdb_mstate)); 1090 break; 1091 case SVC3_INI_ROLE: 1092 printf(" Slave State=%s\n", 1093 isp2100_pdb_statename(pdbp->pdb_sstate)); 1094 break; 1095 default: 1096 break; 1097 } 1098 } 1099 break; 1100 } 1101 case ISPASYNC_CHANGE_NOTIFY: 1102 printf("%s: Name Server Database Changed\n", isp->isp_name); 1103 break; 1104 default: 1105 break; 1106 } 1107 return (0); 1108 } 1109 1110 /* 1111 * Free any associated resources prior to decommissioning and 1112 * set the card to a known state (so it doesn't wake up and kick 1113 * us when we aren't expecting it to). 1114 * 1115 * Locks are held before coming here. 1116 */ 1117 void 1118 isp_uninit(isp) 1119 struct ispsoftc *isp; 1120 { 1121 int s = splbio(); 1122 /* 1123 * Leave with interrupts disabled. 1124 */ 1125 DISABLE_INTS(isp); 1126 1127 /* 1128 * Turn off the watchdog (if active). 1129 */ 1130 if (isp->isp_dogactive) { 1131 untimeout(isp_watch, isp); 1132 isp->isp_dogactive = 0; 1133 } 1134 /* 1135 * And out... 1136 */ 1137 splx(s); 1138 } 1139 #endif 1140