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