Home | History | Annotate | Line # | Download | only in ic
isp_netbsd.c revision 1.25
      1 /* $NetBSD: isp_netbsd.c,v 1.25 2000/05/13 16:53:03 he Exp $ */
      2 /*
      3  * Platform (NetBSD) dependent common attachment code for Qlogic adapters.
      4  * Matthew Jacob <mjacob (at) nas.nasa.gov>
      5  */
      6 /*
      7  * Copyright (C) 1997, 1998, 1999 National Aeronautics & Space Administration
      8  * All rights reserved.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. The name of the author may not be used to endorse or promote products
     19  *    derived from this software without specific prior written permission
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  */
     32 
     33 #include <dev/ic/isp_netbsd.h>
     34 #include <sys/scsiio.h>
     35 
     36 static void ispminphys __P((struct buf *));
     37 static int32_t ispcmd_slow __P((ISP_SCSI_XFER_T *));
     38 static int32_t ispcmd __P((ISP_SCSI_XFER_T *));
     39 static int
     40 ispioctl __P((struct scsipi_link *, u_long, caddr_t, int, struct proc *));
     41 
     42 static struct scsipi_device isp_dev = { NULL, NULL, NULL, NULL };
     43 static int isp_poll __P((struct ispsoftc *, ISP_SCSI_XFER_T *, int));
     44 static void isp_watch __P((void *));
     45 static void isp_command_requeue __P((void *));
     46 static void isp_internal_restart __P((void *));
     47 
     48 /*
     49  * Complete attachment of hardware, include subdevices.
     50  */
     51 void
     52 isp_attach(isp)
     53 	struct ispsoftc *isp;
     54 {
     55 
     56 	isp->isp_osinfo._adapter.scsipi_minphys = ispminphys;
     57 	isp->isp_osinfo._adapter.scsipi_ioctl = ispioctl;
     58 
     59 	isp->isp_state = ISP_RUNSTATE;
     60 	isp->isp_osinfo._link.scsipi_scsi.channel =
     61 	    (IS_DUALBUS(isp))? 0 : SCSI_CHANNEL_ONLY_ONE;
     62 	isp->isp_osinfo._link.adapter_softc = isp;
     63 	isp->isp_osinfo._link.device = &isp_dev;
     64 	isp->isp_osinfo._link.adapter = &isp->isp_osinfo._adapter;
     65 	isp->isp_osinfo._link.openings = isp->isp_maxcmds;
     66 	TAILQ_INIT(&isp->isp_osinfo.waitq);	/* XXX 2nd Bus? */
     67 
     68 	if (IS_FC(isp)) {
     69 		/*
     70 		 * Give it another chance here to come alive...
     71 		 */
     72 		isp->isp_osinfo._adapter.scsipi_cmd = ispcmd;
     73 		isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_FC_TARG-1;
     74 #ifdef	ISP2100_SCCLUN
     75 		/*
     76 		 * 16 bits worth, but let's be reasonable..
     77 		 */
     78 		isp->isp_osinfo._link.scsipi_scsi.max_lun = 255;
     79 #else
     80 		isp->isp_osinfo._link.scsipi_scsi.max_lun = 15;
     81 #endif
     82 		/* set below */
     83 	} else {
     84 		sdparam *sdp = isp->isp_param;
     85 		isp->isp_osinfo._adapter.scsipi_cmd = ispcmd_slow;
     86 		isp->isp_osinfo._link.scsipi_scsi.max_target = MAX_TARGETS-1;
     87 		isp->isp_osinfo._link.scsipi_scsi.max_lun = 7;
     88 		isp->isp_osinfo._link.scsipi_scsi.adapter_target =
     89 		    sdp->isp_initiator_id;
     90 		isp->isp_osinfo.discovered[0] = 1 << sdp->isp_initiator_id;
     91 		if (IS_DUALBUS(isp)) {
     92 			isp->isp_osinfo._link_b = isp->isp_osinfo._link;
     93 			sdp++;
     94 			isp->isp_osinfo.discovered[1] =
     95 			    1 << sdp->isp_initiator_id;
     96 			isp->isp_osinfo._link_b.scsipi_scsi.adapter_target =
     97 			    sdp->isp_initiator_id;
     98 			isp->isp_osinfo._link_b.scsipi_scsi.channel = 1;
     99 		}
    100 	}
    101 	isp->isp_osinfo._link.type = BUS_SCSI;
    102 
    103 	/*
    104 	 * Send a SCSI Bus Reset.
    105 	 */
    106 	if (IS_SCSI(isp)) {
    107 		int bus = 0;
    108 		(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
    109 		if (IS_DUALBUS(isp)) {
    110 			bus++;
    111 			(void) isp_control(isp, ISPCTL_RESET_BUS, &bus);
    112 		}
    113 		SYS_DELAY(2*1000000);
    114 	} else {
    115 		int i, j;
    116 		fcparam *fcp = isp->isp_param;
    117 		delay(2 * 1000000);
    118 		for (j = 0; j < 5; j++) {
    119 			for (i = 0; i < 5; i++) {
    120 				if (isp_control(isp, ISPCTL_FCLINK_TEST, NULL))
    121 					continue;
    122 #ifdef	ISP2100_FABRIC
    123 				/*
    124 				 * Wait extra time to see if the f/w
    125 				 * eventually completed an FLOGI that
    126 				 * will allow us to know we're on a
    127 				 * fabric.
    128 				 */
    129 				if (fcp->isp_onfabric == 0) {
    130 					delay(1 * 1000000);
    131 					continue;
    132 				}
    133 #endif
    134 				break;
    135 			}
    136 			if (fcp->isp_fwstate == FW_READY &&
    137 			    fcp->isp_loopstate >= LOOP_PDB_RCVD) {
    138 				break;
    139 			}
    140 		}
    141 		isp->isp_osinfo._link.scsipi_scsi.adapter_target =
    142 			fcp->isp_loopid;
    143 	}
    144 
    145 	/*
    146 	 * Start the watchdog.
    147 	 */
    148 	callout_init(&isp->isp_osinfo._watchdog);
    149 	isp->isp_dogactive = 1;
    150 	callout_reset(&isp->isp_osinfo._watchdog, WATCH_INTERVAL * hz,
    151 	    isp_watch, isp);
    152 
    153 	/*
    154 	 * And attach children (if any).
    155 	 */
    156 	config_found((void *)isp, &isp->isp_osinfo._link, scsiprint);
    157 	if (IS_DUALBUS(isp)) {
    158 		config_found((void *)isp, &isp->isp_osinfo._link_b, scsiprint);
    159 	}
    160 }
    161 
    162 /*
    163  * minphys our xfers
    164  *
    165  * Unfortunately, the buffer pointer describes the target device- not the
    166  * adapter device, so we can't use the pointer to find out what kind of
    167  * adapter we are and adjust accordingly.
    168  */
    169 
    170 static void
    171 ispminphys(bp)
    172 	struct buf *bp;
    173 {
    174 	/*
    175 	 * XX: Only the 1020 has a 24 bit limit.
    176 	 */
    177 	if (bp->b_bcount >= (1 << 24)) {
    178 		bp->b_bcount = (1 << 24);
    179 	}
    180 	minphys(bp);
    181 }
    182 
    183 static int32_t
    184 ispcmd_slow(xs)
    185 	ISP_SCSI_XFER_T *xs;
    186 {
    187 	sdparam *sdp;
    188 	int tgt, chan, s;
    189 	u_int16_t flags;
    190 	struct ispsoftc *isp = XS_ISP(xs);
    191 
    192 	/*
    193 	 * Have we completed discovery for this target on this adapter?
    194 	 */
    195 	tgt = XS_TGT(xs);
    196 	chan = XS_CHANNEL(xs);
    197 	if ((xs->xs_control & XS_CTL_DISCOVERY) != 0 ||
    198 	    (isp->isp_osinfo.discovered[chan] & (1 << tgt)) != 0) {
    199 		return (ispcmd(xs));
    200 	}
    201 
    202 	flags = DPARM_DEFAULT;
    203 	if (xs->sc_link->quirks & SDEV_NOSYNC) {
    204 		flags ^= DPARM_SYNC;
    205 #ifdef	DEBUG
    206 	} else {
    207 		printf("%s: channel %d target %d can do SYNC xfers\n",
    208 		    isp->isp_name, chan, tgt);
    209 #endif
    210 	}
    211 	if (xs->sc_link->quirks & SDEV_NOWIDE) {
    212 		flags ^= DPARM_WIDE;
    213 #ifdef	DEBUG
    214 	} else {
    215 		printf("%s: channel %d target %d can do WIDE xfers\n",
    216 		    isp->isp_name, chan, tgt);
    217 #endif
    218 	}
    219 	if (xs->sc_link->quirks & SDEV_NOTAG) {
    220 		flags ^= DPARM_TQING;
    221 #ifdef	DEBUG
    222 	} else {
    223 		printf("%s: channel %d target %d can do TAGGED xfers\n",
    224 		    isp->isp_name, chan, tgt);
    225 #endif
    226 	}
    227 	/*
    228 	 * Okay, we know about this device now,
    229 	 * so mark parameters to be updated for it.
    230 	 */
    231 	s = splbio();
    232 	isp->isp_osinfo.discovered[chan] |= (1 << tgt);
    233 	sdp = isp->isp_param;
    234 	sdp += chan;
    235 	sdp->isp_devparam[tgt].dev_flags = flags;
    236 	sdp->isp_devparam[tgt].dev_update = 1;
    237 	isp->isp_update |= (1 << chan);
    238 	splx(s);
    239 	return (ispcmd(xs));
    240 }
    241 
    242 static int
    243 ispioctl(sc_link, cmd, addr, flag, p)
    244 	struct scsipi_link *sc_link;
    245 	u_long cmd;
    246 	caddr_t addr;
    247 	int flag;
    248 	struct proc *p;
    249 {
    250 	struct ispsoftc *isp = sc_link->adapter_softc;
    251 	int s, chan, retval = ENOTTY;
    252 
    253 	switch (cmd) {
    254 	case SCBUSIORESET:
    255 		chan = sc_link->scsipi_scsi.channel;
    256 		s = splbio();
    257 		if (isp_control(isp, ISPCTL_RESET_BUS, &chan))
    258 			retval = EIO;
    259 		else
    260 			retval = 0;
    261 		(void) splx(s);
    262 		break;
    263 	default:
    264 		break;
    265 	}
    266 	return (retval);
    267 }
    268 
    269 
    270 static int32_t
    271 ispcmd(xs)
    272 	ISP_SCSI_XFER_T *xs;
    273 {
    274 	struct ispsoftc *isp;
    275 	int result, s;
    276 
    277 	isp = XS_ISP(xs);
    278 	s = splbio();
    279 	if (isp->isp_state < ISP_RUNSTATE) {
    280 		DISABLE_INTS(isp);
    281 		isp_init(isp);
    282                 if (isp->isp_state != ISP_INITSTATE) {
    283 			ENABLE_INTS(isp);
    284                         (void) splx(s);
    285                         XS_SETERR(xs, HBA_BOTCH);
    286                         return (COMPLETE);
    287                 }
    288                 isp->isp_state = ISP_RUNSTATE;
    289 		ENABLE_INTS(isp);
    290         }
    291 
    292 	/*
    293 	 * Check for queue blockage...
    294 	 */
    295 	if (isp->isp_osinfo.blocked) {
    296 		if (xs->xs_control & XS_CTL_POLL) {
    297 			xs->error = XS_DRIVER_STUFFUP;
    298 			splx(s);
    299 			return (TRY_AGAIN_LATER);
    300 		}
    301 		TAILQ_INSERT_TAIL(&isp->isp_osinfo.waitq, xs, adapter_q);
    302 		splx(s);
    303 		return (SUCCESSFULLY_QUEUED);
    304 	}
    305 	DISABLE_INTS(isp);
    306 	result = ispscsicmd(xs);
    307 	ENABLE_INTS(isp);
    308 
    309 	if ((xs->xs_control & XS_CTL_POLL) == 0) {
    310 		switch (result) {
    311 		case CMD_QUEUED:
    312 			result = SUCCESSFULLY_QUEUED;
    313 			break;
    314 		case CMD_EAGAIN:
    315 			result = TRY_AGAIN_LATER;
    316 			break;
    317 		case CMD_RQLATER:
    318 			result = SUCCESSFULLY_QUEUED;
    319 			callout_reset(&xs->xs_callout, hz,
    320 			    isp_command_requeue, xs);
    321 			break;
    322 		case CMD_COMPLETE:
    323 			result = COMPLETE;
    324 			break;
    325 		}
    326 		(void) splx(s);
    327 		return (result);
    328 	}
    329 
    330 	switch (result) {
    331 	case CMD_QUEUED:
    332 		result = SUCCESSFULLY_QUEUED;
    333 		break;
    334 	case CMD_RQLATER:
    335 	case CMD_EAGAIN:
    336 		if (XS_NOERR(xs)) {
    337 			xs->error = XS_DRIVER_STUFFUP;
    338 		}
    339 		result = TRY_AGAIN_LATER;
    340 		break;
    341 	case CMD_COMPLETE:
    342 		result = COMPLETE;
    343 		break;
    344 
    345 	}
    346 	/*
    347 	 * If we can't use interrupts, poll on completion.
    348 	 */
    349 	if (result == SUCCESSFULLY_QUEUED) {
    350 		if (isp_poll(isp, xs, XS_TIME(xs))) {
    351 			/*
    352 			 * If no other error occurred but we didn't finish,
    353 			 * something bad happened.
    354 			 */
    355 			if (XS_IS_CMD_DONE(xs) == 0) {
    356 				if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
    357 					isp_restart(isp);
    358 				}
    359 				if (XS_NOERR(xs)) {
    360 					XS_SETERR(xs, HBA_BOTCH);
    361 				}
    362 			}
    363 		}
    364 		result = COMPLETE;
    365 	}
    366 	(void) splx(s);
    367 	return (result);
    368 }
    369 
    370 static int
    371 isp_poll(isp, xs, mswait)
    372 	struct ispsoftc *isp;
    373 	ISP_SCSI_XFER_T *xs;
    374 	int mswait;
    375 {
    376 
    377 	while (mswait) {
    378 		/* Try the interrupt handling routine */
    379 		(void)isp_intr((void *)isp);
    380 
    381 		/* See if the xs is now done */
    382 		if (XS_IS_CMD_DONE(xs)) {
    383 			return (0);
    384 		}
    385 		SYS_DELAY(1000);	/* wait one millisecond */
    386 		mswait--;
    387 	}
    388 	return (1);
    389 }
    390 
    391 static void
    392 isp_watch(arg)
    393 	void *arg;
    394 {
    395 	int i;
    396 	struct ispsoftc *isp = arg;
    397 	struct scsipi_xfer *xs;
    398 	int s;
    399 
    400 	/*
    401 	 * Look for completely dead commands (but not polled ones).
    402 	 */
    403 	s = splbio();
    404 	for (i = 0; i < isp->isp_maxcmds; i++) {
    405 		xs = isp->isp_xflist[i];
    406 		if (xs == NULL) {
    407 			continue;
    408 		}
    409 		if (xs->timeout == 0 || (xs->xs_control & XS_CTL_POLL)) {
    410 			continue;
    411 		}
    412 		xs->timeout -= (WATCH_INTERVAL * 1000);
    413 		/*
    414 		 * Avoid later thinking that this
    415 		 * transaction is not being timed.
    416 		 * Then give ourselves to watchdog
    417 		 * periods of grace.
    418 		 */
    419 		if (xs->timeout == 0) {
    420 			xs->timeout = 1;
    421 		} else if (xs->timeout > -(2 * WATCH_INTERVAL * 1000)) {
    422 			continue;
    423 		}
    424 		if (isp_control(isp, ISPCTL_ABORT_CMD, xs)) {
    425 			printf("%s: isp_watch failed to abort command\n",
    426 			    isp->isp_name);
    427 			isp_restart(isp);
    428 			break;
    429 		}
    430 	}
    431 	callout_reset(&isp->isp_osinfo._watchdog, WATCH_INTERVAL * hz,
    432 	    isp_watch, isp);
    433 	isp->isp_dogactive = 1;
    434 	(void) splx(s);
    435 }
    436 
    437 /*
    438  * Free any associated resources prior to decommissioning and
    439  * set the card to a known state (so it doesn't wake up and kick
    440  * us when we aren't expecting it to).
    441  *
    442  * Locks are held before coming here.
    443  */
    444 void
    445 isp_uninit(isp)
    446 	struct ispsoftc *isp;
    447 {
    448 	ISP_ILOCKVAL_DECL;
    449 	ISP_ILOCK(isp);
    450 	/*
    451 	 * Leave with interrupts disabled.
    452 	 */
    453 	DISABLE_INTS(isp);
    454 
    455 	/*
    456 	 * Turn off the watchdog (if active).
    457 	 */
    458 	if (isp->isp_dogactive) {
    459 		callout_stop(&isp->isp_osinfo._watchdog);
    460 		isp->isp_dogactive = 0;
    461 	}
    462 
    463 	ISP_IUNLOCK(isp);
    464 }
    465 
    466 /*
    467  * Restart function for a command to be requeued later.
    468  */
    469 static void
    470 isp_command_requeue(arg)
    471 	void *arg;
    472 {
    473 	struct scsipi_xfer *xs = arg;
    474 	struct ispsoftc *isp = XS_ISP(xs);
    475 	int s = splbio();
    476 	switch (ispcmd_slow(xs)) {
    477 	case SUCCESSFULLY_QUEUED:
    478 		printf("%s: isp_command_requeue: requeued for %d.%d\n",
    479 		    isp->isp_name, XS_TGT(xs), XS_LUN(xs));
    480 		break;
    481 	case TRY_AGAIN_LATER:
    482 		printf("%s: EAGAIN for %d.%d\n",
    483 		    isp->isp_name, XS_TGT(xs), XS_LUN(xs));
    484 		/* FALLTHROUGH */
    485 	case COMPLETE:
    486 		/* can only be an error */
    487 		xs->xs_status |= XS_STS_DONE;
    488 		if (XS_NOERR(xs)) {
    489 			XS_SETERR(xs, HBA_BOTCH);
    490 		}
    491 		scsipi_done(xs);
    492 		break;
    493 	}
    494 	(void) splx(s);
    495 }
    496 
    497 /*
    498  * Restart function after a LOOP UP event (e.g.),
    499  * done as a timeout for some hysteresis.
    500  */
    501 static void
    502 isp_internal_restart(arg)
    503 	void *arg;
    504 {
    505 	struct ispsoftc *isp = arg;
    506 	int result, nrestarted = 0, s;
    507 
    508 	s = splbio();
    509 	if (isp->isp_osinfo.blocked == 0) {
    510 		struct scsipi_xfer *xs;
    511 		while ((xs = TAILQ_FIRST(&isp->isp_osinfo.waitq)) != NULL) {
    512 			TAILQ_REMOVE(&isp->isp_osinfo.waitq, xs, adapter_q);
    513 			DISABLE_INTS(isp);
    514 			result = ispscsicmd(xs);
    515 			ENABLE_INTS(isp);
    516 			if (result != CMD_QUEUED) {
    517 				printf("%s: botched command restart (0x%x)\n",
    518 				    isp->isp_name, result);
    519 				xs->xs_status |= XS_STS_DONE;
    520 				if (xs->error == XS_NOERROR)
    521 					xs->error = XS_DRIVER_STUFFUP;
    522 				scsipi_done(xs);
    523 			}
    524 			nrestarted++;
    525 		}
    526 		printf("%s: requeued %d commands\n", isp->isp_name, nrestarted);
    527 	}
    528 	(void) splx(s);
    529 }
    530 
    531 int
    532 isp_async(isp, cmd, arg)
    533 	struct ispsoftc *isp;
    534 	ispasync_t cmd;
    535 	void *arg;
    536 {
    537 	int bus, tgt;
    538 	int s = splbio();
    539 	switch (cmd) {
    540 	case ISPASYNC_NEW_TGT_PARAMS:
    541 	if (IS_SCSI(isp) && isp->isp_dblev) {
    542 		sdparam *sdp = isp->isp_param;
    543 		char *wt;
    544 		int mhz, flags, period;
    545 
    546 		tgt = *((int *) arg);
    547 		bus = (tgt >> 16) & 0xffff;
    548 		tgt &= 0xffff;
    549 		sdp += bus;
    550 		flags = sdp->isp_devparam[tgt].cur_dflags;
    551 		period = sdp->isp_devparam[tgt].cur_period;
    552 
    553 		if ((flags & DPARM_SYNC) && period &&
    554 		    (sdp->isp_devparam[tgt].cur_offset) != 0) {
    555 #if	0
    556 			/* CAUSES PANICS */
    557 			static char *m = "%s: bus %d now %s mode\n";
    558 			u_int16_t r, l;
    559 			if (bus == 1)
    560 				r = SXP_PINS_DIFF | SXP_BANK1_SELECT;
    561 			else
    562 				r = SXP_PINS_DIFF;
    563 			l = ISP_READ(isp, r) & ISP1080_MODE_MASK;
    564 			switch (l) {
    565 			case ISP1080_LVD_MODE:
    566 				sdp->isp_lvdmode = 1;
    567 				printf(m, isp->isp_name, bus, "LVD");
    568 				break;
    569 			case ISP1080_HVD_MODE:
    570 				sdp->isp_diffmode = 1;
    571 				printf(m, isp->isp_name, bus, "Differential");
    572 				break;
    573 			case ISP1080_SE_MODE:
    574 				sdp->isp_ultramode = 1;
    575 				printf(m, isp->isp_name, bus, "Single-Ended");
    576 				break;
    577 			default:
    578 				printf("%s: unknown mode on bus %d (0x%x)\n",
    579 				    isp->isp_name, bus, l);
    580 				break;
    581 			}
    582 #endif
    583 			/*
    584 			 * There's some ambiguity about our negotiated speed
    585 			 * if we haven't detected LVD mode correctly (which
    586 			 * seems to happen, unfortunately). If we're in LVD
    587 			 * mode, then different rules apply about speed.
    588 			 */
    589 			if (sdp->isp_lvdmode || period < 0xc) {
    590 				switch (period) {
    591 				case 0x9:
    592 					mhz = 80;
    593 					break;
    594 				case 0xa:
    595 					mhz = 40;
    596 					break;
    597 				case 0xb:
    598 					mhz = 33;
    599 					break;
    600 				case 0xc:
    601 					mhz = 25;
    602 					break;
    603 				default:
    604 					mhz = 1000 / (period * 4);
    605 					break;
    606 				}
    607 			} else {
    608 				mhz = 1000 / (period * 4);
    609 			}
    610 		} else {
    611 			mhz = 0;
    612 		}
    613 		switch (flags & (DPARM_WIDE|DPARM_TQING)) {
    614 		case DPARM_WIDE:
    615 			wt = ", 16 bit wide\n";
    616 			break;
    617 		case DPARM_TQING:
    618 			wt = ", Tagged Queueing Enabled\n";
    619 			break;
    620 		case DPARM_WIDE|DPARM_TQING:
    621 			wt = ", 16 bit wide, Tagged Queueing Enabled\n";
    622 			break;
    623 		default:
    624 			wt = "\n";
    625 			break;
    626 		}
    627 		if (mhz) {
    628 			CFGPRINTF("%s: Bus %d Target %d at %dMHz Max "
    629 			    "Offset %d%s", isp->isp_name, bus, tgt, mhz,
    630 			    sdp->isp_devparam[tgt].cur_offset, wt);
    631 		} else {
    632 			CFGPRINTF("%s: Bus %d Target %d Async Mode%s",
    633 			    isp->isp_name, bus, tgt, wt);
    634 		}
    635 		break;
    636 	}
    637 	case ISPASYNC_BUS_RESET:
    638 		if (arg)
    639 			bus = *((int *) arg);
    640 		else
    641 			bus = 0;
    642 		printf("%s: SCSI bus %d reset detected\n", isp->isp_name, bus);
    643 		break;
    644 	case ISPASYNC_LOOP_DOWN:
    645 		/*
    646 		 * Hopefully we get here in time to minimize the number
    647 		 * of commands we are firing off that are sure to die.
    648 		 */
    649 		isp->isp_osinfo.blocked = 1;
    650 		printf("%s: Loop DOWN\n", isp->isp_name);
    651 		break;
    652         case ISPASYNC_LOOP_UP:
    653 		isp->isp_osinfo.blocked = 0;
    654 		callout_reset(&isp->isp_osinfo._restart, 1,
    655 		    isp_internal_restart, isp);
    656 		printf("%s: Loop UP\n", isp->isp_name);
    657 		break;
    658 	case ISPASYNC_PDB_CHANGED:
    659 	if (IS_FC(isp) && isp->isp_dblev) {
    660 		const char *fmt = "%s: Target %d (Loop 0x%x) Port ID 0x%x "
    661 		    "role %s %s\n Port WWN 0x%08x%08x\n Node WWN 0x%08x%08x\n";
    662 		const static char *roles[4] = {
    663 		    "No", "Target", "Initiator", "Target/Initiator"
    664 		};
    665 		char *ptr;
    666 		fcparam *fcp = isp->isp_param;
    667 		int tgt = *((int *) arg);
    668 		struct lportdb *lp = &fcp->portdb[tgt];
    669 
    670 		if (lp->valid) {
    671 			ptr = "arrived";
    672 		} else {
    673 			ptr = "disappeared";
    674 		}
    675 		printf(fmt, isp->isp_name, tgt, lp->loopid, lp->portid,
    676 		    roles[lp->roles & 0x3], ptr,
    677 		    (u_int32_t) (lp->port_wwn >> 32),
    678 		    (u_int32_t) (lp->port_wwn & 0xffffffffLL),
    679 		    (u_int32_t) (lp->node_wwn >> 32),
    680 		    (u_int32_t) (lp->node_wwn & 0xffffffffLL));
    681 		break;
    682 	}
    683 #ifdef	ISP2100_FABRIC
    684 	case ISPASYNC_CHANGE_NOTIFY:
    685 		printf("%s: Name Server Database Changed\n", isp->isp_name);
    686 		break;
    687 	case ISPASYNC_FABRIC_DEV:
    688 	{
    689 		int target;
    690 		struct lportdb *lp;
    691 		sns_scrsp_t *resp = (sns_scrsp_t *) arg;
    692 		u_int32_t portid;
    693 		u_int64_t wwn;
    694 		fcparam *fcp = isp->isp_param;
    695 
    696 		portid =
    697 		    (((u_int32_t) resp->snscb_port_id[0]) << 16) |
    698 		    (((u_int32_t) resp->snscb_port_id[1]) << 8) |
    699 		    (((u_int32_t) resp->snscb_port_id[2]));
    700 		wwn =
    701 		    (((u_int64_t)resp->snscb_portname[0]) << 56) |
    702 		    (((u_int64_t)resp->snscb_portname[1]) << 48) |
    703 		    (((u_int64_t)resp->snscb_portname[2]) << 40) |
    704 		    (((u_int64_t)resp->snscb_portname[3]) << 32) |
    705 		    (((u_int64_t)resp->snscb_portname[4]) << 24) |
    706 		    (((u_int64_t)resp->snscb_portname[5]) << 16) |
    707 		    (((u_int64_t)resp->snscb_portname[6]) <<  8) |
    708 		    (((u_int64_t)resp->snscb_portname[7]));
    709 		printf("%s: Fabric Device (Type 0x%x)@PortID 0x%x WWN "
    710 		    "0x%08x%08x\n", isp->isp_name, resp->snscb_port_type,
    711 		    portid, ((u_int32_t)(wwn >> 32)),
    712 		    ((u_int32_t)(wwn & 0xffffffff)));
    713 		if (resp->snscb_port_type != 2)
    714 			break;
    715 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
    716 			lp = &fcp->portdb[target];
    717 			if (lp->port_wwn == wwn)
    718 				break;
    719 		}
    720 		if (target < MAX_FC_TARG) {
    721 			break;
    722 		}
    723 		for (target = FC_SNS_ID+1; target < MAX_FC_TARG; target++) {
    724 			lp = &fcp->portdb[target];
    725 			if (lp->port_wwn == 0)
    726 				break;
    727 		}
    728 		if (target == MAX_FC_TARG) {
    729 			printf("%s: no more space for fabric devices\n",
    730 			    isp->isp_name);
    731 			return (-1);
    732 		}
    733 		lp->port_wwn = lp->node_wwn = wwn;
    734 		lp->portid = portid;
    735 		break;
    736 	}
    737 #endif
    738 	default:
    739 		break;
    740 	}
    741 	(void) splx(s);
    742 	return (0);
    743 }
    744