1 /* $NetBSD: isp_netbsd.c,v 1.48 2001/09/05 23:08:23 mjacob Exp $ */ 2 /* 3 * This driver, which is contained in NetBSD in the files: 4 * 5 * sys/dev/ic/isp.c 6 * sys/dev/ic/isp_inline.h 7 * sys/dev/ic/isp_netbsd.c 8 * sys/dev/ic/isp_netbsd.h 9 * sys/dev/ic/isp_target.c 10 * sys/dev/ic/isp_target.h 11 * sys/dev/ic/isp_tpublic.h 12 * sys/dev/ic/ispmbox.h 13 * sys/dev/ic/ispreg.h 14 * sys/dev/ic/ispvar.h 15 * sys/microcode/isp/asm_sbus.h 16 * sys/microcode/isp/asm_1040.h 17 * sys/microcode/isp/asm_1080.h 18 * sys/microcode/isp/asm_12160.h 19 * sys/microcode/isp/asm_2100.h 20 * sys/microcode/isp/asm_2200.h 21 * sys/pci/isp_pci.c 22 * sys/sbus/isp_sbus.c 23 * 24 * Is being actively maintained by Matthew Jacob (mjacob@netbsd.org). 25 * This driver also is shared source with FreeBSD, OpenBSD, Linux, Solaris, 26 * Linux versions. This tends to be an interesting maintenance problem. 27 * 28 * Please coordinate with Matthew Jacob on changes you wish to make here. 29 */ 30 /* 31 * Platform (NetBSD) dependent common attachment code for Qlogic adapters. 32 * Matthew Jacob <mjacob@nas.nasa.gov> 33 */ 34 /* 35 * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration 36 * All rights reserved. 37 * 38 * Redistribution and use in source and binary forms, with or without 39 * modification, are permitted provided that the following conditions 40 * are met: 41 * 1. Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * 2. Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in the 45 * documentation and/or other materials provided with the distribution. 46 * 3. The name of the author may not be used to endorse or promote products 47 * derived from this software without specific prior written permission 48 * 49 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 50 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 51 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 52 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 53 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 54 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 55 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 56 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 57 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 58 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 */ 60 61 #include <dev/ic/isp_netbsd.h> 62 #include <sys/scsiio.h> 63 64 65 /* 66 * Set a timeout for the watchdogging of a command. 67 * 68 * The dimensional analysis is 69 * 70 * milliseconds * (seconds/millisecond) * (ticks/second) = ticks 71 * 72 * = 73 * 74 * (milliseconds / 1000) * hz = ticks 75 * 76 * 77 * For timeouts less than 1 second, we'll get zero. Because of this, and 78 * because we want to establish *our* timeout to be longer than what the 79 * firmware might do, we just add 3 seconds at the back end. 80 */ 81 #define _XT(xs) ((((xs)->timeout/1000) * hz) + (3 * hz)) 82 83 static void isp_config_interrupts(struct device *); 84 static void ispminphys_1020(struct buf *); 85 static void ispminphys(struct buf *); 86 static INLINE void ispcmd(struct ispsoftc *, XS_T *); 87 static void isprequest(struct scsipi_channel *, scsipi_adapter_req_t, void *); 88 static int 89 ispioctl(struct scsipi_channel *, u_long, caddr_t, int, struct proc *); 90 91 static void isp_polled_cmd(struct ispsoftc *, XS_T *); 92 static void isp_dog(void *); 93 static void isp_create_fc_worker(void *); 94 static void isp_fc_worker(void *); 95 96 /* 97 * Complete attachment of hardware, include subdevices. 98 */ 99 void 100 isp_attach(struct ispsoftc *isp) 101 { 102 isp->isp_state = ISP_RUNSTATE; 103 104 isp->isp_osinfo._adapter.adapt_dev = &isp->isp_osinfo._dev; 105 isp->isp_osinfo._adapter.adapt_nchannels = IS_DUALBUS(isp) ? 2 : 1; 106 isp->isp_osinfo._adapter.adapt_openings = isp->isp_maxcmds; 107 /* 108 * It's not stated whether max_periph is limited by SPI 109 * tag uage, but let's assume that it is. 110 */ 111 isp->isp_osinfo._adapter.adapt_max_periph = min(isp->isp_maxcmds, 255); 112 isp->isp_osinfo._adapter.adapt_ioctl = ispioctl; 113 isp->isp_osinfo._adapter.adapt_request = isprequest; 114 if (isp->isp_type <= ISP_HA_SCSI_1020A) { 115 isp->isp_osinfo._adapter.adapt_minphys = ispminphys_1020; 116 } else { 117 isp->isp_osinfo._adapter.adapt_minphys = ispminphys; 118 } 119 120 isp->isp_osinfo._chan.chan_adapter = &isp->isp_osinfo._adapter; 121 isp->isp_osinfo._chan.chan_bustype = &scsi_bustype; 122 isp->isp_osinfo._chan.chan_channel = 0; 123 124 /* 125 * Until the midlayer is fixed to use REPORT LUNS, limit to 8 luns. 126 */ 127 isp->isp_osinfo._chan.chan_nluns = min(isp->isp_maxluns, 8); 128 129 if (IS_FC(isp)) { 130 isp->isp_osinfo._chan.chan_ntargets = MAX_FC_TARG; 131 isp->isp_osinfo._chan.chan_id = MAX_FC_TARG; 132 isp->isp_osinfo.threadwork = 1; 133 /* 134 * Note that isp_create_fc_worker won't get called 135 * until much much later (after proc0 is created). 136 */ 137 kthread_create(isp_create_fc_worker, isp); 138 } else { 139 int bus = 0; 140 sdparam *sdp = isp->isp_param; 141 142 isp->isp_osinfo._chan.chan_ntargets = MAX_TARGETS; 143 isp->isp_osinfo._chan.chan_id = sdp->isp_initiator_id; 144 isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id; 145 if (IS_DUALBUS(isp)) { 146 isp->isp_osinfo._chan_b = isp->isp_osinfo._chan; 147 sdp++; 148 isp->isp_osinfo.discovered[1] = 149 1 << sdp->isp_initiator_id; 150 isp->isp_osinfo._chan_b.chan_id = sdp->isp_initiator_id; 151 isp->isp_osinfo._chan_b.chan_channel = 1; 152 } 153 ISP_LOCK(isp); 154 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus); 155 if (IS_DUALBUS(isp)) { 156 bus++; 157 (void) isp_control(isp, ISPCTL_RESET_BUS, &bus); 158 } 159 ISP_UNLOCK(isp); 160 } 161 162 163 /* 164 * Defer enabling mailbox interrupts until later. 165 */ 166 config_interrupts((struct device *) isp, isp_config_interrupts); 167 168 /* 169 * And attach children (if any). 170 */ 171 config_found((void *)isp, &isp->isp_chanA, scsiprint); 172 if (IS_DUALBUS(isp)) { 173 config_found((void *)isp, &isp->isp_chanB, scsiprint); 174 } 175 } 176 177 178 static void 179 isp_config_interrupts(struct device *self) 180 { 181 #if 0 182 struct ispsoftc *isp = (struct ispsoftc *) self; 183 184 /* 185 * After this point, we'll be doing the new configuration 186 * schema which allows interrupts, so we can do tsleep/wakeup 187 * for mailbox stuff at that point. 188 */ 189 190 /* 191 * Argh. We cannot use this until we know whether isprequest 192 * was *not* called via a hardclock (timed thaw). So- we'll 193 * only allow a window of the FC kernel thread doing this 194 * when calling isp_fc_runstate. 195 */ 196 isp->isp_osinfo.no_mbox_ints = 0; 197 #endif 198 } 199 200 201 /* 202 * minphys our xfers 203 */ 204 205 static void 206 ispminphys_1020(struct buf *bp) 207 { 208 if (bp->b_bcount >= (1 << 24)) { 209 bp->b_bcount = (1 << 24); 210 } 211 minphys(bp); 212 } 213 214 static void 215 ispminphys(struct buf *bp) 216 { 217 if (bp->b_bcount >= (1 << 30)) { 218 bp->b_bcount = (1 << 30); 219 } 220 minphys(bp); 221 } 222 223 static int 224 ispioctl(struct scsipi_channel *chan, u_long cmd, caddr_t addr, int flag, 225 struct proc *p) 226 { 227 struct ispsoftc *isp = (void *)chan->chan_adapter->adapt_dev; 228 int retval = ENOTTY; 229 230 switch (cmd) { 231 case SCBUSIORESET: 232 ISP_LOCK(isp); 233 if (isp_control(isp, ISPCTL_RESET_BUS, &chan->chan_channel)) 234 retval = EIO; 235 else 236 retval = 0; 237 ISP_UNLOCK(isp); 238 break; 239 case ISP_SDBLEV: 240 { 241 int olddblev = isp->isp_dblev; 242 isp->isp_dblev = *(int *)addr; 243 *(int *)addr = olddblev; 244 retval = 0; 245 break; 246 } 247 case ISP_RESETHBA: 248 ISP_LOCK(isp); 249 isp_reinit(isp); 250 ISP_UNLOCK(isp); 251 retval = 0; 252 break; 253 case ISP_FC_RESCAN: 254 if (IS_FC(isp)) { 255 ISP_LOCK(isp); 256 if (isp_fc_runstate(isp, 5 * 1000000)) { 257 retval = EIO; 258 } else { 259 retval = 0; 260 } 261 ISP_UNLOCK(isp); 262 } 263 break; 264 case ISP_FC_LIP: 265 if (IS_FC(isp)) { 266 ISP_LOCK(isp); 267 if (isp_control(isp, ISPCTL_SEND_LIP, 0)) { 268 retval = EIO; 269 } else { 270 retval = 0; 271 } 272 ISP_UNLOCK(isp); 273 } 274 break; 275 case ISP_FC_GETDINFO: 276 { 277 struct isp_fc_device *ifc = (struct isp_fc_device *) addr; 278 struct lportdb *lp; 279 280 if (ifc->loopid < 0 || ifc->loopid >= MAX_FC_TARG) { 281 retval = EINVAL; 282 break; 283 } 284 ISP_LOCK(isp); 285 lp = &FCPARAM(isp)->portdb[ifc->loopid]; 286 if (lp->valid) { 287 ifc->loopid = lp->loopid; 288 ifc->portid = lp->portid; 289 ifc->node_wwn = lp->node_wwn; 290 ifc->port_wwn = lp->port_wwn; 291 retval = 0; 292 } else { 293 retval = ENODEV; 294 } 295 ISP_UNLOCK(isp); 296 break; 297 } 298 default: 299 break; 300 } 301 return (retval); 302 } 303 304 static INLINE void 305 ispcmd(struct ispsoftc *isp, XS_T *xs) 306 { 307 ISP_LOCK(isp); 308 if (isp->isp_state < ISP_RUNSTATE) { 309 DISABLE_INTS(isp); 310 isp_init(isp); 311 if (isp->isp_state != ISP_INITSTATE) { 312 ENABLE_INTS(isp); 313 ISP_UNLOCK(isp); 314 XS_SETERR(xs, HBA_BOTCH); 315 scsipi_done(xs); 316 return; 317 } 318 isp->isp_state = ISP_RUNSTATE; 319 ENABLE_INTS(isp); 320 } 321 /* 322 * Handle the case of a FC card where the FC thread hasn't 323 * fired up yet and we have loop state to clean up. If we 324 * can't clear things up and we've never seen loop up, bounce 325 * the command. 326 */ 327 if (IS_FC(isp) && isp->isp_osinfo.threadwork && 328 isp->isp_osinfo.thread == 0) { 329 volatile u_int8_t ombi = isp->isp_osinfo.no_mbox_ints; 330 int delay_time; 331 332 if (xs->xs_control & XS_CTL_POLL) { 333 isp->isp_osinfo.no_mbox_ints = 1; 334 } 335 336 if (isp->isp_osinfo.loop_checked == 0) { 337 delay_time = 10 * 1000000; 338 isp->isp_osinfo.loop_checked = 1; 339 } else { 340 delay_time = 250000; 341 } 342 343 if (isp_fc_runstate(isp, delay_time) != 0) { 344 if (xs->xs_control & XS_CTL_POLL) { 345 isp->isp_osinfo.no_mbox_ints = ombi; 346 } 347 if (FCPARAM(isp)->loop_seen_once == 0) { 348 XS_SETERR(xs, HBA_SELTIMEOUT); 349 scsipi_done(xs); 350 ISP_UNLOCK(isp); 351 return; 352 } 353 /* 354 * Otherwise, fall thru to be queued up for later. 355 */ 356 } else { 357 int wasblocked = 358 (isp->isp_osinfo.blocked || isp->isp_osinfo.paused); 359 isp->isp_osinfo.threadwork = 0; 360 isp->isp_osinfo.blocked = 361 isp->isp_osinfo.paused = 0; 362 if (wasblocked) { 363 scsipi_channel_thaw(&isp->isp_chanA, 1); 364 } 365 } 366 if (xs->xs_control & XS_CTL_POLL) { 367 isp->isp_osinfo.no_mbox_ints = ombi; 368 } 369 } 370 371 if (isp->isp_osinfo.paused) { 372 isp_prt(isp, ISP_LOGWARN, "I/O while paused"); 373 xs->error = XS_RESOURCE_SHORTAGE; 374 scsipi_done(xs); 375 ISP_UNLOCK(isp); 376 return; 377 } 378 if (isp->isp_osinfo.blocked) { 379 isp_prt(isp, ISP_LOGWARN, "I/O while blocked"); 380 xs->error = XS_REQUEUE; 381 scsipi_done(xs); 382 ISP_UNLOCK(isp); 383 return; 384 } 385 386 if (xs->xs_control & XS_CTL_POLL) { 387 volatile u_int8_t ombi = isp->isp_osinfo.no_mbox_ints; 388 isp->isp_osinfo.no_mbox_ints = 1; 389 isp_polled_cmd(isp, xs); 390 isp->isp_osinfo.no_mbox_ints = ombi; 391 ISP_UNLOCK(isp); 392 return; 393 } 394 395 switch (isp_start(xs)) { 396 case CMD_QUEUED: 397 if (xs->timeout) { 398 callout_reset(&xs->xs_callout, _XT(xs), isp_dog, xs); 399 } 400 break; 401 case CMD_EAGAIN: 402 isp->isp_osinfo.paused = 1; 403 xs->error = XS_RESOURCE_SHORTAGE; 404 scsipi_channel_freeze(&isp->isp_chanA, 1); 405 if (IS_DUALBUS(isp)) { 406 scsipi_channel_freeze(&isp->isp_chanB, 1); 407 } 408 scsipi_done(xs); 409 break; 410 case CMD_RQLATER: 411 /* 412 * We can only get RQLATER from FC devices (1 channel only) 413 * 414 * Also, if we've never seen loop up, bounce the command 415 * (somebody has booted with no FC cable connected) 416 */ 417 if (FCPARAM(isp)->loop_seen_once == 0) { 418 XS_SETERR(xs, HBA_SELTIMEOUT); 419 scsipi_done(xs); 420 break; 421 } 422 if (isp->isp_osinfo.blocked == 0) { 423 isp->isp_osinfo.blocked = 1; 424 scsipi_channel_freeze(&isp->isp_chanA, 1); 425 } 426 xs->error = XS_REQUEUE; 427 scsipi_done(xs); 428 break; 429 case CMD_COMPLETE: 430 scsipi_done(xs); 431 break; 432 } 433 ISP_UNLOCK(isp); 434 } 435 436 static void 437 isprequest(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg) 438 { 439 struct ispsoftc *isp = (void *)chan->chan_adapter->adapt_dev; 440 441 switch (req) { 442 case ADAPTER_REQ_RUN_XFER: 443 ispcmd(isp, (XS_T *) arg); 444 break; 445 446 case ADAPTER_REQ_GROW_RESOURCES: 447 /* Not supported. */ 448 break; 449 450 case ADAPTER_REQ_SET_XFER_MODE: 451 if (IS_SCSI(isp)) { 452 struct scsipi_xfer_mode *xm = arg; 453 int dflags = 0; 454 sdparam *sdp = SDPARAM(isp); 455 456 sdp += chan->chan_channel; 457 if (xm->xm_mode & PERIPH_CAP_TQING) 458 dflags |= DPARM_TQING; 459 if (xm->xm_mode & PERIPH_CAP_WIDE16) 460 dflags |= DPARM_WIDE; 461 if (xm->xm_mode & PERIPH_CAP_SYNC) 462 dflags |= DPARM_SYNC; 463 ISP_LOCK(isp); 464 sdp->isp_devparam[xm->xm_target].goal_flags |= dflags; 465 dflags = sdp->isp_devparam[xm->xm_target].goal_flags; 466 sdp->isp_devparam[xm->xm_target].dev_update = 1; 467 isp->isp_update |= (1 << chan->chan_channel); 468 ISP_UNLOCK(isp); 469 isp_prt(isp, ISP_LOGDEBUG1, 470 "ispioctl: device flags 0x%x for %d.%d.X", 471 dflags, chan->chan_channel, xm->xm_target); 472 break; 473 } 474 default: 475 break; 476 } 477 } 478 479 static void 480 isp_polled_cmd(struct ispsoftc *isp, XS_T *xs) 481 { 482 int result; 483 int infinite = 0, mswait; 484 485 result = isp_start(xs); 486 487 switch (result) { 488 case CMD_QUEUED: 489 break; 490 case CMD_RQLATER: 491 if (XS_NOERR(xs)) { 492 xs->error = XS_REQUEUE; 493 } 494 case CMD_EAGAIN: 495 if (XS_NOERR(xs)) { 496 xs->error = XS_RESOURCE_SHORTAGE; 497 } 498 /* FALLTHROUGH */ 499 case CMD_COMPLETE: 500 scsipi_done(xs); 501 return; 502 503 } 504 505 /* 506 * If we can't use interrupts, poll on completion. 507 */ 508 if ((mswait = XS_TIME(xs)) == 0) 509 infinite = 1; 510 511 while (mswait || infinite) { 512 u_int16_t isr, sema, mbox; 513 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { 514 isp_intr(isp, isr, sema, mbox); 515 if (XS_CMD_DONE_P(xs)) { 516 break; 517 } 518 } 519 USEC_DELAY(1000); 520 mswait -= 1; 521 } 522 523 /* 524 * If no other error occurred but we didn't finish, 525 * something bad happened. 526 */ 527 if (XS_CMD_DONE_P(xs) == 0) { 528 if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) { 529 isp_reinit(isp); 530 } 531 if (XS_NOERR(xs)) { 532 XS_SETERR(xs, HBA_BOTCH); 533 } 534 } 535 scsipi_done(xs); 536 } 537 538 void 539 isp_done(XS_T *xs) 540 { 541 XS_CMD_S_DONE(xs); 542 if (XS_CMD_WDOG_P(xs) == 0) { 543 struct ispsoftc *isp = XS_ISP(xs); 544 callout_stop(&xs->xs_callout); 545 if (XS_CMD_GRACE_P(xs)) { 546 isp_prt(isp, ISP_LOGDEBUG1, 547 "finished command on borrowed time"); 548 } 549 XS_CMD_S_CLEAR(xs); 550 /* 551 * Fixup- if we get a QFULL, we need 552 * to set XS_BUSY as the error. 553 */ 554 if (xs->status == SCSI_QUEUE_FULL) { 555 xs->error = XS_BUSY; 556 } 557 if (isp->isp_osinfo.paused) { 558 isp->isp_osinfo.paused = 0; 559 scsipi_channel_timed_thaw(&isp->isp_chanA); 560 if (IS_DUALBUS(isp)) { 561 scsipi_channel_timed_thaw(&isp->isp_chanB); 562 } 563 } 564 scsipi_done(xs); 565 } 566 } 567 568 static void 569 isp_dog(void *arg) 570 { 571 XS_T *xs = arg; 572 struct ispsoftc *isp = XS_ISP(xs); 573 u_int16_t handle; 574 575 ISP_ILOCK(isp); 576 /* 577 * We've decided this command is dead. Make sure we're not trying 578 * to kill a command that's already dead by getting it's handle and 579 * and seeing whether it's still alive. 580 */ 581 handle = isp_find_handle(isp, xs); 582 if (handle) { 583 u_int16_t isr, mbox, sema; 584 585 if (XS_CMD_DONE_P(xs)) { 586 isp_prt(isp, ISP_LOGDEBUG1, 587 "watchdog found done cmd (handle 0x%x)", handle); 588 ISP_IUNLOCK(isp); 589 return; 590 } 591 592 if (XS_CMD_WDOG_P(xs)) { 593 isp_prt(isp, ISP_LOGDEBUG1, 594 "recursive watchdog (handle 0x%x)", handle); 595 ISP_IUNLOCK(isp); 596 return; 597 } 598 599 XS_CMD_S_WDOG(xs); 600 601 if (ISP_READ_ISR(isp, &isr, &sema, &mbox)) { 602 isp_intr(isp, isr, sema, mbox); 603 604 } 605 if (XS_CMD_DONE_P(xs)) { 606 isp_prt(isp, ISP_LOGDEBUG1, 607 "watchdog cleanup for handle 0x%x", handle); 608 XS_CMD_C_WDOG(xs); 609 isp_done(xs); 610 } else if (XS_CMD_GRACE_P(xs)) { 611 isp_prt(isp, ISP_LOGDEBUG1, 612 "watchdog timeout for handle 0x%x", handle); 613 /* 614 * Make sure the command is *really* dead before we 615 * release the handle (and DMA resources) for reuse. 616 */ 617 (void) isp_control(isp, ISPCTL_ABORT_CMD, arg); 618 619 /* 620 * After this point, the comamnd is really dead. 621 */ 622 if (XS_XFRLEN(xs)) { 623 ISP_DMAFREE(isp, xs, handle); 624 } 625 isp_destroy_handle(isp, handle); 626 XS_SETERR(xs, XS_TIMEOUT); 627 XS_CMD_S_CLEAR(xs); 628 isp_done(xs); 629 } else { 630 u_int16_t iptr, optr; 631 ispreq_t *mp; 632 isp_prt(isp, ISP_LOGDEBUG2, 633 "possible command timeout on handle %x", handle); 634 XS_CMD_C_WDOG(xs); 635 callout_reset(&xs->xs_callout, hz, isp_dog, xs); 636 if (isp_getrqentry(isp, &iptr, &optr, (void **) &mp)) { 637 ISP_UNLOCK(isp); 638 return; 639 } 640 XS_CMD_S_GRACE(xs); 641 MEMZERO((void *) mp, sizeof (*mp)); 642 mp->req_header.rqs_entry_count = 1; 643 mp->req_header.rqs_entry_type = RQSTYPE_MARKER; 644 mp->req_modifier = SYNC_ALL; 645 mp->req_target = XS_CHANNEL(xs) << 7; 646 ISP_SWIZZLE_REQUEST(isp, mp); 647 ISP_ADD_REQUEST(isp, iptr); 648 } 649 } else { 650 isp_prt(isp, ISP_LOGDEBUG0, "watchdog with no command"); 651 } 652 ISP_IUNLOCK(isp); 653 } 654 655 /* 656 * Fibre Channel state cleanup thread 657 */ 658 static void 659 isp_create_fc_worker(void *arg) 660 { 661 struct ispsoftc *isp = arg; 662 663 if (kthread_create1(isp_fc_worker, isp, &isp->isp_osinfo.thread, 664 "%s:fc_thrd", isp->isp_name)) { 665 isp_prt(isp, ISP_LOGERR, "unable to create FC worker thread"); 666 panic("isp_create_fc_worker"); 667 } 668 669 } 670 671 static void 672 isp_fc_worker(void *arg) 673 { 674 void scsipi_run_queue(struct scsipi_channel *); 675 struct ispsoftc *isp = arg; 676 677 for (;;) { 678 int s; 679 680 /* 681 * Note we do *not* use the ISP_LOCK/ISP_UNLOCK macros here. 682 */ 683 s = splbio(); 684 while (isp->isp_osinfo.threadwork) { 685 int omb, r; 686 isp->isp_osinfo.threadwork = 0; 687 omb = isp->isp_osinfo.no_mbox_ints; 688 isp->isp_osinfo.no_mbox_ints = 0; 689 r = isp_fc_runstate(isp, 10 * 1000000); 690 isp->isp_osinfo.no_mbox_ints = omb; 691 if (r) { 692 break; 693 } 694 if (isp->isp_osinfo.loop_checked && 695 FCPARAM(isp)->loop_seen_once == 0) { 696 splx(s); 697 goto skip; 698 } 699 isp->isp_osinfo.threadwork = 1; 700 splx(s); 701 delay(500 * 1000); 702 s = splbio(); 703 } 704 if (FCPARAM(isp)->isp_fwstate != FW_READY || 705 FCPARAM(isp)->isp_loopstate != LOOP_READY) { 706 isp_prt(isp, ISP_LOGINFO, "isp_fc_runstate in vain"); 707 isp->isp_osinfo.threadwork = 1; 708 splx(s); 709 continue; 710 } 711 712 if (isp->isp_osinfo.blocked) { 713 isp->isp_osinfo.blocked = 0; 714 isp_prt(isp, ISP_LOGDEBUG0, 715 "restarting queues (freeze count %d)", 716 isp->isp_chanA.chan_qfreeze); 717 scsipi_channel_thaw(&isp->isp_chanA, 1); 718 } 719 720 if (isp->isp_osinfo.thread == NULL) 721 break; 722 723 skip: 724 (void) tsleep(&isp->isp_osinfo.thread, PRIBIO, "fcclnup", 0); 725 726 splx(s); 727 } 728 729 /* In case parent is waiting for us to exit. */ 730 wakeup(&isp->isp_osinfo.thread); 731 732 kthread_exit(0); 733 } 734 735 /* 736 * Free any associated resources prior to decommissioning and 737 * set the card to a known state (so it doesn't wake up and kick 738 * us when we aren't expecting it to). 739 * 740 * Locks are held before coming here. 741 */ 742 void 743 isp_uninit(struct ispsoftc *isp) 744 { 745 isp_lock(isp); 746 /* 747 * Leave with interrupts disabled. 748 */ 749 DISABLE_INTS(isp); 750 isp_unlock(isp); 751 } 752 753 int 754 isp_async(struct ispsoftc *isp, ispasync_t cmd, void *arg) 755 { 756 int bus, tgt; 757 758 switch (cmd) { 759 case ISPASYNC_NEW_TGT_PARAMS: 760 if (IS_SCSI(isp) && isp->isp_dblev) { 761 sdparam *sdp = isp->isp_param; 762 int flags; 763 struct scsipi_xfer_mode xm; 764 765 tgt = *((int *) arg); 766 bus = (tgt >> 16) & 0xffff; 767 tgt &= 0xffff; 768 sdp += bus; 769 flags = sdp->isp_devparam[tgt].actv_flags; 770 771 xm.xm_mode = 0; 772 xm.xm_period = sdp->isp_devparam[tgt].actv_period; 773 xm.xm_offset = sdp->isp_devparam[tgt].actv_offset; 774 xm.xm_target = tgt; 775 776 if ((flags & DPARM_SYNC) && xm.xm_period && xm.xm_offset) 777 xm.xm_mode |= PERIPH_CAP_SYNC; 778 if (flags & DPARM_WIDE) 779 xm.xm_mode |= PERIPH_CAP_WIDE16; 780 if (flags & DPARM_TQING) 781 xm.xm_mode |= PERIPH_CAP_TQING; 782 scsipi_async_event(bus? &isp->isp_chanB : &isp->isp_chanA, 783 ASYNC_EVENT_XFER_MODE, &xm); 784 break; 785 } 786 case ISPASYNC_BUS_RESET: 787 bus = *((int *) arg); 788 scsipi_async_event(bus? &isp->isp_chanB : &isp->isp_chanA, 789 ASYNC_EVENT_RESET, NULL); 790 isp_prt(isp, ISP_LOGINFO, "SCSI bus %d reset detected", bus); 791 break; 792 case ISPASYNC_LIP: 793 /* 794 * Don't do queue freezes or blockage until we have the 795 * thread running that can unfreeze/unblock us. 796 */ 797 if (isp->isp_osinfo.blocked == 0) { 798 if (isp->isp_osinfo.thread) { 799 isp->isp_osinfo.blocked = 1; 800 scsipi_channel_freeze(&isp->isp_chanA, 1); 801 } 802 } 803 isp_prt(isp, ISP_LOGINFO, "LIP Received"); 804 break; 805 case ISPASYNC_LOOP_RESET: 806 /* 807 * Don't do queue freezes or blockage until we have the 808 * thread running that can unfreeze/unblock us. 809 */ 810 if (isp->isp_osinfo.blocked == 0) { 811 if (isp->isp_osinfo.thread) { 812 isp->isp_osinfo.blocked = 1; 813 scsipi_channel_freeze(&isp->isp_chanA, 1); 814 } 815 } 816 isp_prt(isp, ISP_LOGINFO, "Loop Reset Received"); 817 break; 818 case ISPASYNC_LOOP_DOWN: 819 /* 820 * Don't do queue freezes or blockage until we have the 821 * thread running that can unfreeze/unblock us. 822 */ 823 if (isp->isp_osinfo.blocked == 0) { 824 if (isp->isp_osinfo.thread) { 825 isp->isp_osinfo.blocked = 1; 826 scsipi_channel_freeze(&isp->isp_chanA, 1); 827 } 828 } 829 isp_prt(isp, ISP_LOGINFO, "Loop DOWN"); 830 break; 831 case ISPASYNC_LOOP_UP: 832 /* 833 * Let the subsequent ISPASYNC_CHANGE_NOTIFY invoke 834 * the FC worker thread. When the FC worker thread 835 * is done, let *it* call scsipi_channel_thaw... 836 */ 837 isp_prt(isp, ISP_LOGINFO, "Loop UP"); 838 break; 839 case ISPASYNC_PROMENADE: 840 if (IS_FC(isp) && isp->isp_dblev) { 841 const char fmt[] = "Target %d (Loop 0x%x) Port ID 0x%x " 842 "(role %s) %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x"; 843 const static char *roles[4] = { 844 "None", "Target", "Initiator", "Target/Initiator" 845 }; 846 fcparam *fcp = isp->isp_param; 847 int tgt = *((int *) arg); 848 struct lportdb *lp = &fcp->portdb[tgt]; 849 850 isp_prt(isp, ISP_LOGINFO, fmt, tgt, lp->loopid, lp->portid, 851 roles[lp->roles & 0x3], 852 (lp->valid)? "Arrived" : "Departed", 853 (u_int32_t) (lp->port_wwn >> 32), 854 (u_int32_t) (lp->port_wwn & 0xffffffffLL), 855 (u_int32_t) (lp->node_wwn >> 32), 856 (u_int32_t) (lp->node_wwn & 0xffffffffLL)); 857 break; 858 } 859 case ISPASYNC_CHANGE_NOTIFY: 860 if (arg == ISPASYNC_CHANGE_PDB) { 861 isp_prt(isp, ISP_LOGINFO, "Port Database Changed"); 862 } else if (arg == ISPASYNC_CHANGE_SNS) { 863 isp_prt(isp, ISP_LOGINFO, 864 "Name Server Database Changed"); 865 } 866 867 /* 868 * We can set blocked here because we know it's now okay 869 * to try and run isp_fc_runstate (in order to build loop 870 * state). But we don't try and freeze the midlayer's queue 871 * if we have no thread that we can wake to later unfreeze 872 * it. 873 */ 874 if (isp->isp_osinfo.blocked == 0) { 875 isp->isp_osinfo.blocked = 1; 876 if (isp->isp_osinfo.thread) { 877 scsipi_channel_freeze(&isp->isp_chanA, 1); 878 } 879 } 880 /* 881 * Note that we have work for the thread to do, and 882 * if the thread is here already, wake it up. 883 */ 884 isp->isp_osinfo.threadwork++; 885 if (isp->isp_osinfo.thread) { 886 wakeup(&isp->isp_osinfo.thread); 887 } else { 888 isp_prt(isp, ISP_LOGDEBUG1, "no FC thread yet"); 889 } 890 break; 891 case ISPASYNC_FABRIC_DEV: 892 { 893 int target, lrange; 894 struct lportdb *lp = NULL; 895 char *pt; 896 sns_ganrsp_t *resp = (sns_ganrsp_t *) arg; 897 u_int32_t portid; 898 u_int64_t wwpn, wwnn; 899 fcparam *fcp = isp->isp_param; 900 901 portid = 902 (((u_int32_t) resp->snscb_port_id[0]) << 16) | 903 (((u_int32_t) resp->snscb_port_id[1]) << 8) | 904 (((u_int32_t) resp->snscb_port_id[2])); 905 906 wwpn = 907 (((u_int64_t)resp->snscb_portname[0]) << 56) | 908 (((u_int64_t)resp->snscb_portname[1]) << 48) | 909 (((u_int64_t)resp->snscb_portname[2]) << 40) | 910 (((u_int64_t)resp->snscb_portname[3]) << 32) | 911 (((u_int64_t)resp->snscb_portname[4]) << 24) | 912 (((u_int64_t)resp->snscb_portname[5]) << 16) | 913 (((u_int64_t)resp->snscb_portname[6]) << 8) | 914 (((u_int64_t)resp->snscb_portname[7])); 915 916 wwnn = 917 (((u_int64_t)resp->snscb_nodename[0]) << 56) | 918 (((u_int64_t)resp->snscb_nodename[1]) << 48) | 919 (((u_int64_t)resp->snscb_nodename[2]) << 40) | 920 (((u_int64_t)resp->snscb_nodename[3]) << 32) | 921 (((u_int64_t)resp->snscb_nodename[4]) << 24) | 922 (((u_int64_t)resp->snscb_nodename[5]) << 16) | 923 (((u_int64_t)resp->snscb_nodename[6]) << 8) | 924 (((u_int64_t)resp->snscb_nodename[7])); 925 if (portid == 0 || wwpn == 0) { 926 break; 927 } 928 929 switch (resp->snscb_port_type) { 930 case 1: 931 pt = " N_Port"; 932 break; 933 case 2: 934 pt = " NL_Port"; 935 break; 936 case 3: 937 pt = "F/NL_Port"; 938 break; 939 case 0x7f: 940 pt = " Nx_Port"; 941 break; 942 case 0x81: 943 pt = " F_port"; 944 break; 945 case 0x82: 946 pt = " FL_Port"; 947 break; 948 case 0x84: 949 pt = " E_port"; 950 break; 951 default: 952 pt = "?"; 953 break; 954 } 955 isp_prt(isp, ISP_LOGINFO, 956 "%s @ 0x%x, Node 0x%08x%08x Port %08x%08x", 957 pt, portid, ((u_int32_t) (wwnn >> 32)), ((u_int32_t) wwnn), 958 ((u_int32_t) (wwpn >> 32)), ((u_int32_t) wwpn)); 959 /* 960 * We're only interested in SCSI_FCP types (for now) 961 */ 962 if ((resp->snscb_fc4_types[2] & 1) == 0) { 963 break; 964 } 965 if (fcp->isp_topo != TOPO_F_PORT) 966 lrange = FC_SNS_ID+1; 967 else 968 lrange = 0; 969 /* 970 * Is it already in our list? 971 */ 972 for (target = lrange; target < MAX_FC_TARG; target++) { 973 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 974 continue; 975 } 976 lp = &fcp->portdb[target]; 977 if (lp->port_wwn == wwpn && lp->node_wwn == wwnn) { 978 lp->fabric_dev = 1; 979 break; 980 } 981 } 982 if (target < MAX_FC_TARG) { 983 break; 984 } 985 for (target = lrange; target < MAX_FC_TARG; target++) { 986 if (target >= FL_PORT_ID && target <= FC_SNS_ID) { 987 continue; 988 } 989 lp = &fcp->portdb[target]; 990 if (lp->port_wwn == 0) { 991 break; 992 } 993 } 994 if (target == MAX_FC_TARG) { 995 isp_prt(isp, ISP_LOGWARN, 996 "no more space for fabric devices"); 997 break; 998 } 999 lp->node_wwn = wwnn; 1000 lp->port_wwn = wwpn; 1001 lp->portid = portid; 1002 lp->fabric_dev = 1; 1003 break; 1004 } 1005 case ISPASYNC_FW_CRASH: 1006 { 1007 u_int16_t mbox1, mbox6; 1008 mbox1 = ISP_READ(isp, OUTMAILBOX1); 1009 if (IS_DUALBUS(isp)) { 1010 mbox6 = ISP_READ(isp, OUTMAILBOX6); 1011 } else { 1012 mbox6 = 0; 1013 } 1014 isp_prt(isp, ISP_LOGERR, 1015 "Internal Firmware Error on bus %d @ RISC Address 0x%x", 1016 mbox6, mbox1); 1017 isp_reinit(isp); 1018 break; 1019 } 1020 default: 1021 break; 1022 } 1023 return (0); 1024 } 1025 1026 #include <machine/stdarg.h> 1027 void 1028 isp_prt(struct ispsoftc *isp, int level, const char *fmt, ...) 1029 { 1030 va_list ap; 1031 if (level != ISP_LOGALL && (level & isp->isp_dblev) == 0) { 1032 return; 1033 } 1034 printf("%s: ", isp->isp_name); 1035 va_start(ap, fmt); 1036 vprintf(fmt, ap); 1037 va_end(ap); 1038 printf("\n"); 1039 } 1040