xref: /freebsd/sys/dev/isp/isp.c (revision 36daf0495aa68d669ac6abf004940ec1b1e83e42)
1 /*-
2  *  Copyright (c) 1997-2009 by Matthew Jacob
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions
7  *  are met:
8  *
9  *  1. Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  *  2. Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  *
15  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  *  SUCH DAMAGE.
26  *
27  */
28 
29 /*
30  * Machine and OS Independent (well, as best as possible)
31  * code for the Qlogic ISP SCSI and FC-SCSI adapters.
32  */
33 
34 /*
35  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
36  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
37  * ideas dredged from the Solaris driver.
38  */
39 
40 /*
41  * Include header file appropriate for platform we're building on.
42  */
43 #ifdef	__NetBSD__
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD$");
46 #include <dev/ic/isp_netbsd.h>
47 #endif
48 #ifdef	__FreeBSD__
49 #include <sys/cdefs.h>
50 __FBSDID("$FreeBSD$");
51 #include <dev/isp/isp_freebsd.h>
52 #endif
53 #ifdef	__OpenBSD__
54 #include <dev/ic/isp_openbsd.h>
55 #endif
56 #ifdef	__linux__
57 #include "isp_linux.h"
58 #endif
59 #ifdef	__svr4__
60 #include "isp_solaris.h"
61 #endif
62 
63 /*
64  * General defines
65  */
66 #define	MBOX_DELAY_COUNT	1000000 / 100
67 #define	ISP_MARK_PORTDB(a, b, c)				\
68     isp_prt(isp, ISP_LOGSANCFG, 				\
69 	"Chan %d ISP_MARK_PORTDB@LINE %d", b, __LINE__);	\
70     isp_mark_portdb(a, b, c)
71 
72 /*
73  * Local static data
74  */
75 static const char fconf[] = "Chan %d PortDB[%d] changed:\n current =(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)\n database=(0x%x@0x%06x 0x%08x%08x 0x%08x%08x)";
76 static const char notresp[] = "Not RESPONSE in RESPONSE Queue (type 0x%x) @ idx %d (next %d) nlooked %d";
77 static const char topology[] = "Chan %d WWPN 0x%08x%08x PortID 0x%06x N-Port Handle %d, Connection '%s'";
78 static const char sc4[] = "NVRAM";
79 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
80 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
81 static const char sacq[] = "unable to acquire scratch area";
82 
83 static const uint8_t alpa_map[] = {
84 	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
85 	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
86 	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
87 	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
88 	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
89 	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
90 	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
91 	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
92 	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
93 	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
94 	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
95 	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
96 	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
97 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
98 	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
99 	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
100 };
101 
102 /*
103  * Local function prototypes.
104  */
105 static int isp_parse_async(ispsoftc_t *, uint16_t);
106 static int isp_parse_async_fc(ispsoftc_t *, uint16_t);
107 static int isp_handle_other_response(ispsoftc_t *, int, isphdr_t *, uint32_t *);
108 static void isp_parse_status(ispsoftc_t *, ispstatusreq_t *, XS_T *, long *); static void
109 isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *, long *);
110 static void isp_fastpost_complete(ispsoftc_t *, uint32_t);
111 static int isp_mbox_continue(ispsoftc_t *);
112 static void isp_scsi_init(ispsoftc_t *);
113 static void isp_scsi_channel_init(ispsoftc_t *, int);
114 static void isp_fibre_init(ispsoftc_t *);
115 static void isp_fibre_init_2400(ispsoftc_t *);
116 static void isp_mark_portdb(ispsoftc_t *, int, int);
117 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int, int);
118 static int isp_port_login(ispsoftc_t *, uint16_t, uint32_t);
119 static int isp_port_logout(ispsoftc_t *, uint16_t, uint32_t);
120 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *, int);
121 static void isp_dump_chip_portdb(ispsoftc_t *, int, int);
122 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
123 static int isp_fclink_test(ispsoftc_t *, int, int);
124 static int isp_pdb_sync(ispsoftc_t *, int);
125 static int isp_scan_loop(ispsoftc_t *, int);
126 static int isp_gid_ft_sns(ispsoftc_t *, int);
127 static int isp_gid_ft_ct_passthru(ispsoftc_t *, int);
128 static int isp_scan_fabric(ispsoftc_t *, int);
129 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
130 static int isp_register_fc4_type(ispsoftc_t *, int);
131 static int isp_register_fc4_type_24xx(ispsoftc_t *, int);
132 static uint16_t isp_nxt_handle(ispsoftc_t *, int, uint16_t);
133 static void isp_fw_state(ispsoftc_t *, int);
134 static void isp_mboxcmd_qnw(ispsoftc_t *, mbreg_t *, int);
135 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
136 
137 static void isp_spi_update(ispsoftc_t *, int);
138 static void isp_setdfltsdparm(ispsoftc_t *);
139 static void isp_setdfltfcparm(ispsoftc_t *, int);
140 static int isp_read_nvram(ispsoftc_t *, int);
141 static int isp_read_nvram_2400(ispsoftc_t *, uint8_t *);
142 static void isp_rdnvram_word(ispsoftc_t *, int, uint16_t *);
143 static void isp_rd_2400_nvram(ispsoftc_t *, uint32_t, uint32_t *);
144 static void isp_parse_nvram_1020(ispsoftc_t *, uint8_t *);
145 static void isp_parse_nvram_1080(ispsoftc_t *, int, uint8_t *);
146 static void isp_parse_nvram_12160(ispsoftc_t *, int, uint8_t *);
147 static void isp_parse_nvram_2100(ispsoftc_t *, uint8_t *);
148 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
149 
150 /*
151  * Reset Hardware.
152  *
153  * Hit the chip over the head, download new f/w if available and set it running.
154  *
155  * Locking done elsewhere.
156  */
157 
158 void
159 isp_reset(ispsoftc_t *isp, int do_load_defaults)
160 {
161 	mbreg_t mbs;
162 	uint32_t code_org, val;
163 	int loops, i, dodnld = 1;
164 	const char *btype = "????";
165 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
166 
167 	isp->isp_state = ISP_NILSTATE;
168 	if (isp->isp_dead) {
169 		isp_shutdown(isp);
170 		ISP_DISABLE_INTS(isp);
171 		return;
172 	}
173 
174 	/*
175 	 * Basic types (SCSI, FibreChannel and PCI or SBus)
176 	 * have been set in the MD code. We figure out more
177 	 * here. Possibly more refined types based upon PCI
178 	 * identification. Chip revision has been gathered.
179 	 *
180 	 * After we've fired this chip up, zero out the conf1 register
181 	 * for SCSI adapters and do other settings for the 2100.
182 	 */
183 
184 	ISP_DISABLE_INTS(isp);
185 
186 	/*
187 	 * Pick an initial maxcmds value which will be used
188 	 * to allocate xflist pointer space. It may be changed
189 	 * later by the firmware.
190 	 */
191 	if (IS_24XX(isp)) {
192 		isp->isp_maxcmds = 4096;
193 	} else if (IS_2322(isp)) {
194 		isp->isp_maxcmds = 2048;
195 	} else if (IS_23XX(isp) || IS_2200(isp)) {
196 		isp->isp_maxcmds = 1024;
197  	} else {
198 		isp->isp_maxcmds = 512;
199 	}
200 
201 	/*
202 	 * Set up DMA for the request and response queues.
203 	 *
204 	 * We do this now so we can use the request queue
205 	 * for dma to load firmware from.
206 	 */
207 	if (ISP_MBOXDMASETUP(isp) != 0) {
208 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
209 		return;
210 	}
211 
212 	/*
213 	 * Set up default request/response queue in-pointer/out-pointer
214 	 * register indices.
215 	 */
216 	if (IS_24XX(isp)) {
217 		isp->isp_rqstinrp = BIU2400_REQINP;
218 		isp->isp_rqstoutrp = BIU2400_REQOUTP;
219 		isp->isp_respinrp = BIU2400_RSPINP;
220 		isp->isp_respoutrp = BIU2400_RSPOUTP;
221 	} else if (IS_23XX(isp)) {
222 		isp->isp_rqstinrp = BIU_REQINP;
223 		isp->isp_rqstoutrp = BIU_REQOUTP;
224 		isp->isp_respinrp = BIU_RSPINP;
225 		isp->isp_respoutrp = BIU_RSPOUTP;
226 	} else {
227 		isp->isp_rqstinrp = INMAILBOX4;
228 		isp->isp_rqstoutrp = OUTMAILBOX4;
229 		isp->isp_respinrp = OUTMAILBOX5;
230 		isp->isp_respoutrp = INMAILBOX5;
231 	}
232 
233 	/*
234 	 * Put the board into PAUSE mode (so we can read the SXP registers
235 	 * or write FPM/FBM registers).
236 	 */
237 	if (IS_24XX(isp)) {
238 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
239 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
240 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
241 	} else {
242 		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
243 	}
244 
245 	if (IS_FC(isp)) {
246 		switch (isp->isp_type) {
247 		case ISP_HA_FC_2100:
248 			btype = "2100";
249 			break;
250 		case ISP_HA_FC_2200:
251 			btype = "2200";
252 			break;
253 		case ISP_HA_FC_2300:
254 			btype = "2300";
255 			break;
256 		case ISP_HA_FC_2312:
257 			btype = "2312";
258 			break;
259 		case ISP_HA_FC_2322:
260 			btype = "2322";
261 			break;
262 		case ISP_HA_FC_2400:
263 			btype = "2422";
264 			break;
265 		case ISP_HA_FC_2500:
266 			btype = "2532";
267 			break;
268 		default:
269 			break;
270 		}
271 
272 		if (!IS_24XX(isp)) {
273 			/*
274 			 * While we're paused, reset the FPM module and FBM
275 			 * fifos.
276 			 */
277 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
278 			ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
279 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
280 			ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
281 			ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
282 		}
283 	} else if (IS_1240(isp)) {
284 		sdparam *sdp;
285 
286 		btype = "1240";
287 		isp->isp_clock = 60;
288 		sdp = SDPARAM(isp, 0);
289 		sdp->isp_ultramode = 1;
290 		sdp = SDPARAM(isp, 1);
291 		sdp->isp_ultramode = 1;
292 		/*
293 		 * XXX: Should probably do some bus sensing.
294 		 */
295 	} else if (IS_ULTRA3(isp)) {
296 		sdparam *sdp = isp->isp_param;
297 
298 		isp->isp_clock = 100;
299 
300 		if (IS_10160(isp))
301 			btype = "10160";
302 		else if (IS_12160(isp))
303 			btype = "12160";
304 		else
305 			btype = "<UNKLVD>";
306 		sdp->isp_lvdmode = 1;
307 
308 		if (IS_DUALBUS(isp)) {
309 			sdp++;
310 			sdp->isp_lvdmode = 1;
311 		}
312 	} else if (IS_ULTRA2(isp)) {
313 		static const char m[] = "bus %d is in %s Mode";
314 		uint16_t l;
315 		sdparam *sdp = SDPARAM(isp, 0);
316 
317 		isp->isp_clock = 100;
318 
319 		if (IS_1280(isp))
320 			btype = "1280";
321 		else if (IS_1080(isp))
322 			btype = "1080";
323 		else
324 			btype = "<UNKLVD>";
325 
326 		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
327 		switch (l) {
328 		case ISP1080_LVD_MODE:
329 			sdp->isp_lvdmode = 1;
330 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "LVD");
331 			break;
332 		case ISP1080_HVD_MODE:
333 			sdp->isp_diffmode = 1;
334 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Differential");
335 			break;
336 		case ISP1080_SE_MODE:
337 			sdp->isp_ultramode = 1;
338 			isp_prt(isp, ISP_LOGCONFIG, m, 0, "Single-Ended");
339 			break;
340 		default:
341 			isp_prt(isp, ISP_LOGERR,
342 			    "unknown mode on bus %d (0x%x)", 0, l);
343 			break;
344 		}
345 
346 		if (IS_DUALBUS(isp)) {
347 			sdp = SDPARAM(isp, 1);
348 			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
349 			l &= ISP1080_MODE_MASK;
350 			switch (l) {
351 			case ISP1080_LVD_MODE:
352 				sdp->isp_lvdmode = 1;
353 				isp_prt(isp, ISP_LOGCONFIG, m, 1, "LVD");
354 				break;
355 			case ISP1080_HVD_MODE:
356 				sdp->isp_diffmode = 1;
357 				isp_prt(isp, ISP_LOGCONFIG,
358 				    m, 1, "Differential");
359 				break;
360 			case ISP1080_SE_MODE:
361 				sdp->isp_ultramode = 1;
362 				isp_prt(isp, ISP_LOGCONFIG,
363 				    m, 1, "Single-Ended");
364 				break;
365 			default:
366 				isp_prt(isp, ISP_LOGERR,
367 				    "unknown mode on bus %d (0x%x)", 1, l);
368 				break;
369 			}
370 		}
371 	} else {
372 		sdparam *sdp = SDPARAM(isp, 0);
373 		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
374 		switch (i) {
375 		default:
376 			isp_prt(isp, ISP_LOGALL, "Unknown Chip Type 0x%x", i);
377 			/* FALLTHROUGH */
378 		case 1:
379 			btype = "1020";
380 			isp->isp_type = ISP_HA_SCSI_1020;
381 			isp->isp_clock = 40;
382 			break;
383 		case 2:
384 			/*
385 			 * Some 1020A chips are Ultra Capable, but don't
386 			 * run the clock rate up for that unless told to
387 			 * do so by the Ultra Capable bits being set.
388 			 */
389 			btype = "1020A";
390 			isp->isp_type = ISP_HA_SCSI_1020A;
391 			isp->isp_clock = 40;
392 			break;
393 		case 3:
394 			btype = "1040";
395 			isp->isp_type = ISP_HA_SCSI_1040;
396 			isp->isp_clock = 60;
397 			break;
398 		case 4:
399 			btype = "1040A";
400 			isp->isp_type = ISP_HA_SCSI_1040A;
401 			isp->isp_clock = 60;
402 			break;
403 		case 5:
404 			btype = "1040B";
405 			isp->isp_type = ISP_HA_SCSI_1040B;
406 			isp->isp_clock = 60;
407 			break;
408 		case 6:
409 			btype = "1040C";
410 			isp->isp_type = ISP_HA_SCSI_1040C;
411 			isp->isp_clock = 60;
412                         break;
413 		}
414 		/*
415 		 * Now, while we're at it, gather info about ultra
416 		 * and/or differential mode.
417 		 */
418 		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
419 			isp_prt(isp, ISP_LOGCONFIG, "Differential Mode");
420 			sdp->isp_diffmode = 1;
421 		} else {
422 			sdp->isp_diffmode = 0;
423 		}
424 		i = ISP_READ(isp, RISC_PSR);
425 		if (isp->isp_bustype == ISP_BT_SBUS) {
426 			i &= RISC_PSR_SBUS_ULTRA;
427 		} else {
428 			i &= RISC_PSR_PCI_ULTRA;
429 		}
430 		if (i != 0) {
431 			isp_prt(isp, ISP_LOGCONFIG, "Ultra Mode Capable");
432 			sdp->isp_ultramode = 1;
433 			/*
434 			 * If we're in Ultra Mode, we have to be 60MHz clock-
435 			 * even for the SBus version.
436 			 */
437 			isp->isp_clock = 60;
438 		} else {
439 			sdp->isp_ultramode = 0;
440 			/*
441 			 * Clock is known. Gronk.
442 			 */
443 		}
444 
445 		/*
446 		 * Machine dependent clock (if set) overrides
447 		 * our generic determinations.
448 		 */
449 		if (isp->isp_mdvec->dv_clock) {
450 			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
451 				isp->isp_clock = isp->isp_mdvec->dv_clock;
452 			}
453 		}
454 
455 	}
456 
457 	/*
458 	 * Clear instrumentation
459 	 */
460 	isp->isp_intcnt = isp->isp_intbogus = 0;
461 
462 	/*
463 	 * Do MD specific pre initialization
464 	 */
465 	ISP_RESET0(isp);
466 
467 	/*
468 	 * Hit the chip over the head with hammer,
469 	 * and give it a chance to recover.
470 	 */
471 
472 	if (IS_SCSI(isp)) {
473 		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
474 		/*
475 		 * A slight delay...
476 		 */
477 		ISP_DELAY(100);
478 
479 		/*
480 		 * Clear data && control DMA engines.
481 		 */
482 		ISP_WRITE(isp, CDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
483 		ISP_WRITE(isp, DDMA_CONTROL, DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
484 
485 
486 	} else if (IS_24XX(isp)) {
487 		/*
488 		 * Stop DMA and wait for it to stop.
489 		 */
490 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
491 		for (val = loops = 0; loops < 30000; loops++) {
492 			ISP_DELAY(10);
493 			val = ISP_READ(isp, BIU2400_CSR);
494 			if ((val & BIU2400_DMA_ACTIVE) == 0) {
495 				break;
496 			}
497 		}
498 		if (val & BIU2400_DMA_ACTIVE) {
499 			ISP_RESET0(isp);
500 			isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
501 			return;
502 		}
503 		/*
504 		 * Hold it in SOFT_RESET and STOP state for 100us.
505 		 */
506 		ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
507 		ISP_DELAY(100);
508 		for (loops = 0; loops < 10000; loops++) {
509 			ISP_DELAY(5);
510 			val = ISP_READ(isp, OUTMAILBOX0);
511 		}
512 		for (val = loops = 0; loops < 500000; loops ++) {
513 			val = ISP_READ(isp, BIU2400_CSR);
514 			if ((val & BIU2400_SOFT_RESET) == 0) {
515 				break;
516 			}
517 		}
518 		if (val & BIU2400_SOFT_RESET) {
519 			ISP_RESET0(isp);
520 			isp_prt(isp, ISP_LOGERR, "Failed to come out of reset");
521 			return;
522 		}
523 	} else {
524 		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
525 		/*
526 		 * A slight delay...
527 		 */
528 		ISP_DELAY(100);
529 
530 		/*
531 		 * Clear data && control DMA engines.
532 		 */
533 		ISP_WRITE(isp, CDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
534 		ISP_WRITE(isp, TDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
535 		ISP_WRITE(isp, RDMA2100_CONTROL, DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
536 	}
537 
538 	/*
539 	 * Wait for ISP to be ready to go...
540 	 */
541 	loops = MBOX_DELAY_COUNT;
542 	for (;;) {
543 		if (IS_SCSI(isp)) {
544 			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET)) {
545 				break;
546 			}
547 		} else if (IS_24XX(isp)) {
548 			if (ISP_READ(isp, OUTMAILBOX0) == 0) {
549 				break;
550 			}
551 		} else {
552 			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
553 				break;
554 		}
555 		ISP_DELAY(100);
556 		if (--loops < 0) {
557 			ISP_DUMPREGS(isp, "chip reset timed out");
558 			ISP_RESET0(isp);
559 			return;
560 		}
561 	}
562 
563 	/*
564 	 * After we've fired this chip up, zero out the conf1 register
565 	 * for SCSI adapters and other settings for the 2100.
566 	 */
567 
568 	if (IS_SCSI(isp)) {
569 		ISP_WRITE(isp, BIU_CONF1, 0);
570 	} else if (!IS_24XX(isp)) {
571 		ISP_WRITE(isp, BIU2100_CSR, 0);
572 	}
573 
574 	/*
575 	 * Reset RISC Processor
576 	 */
577 	if (IS_24XX(isp)) {
578 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
579 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
580 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
581 	} else {
582 		ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
583 		ISP_DELAY(100);
584 		ISP_WRITE(isp, BIU_SEMA, 0);
585 	}
586 
587 	/*
588 	 * Post-RISC Reset stuff.
589 	 */
590 	if (IS_24XX(isp)) {
591 		for (val = loops = 0; loops < 5000000; loops++) {
592 			ISP_DELAY(5);
593 			val = ISP_READ(isp, OUTMAILBOX0);
594 			if (val == 0) {
595 				break;
596 			}
597 		}
598 		if (val != 0) {
599 			ISP_RESET0(isp);
600 			isp_prt(isp, ISP_LOGERR, "reset didn't clear");
601 			return;
602 		}
603 	} else if (IS_SCSI(isp)) {
604 		uint16_t tmp = isp->isp_mdvec->dv_conf1;
605 		/*
606 		 * Busted FIFO. Turn off all but burst enables.
607 		 */
608 		if (isp->isp_type == ISP_HA_SCSI_1040A) {
609 			tmp &= BIU_BURST_ENABLE;
610 		}
611 		ISP_SETBITS(isp, BIU_CONF1, tmp);
612 		if (tmp & BIU_BURST_ENABLE) {
613 			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
614 			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
615 		}
616 		if (SDPARAM(isp, 0)->isp_ptisp) {
617 			if (SDPARAM(isp, 0)->isp_ultramode) {
618 				while (ISP_READ(isp, RISC_MTR) != 0x1313) {
619 					ISP_WRITE(isp, RISC_MTR, 0x1313);
620 					ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
621 				}
622 			} else {
623 				ISP_WRITE(isp, RISC_MTR, 0x1212);
624 			}
625 			/*
626 			 * PTI specific register
627 			 */
628 			ISP_WRITE(isp, RISC_EMB, DUAL_BANK);
629 		} else {
630 			ISP_WRITE(isp, RISC_MTR, 0x1212);
631 		}
632 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
633 	} else {
634 		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
635 		if (IS_2200(isp) || IS_23XX(isp)) {
636 			ISP_WRITE(isp, HCCR, HCCR_2X00_DISABLE_PARITY_PAUSE);
637 		}
638 		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
639 	}
640 
641 	ISP_WRITE(isp, isp->isp_rqstinrp, 0);
642 	ISP_WRITE(isp, isp->isp_rqstoutrp, 0);
643 	ISP_WRITE(isp, isp->isp_respinrp, 0);
644 	ISP_WRITE(isp, isp->isp_respoutrp, 0);
645 	if (IS_24XX(isp)) {
646 		ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
647 		ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
648 		ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
649 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
650 	}
651 
652 	/*
653 	 * Do MD specific post initialization
654 	 */
655 	ISP_RESET1(isp);
656 
657 	/*
658 	 * Wait for everything to finish firing up.
659 	 *
660 	 * Avoid doing this on early 2312s because you can generate a PCI
661 	 * parity error (chip breakage).
662 	 */
663 	if (IS_2312(isp) && isp->isp_revision < 2) {
664 		ISP_DELAY(100);
665 	} else {
666 		loops = MBOX_DELAY_COUNT;
667 		while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
668 			ISP_DELAY(100);
669 			if (--loops < 0) {
670 				ISP_RESET0(isp);
671 				isp_prt(isp, ISP_LOGERR,
672 				    "MBOX_BUSY never cleared on reset");
673 				return;
674 			}
675 		}
676 	}
677 
678 	/*
679 	 * Up until this point we've done everything by just reading or
680 	 * setting registers. From this point on we rely on at least *some*
681 	 * kind of firmware running in the card.
682 	 */
683 
684 	/*
685 	 * Do some sanity checking by running a NOP command.
686 	 * If it succeeds, the ROM firmware is now running.
687 	 */
688 	ISP_MEMZERO(&mbs, sizeof (mbs));
689 	mbs.param[0] = MBOX_NO_OP;
690 	mbs.logval = MBLOGALL;
691 	isp_mboxcmd(isp, &mbs);
692 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
693 		isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
694 		ISP_RESET0(isp);
695 		return;
696 	}
697 
698 	/*
699 	 * Do some operational tests
700 	 */
701 
702 	if (IS_SCSI(isp) || IS_24XX(isp)) {
703 		ISP_MEMZERO(&mbs, sizeof (mbs));
704 		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
705 		mbs.param[1] = 0xdead;
706 		mbs.param[2] = 0xbeef;
707 		mbs.param[3] = 0xffff;
708 		mbs.param[4] = 0x1111;
709 		mbs.param[5] = 0xa5a5;
710 		mbs.param[6] = 0x0000;
711 		mbs.param[7] = 0x0000;
712 		mbs.logval = MBLOGALL;
713 		isp_mboxcmd(isp, &mbs);
714 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
715 			ISP_RESET0(isp);
716 			return;
717 		}
718 		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
719 		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
720 		    mbs.param[5] != 0xa5a5) {
721 			ISP_RESET0(isp);
722 			isp_prt(isp, ISP_LOGERR, "Register Test Failed (0x%x 0x%x 0x%x 0x%x 0x%x)", mbs.param[1], mbs.param[2], mbs.param[3], mbs.param[4], mbs.param[5]);
723 			return;
724 		}
725 
726 	}
727 
728 	/*
729 	 * Download new Firmware, unless requested not to do so.
730 	 * This is made slightly trickier in some cases where the
731 	 * firmware of the ROM revision is newer than the revision
732 	 * compiled into the driver. So, where we used to compare
733 	 * versions of our f/w and the ROM f/w, now we just see
734 	 * whether we have f/w at all and whether a config flag
735 	 * has disabled our download.
736 	 */
737 	if ((isp->isp_mdvec->dv_ispfw == NULL) || (isp->isp_confopts & ISP_CFG_NORELOAD)) {
738 		dodnld = 0;
739 	}
740 
741 	if (IS_24XX(isp)) {
742 		code_org = ISP_CODE_ORG_2400;
743 	} else if (IS_23XX(isp)) {
744 		code_org = ISP_CODE_ORG_2300;
745 	} else {
746 		code_org = ISP_CODE_ORG;
747 	}
748 
749 	if (dodnld && IS_24XX(isp)) {
750 		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
751 
752 		/*
753 		 * Keep loading until we run out of f/w.
754 		 */
755 		code_org = ptr[2];	/* 1st load address is our start addr */
756 
757 		for (;;) {
758 			uint32_t la, wi, wl;
759 
760 			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], ptr[2]);
761 
762 			wi = 0;
763 			la = ptr[2];
764 			wl = ptr[3];
765 
766 			while (wi < ptr[3]) {
767 				uint32_t *cp;
768 				uint32_t nw;
769 
770 				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 2;
771 				if (nw > wl) {
772 					nw = wl;
773 				}
774 				cp = isp->isp_rquest;
775 				for (i = 0; i < nw; i++) {
776 					ISP_IOXPUT_32(isp,  ptr[wi++], &cp[i]);
777 					wl--;
778 				}
779 				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
780 				ISP_MEMZERO(&mbs, sizeof (mbs));
781 				if (la < 0x10000 && nw < 0x10000) {
782 					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
783 					mbs.param[1] = la;
784 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
785 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
786 					mbs.param[4] = nw;
787 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
788 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
789 				} else {
790 					mbs.param[0] = MBOX_LOAD_RISC_RAM;
791 					mbs.param[1] = la;
792 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
793 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
794 					mbs.param[4] = nw >> 16;
795 					mbs.param[5] = nw;
796 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
797 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
798 					mbs.param[8] = la >> 16;
799 				}
800 				mbs.logval = MBLOGALL;
801 				isp_mboxcmd(isp, &mbs);
802 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
803 					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
804 					ISP_RESET0(isp);
805 					return;
806 				}
807 				la += nw;
808 			}
809 
810 			if (ptr[1] == 0) {
811 				break;
812 			}
813 			ptr += ptr[3];
814 		}
815 		isp->isp_loaded_fw = 1;
816 	} else if (dodnld && IS_23XX(isp)) {
817 		const uint16_t *ptr = isp->isp_mdvec->dv_ispfw;
818 		uint16_t wi, wl, segno;
819 		uint32_t la;
820 
821 		la = code_org;
822 		segno = 0;
823 
824 		for (;;) {
825 			uint32_t nxtaddr;
826 
827 			isp_prt(isp, ISP_LOGDEBUG0, "load 0x%x words of code at load address 0x%x", ptr[3], la);
828 
829 			wi = 0;
830 			wl = ptr[3];
831 
832 			while (wi < ptr[3]) {
833 				uint16_t *cp;
834 				uint16_t nw;
835 
836 				nw = ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) >> 1;
837 				if (nw > wl) {
838 					nw = wl;
839 				}
840 				if (nw > (1 << 15)) {
841 					nw = 1 << 15;
842 				}
843 				cp = isp->isp_rquest;
844 				for (i = 0; i < nw; i++) {
845 					ISP_IOXPUT_16(isp,  ptr[wi++], &cp[i]);
846 					wl--;
847 				}
848 				MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
849 				ISP_MEMZERO(&mbs, sizeof (mbs));
850 				if (la < 0x10000) {
851 					mbs.param[0] = MBOX_LOAD_RISC_RAM_2100;
852 					mbs.param[1] = la;
853 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
854 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
855 					mbs.param[4] = nw;
856 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
857 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
858 				} else {
859 					mbs.param[0] = MBOX_LOAD_RISC_RAM;
860 					mbs.param[1] = la;
861 					mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
862 					mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
863 					mbs.param[4] = nw;
864 					mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
865 					mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
866 					mbs.param[8] = la >> 16;
867 				}
868 				mbs.logval = MBLOGALL;
869 				isp_mboxcmd(isp, &mbs);
870 				if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
871 					isp_prt(isp, ISP_LOGERR, "F/W Risc Ram Load Failed");
872 					ISP_RESET0(isp);
873 					return;
874 				}
875 				la += nw;
876 			}
877 
878 			if (!IS_2322(isp)) {
879 				break;
880 			}
881 
882 			if (++segno == 3) {
883 				break;
884 			}
885 
886 			/*
887 			 * If we're a 2322, the firmware actually comes in
888 			 * three chunks. We loaded the first at the code_org
889 			 * address. The other two chunks, which follow right
890 			 * after each other in memory here, get loaded at
891 			 * addresses specfied at offset 0x9..0xB.
892 			 */
893 
894 			nxtaddr = ptr[3];
895 			ptr = &ptr[nxtaddr];
896 			la = ptr[5] | ((ptr[4] & 0x3f) << 16);
897 		}
898 		isp->isp_loaded_fw = 1;
899 	} else if (dodnld) {
900 		union {
901 			const uint16_t *cp;
902 			uint16_t *np;
903 		} ucd;
904 		ucd.cp = isp->isp_mdvec->dv_ispfw;
905 		isp->isp_mbxworkp = &ucd.np[1];
906 		isp->isp_mbxwrk0 = ucd.np[3] - 1;
907 		isp->isp_mbxwrk1 = code_org + 1;
908 		ISP_MEMZERO(&mbs, sizeof (mbs));
909 		mbs.param[0] = MBOX_WRITE_RAM_WORD;
910 		mbs.param[1] = code_org;
911 		mbs.param[2] = ucd.np[0];
912 		mbs.logval = MBLOGNONE;
913 		isp_mboxcmd(isp, &mbs);
914 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
915 			isp_prt(isp, ISP_LOGERR, "F/W download failed at word %d", isp->isp_mbxwrk1 - code_org);
916 			ISP_RESET0(isp);
917 			return;
918 		}
919 	} else {
920 		isp->isp_loaded_fw = 0;
921 		isp_prt(isp, ISP_LOGDEBUG2, "skipping f/w download");
922 	}
923 
924 	/*
925 	 * If we loaded firmware, verify its checksum
926 	 */
927 	if (isp->isp_loaded_fw) {
928 		ISP_MEMZERO(&mbs, sizeof (mbs));
929 		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
930 		if (IS_24XX(isp)) {
931 			mbs.param[1] = code_org >> 16;
932 			mbs.param[2] = code_org;
933 		} else {
934 			mbs.param[1] = code_org;
935 		}
936 		isp_mboxcmd(isp, &mbs);
937 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
938 			isp_prt(isp, ISP_LOGERR, dcrc);
939 			ISP_RESET0(isp);
940 			return;
941 		}
942 	}
943 
944 	/*
945 	 * Now start it rolling.
946 	 *
947 	 * If we didn't actually download f/w,
948 	 * we still need to (re)start it.
949 	 */
950 
951 
952 	MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 1000000);
953 	if (IS_24XX(isp)) {
954 		mbs.param[1] = code_org >> 16;
955 		mbs.param[2] = code_org;
956 		if (isp->isp_loaded_fw) {
957 			mbs.param[3] = 0;
958 		} else {
959 			mbs.param[3] = 1;
960 		}
961 		if (IS_25XX(isp)) {
962 			mbs.ibits |= 0x10;
963 		}
964 	} else if (IS_2322(isp)) {
965 		mbs.param[1] = code_org;
966 		if (isp->isp_loaded_fw) {
967 			mbs.param[2] = 0;
968 		} else {
969 			mbs.param[2] = 1;
970 		}
971 	} else {
972 		mbs.param[1] = code_org;
973 	}
974 	isp_mboxcmd(isp, &mbs);
975 	if (IS_2322(isp) || IS_24XX(isp)) {
976 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
977 			ISP_RESET0(isp);
978 			return;
979 		}
980 	}
981 
982 	/*
983 	 * Give it a chance to finish starting up.
984 	 * Give the 24XX more time.
985 	 */
986 	if (IS_24XX(isp)) {
987 		ISP_DELAY(500000);
988 		/*
989 		 * Check to see if the 24XX firmware really started.
990 		 */
991 		if (mbs.param[1] == 0xdead) {
992 			isp_prt(isp, ISP_LOGERR, "f/w didn't *really* start");
993 			ISP_RESET0(isp);
994 			return;
995 		}
996 	} else {
997 		ISP_DELAY(250000);
998 		if (IS_SCSI(isp)) {
999 			/*
1000 			 * Set CLOCK RATE, but only if asked to.
1001 			 */
1002 			if (isp->isp_clock) {
1003 				mbs.param[0] = MBOX_SET_CLOCK_RATE;
1004 				mbs.param[1] = isp->isp_clock;
1005 				mbs.logval = MBLOGNONE;
1006 				isp_mboxcmd(isp, &mbs);
1007 				/* we will try not to care if this fails */
1008 			}
1009 		}
1010 	}
1011 
1012 	/*
1013 	 * Ask the chip for the current firmware version.
1014 	 * This should prove that the new firmware is working.
1015 	 */
1016 	MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 0);
1017 	isp_mboxcmd(isp, &mbs);
1018 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1019 		ISP_RESET0(isp);
1020 		return;
1021 	}
1022 
1023 	/*
1024 	 * The SBus firmware that we are using apparently does not return
1025 	 * major, minor, micro revisions in the mailbox registers, which
1026 	 * is really, really, annoying.
1027 	 */
1028 	if (ISP_SBUS_SUPPORTED && isp->isp_bustype == ISP_BT_SBUS) {
1029 		if (dodnld) {
1030 #ifdef	ISP_TARGET_MODE
1031 			isp->isp_fwrev[0] = 7;
1032 			isp->isp_fwrev[1] = 55;
1033 #else
1034 			isp->isp_fwrev[0] = 1;
1035 			isp->isp_fwrev[1] = 37;
1036 #endif
1037 			isp->isp_fwrev[2] = 0;
1038 		}
1039 	} else {
1040 		isp->isp_fwrev[0] = mbs.param[1];
1041 		isp->isp_fwrev[1] = mbs.param[2];
1042 		isp->isp_fwrev[2] = mbs.param[3];
1043 	}
1044 
1045 	isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
1046 	    btype, isp->isp_revision, dodnld? "loaded" : "resident", isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
1047 
1048 	if (IS_FC(isp)) {
1049 		/*
1050 		 * We do not believe firmware attributes for 2100 code less
1051 		 * than 1.17.0, unless it's the firmware we specifically
1052 		 * are loading.
1053 		 *
1054 		 * Note that all 22XX and later f/w is greater than 1.X.0.
1055 		 */
1056 		if ((ISP_FW_OLDER_THAN(isp, 1, 17, 1))) {
1057 #ifdef	USE_SMALLER_2100_FIRMWARE
1058 			isp->isp_fwattr = ISP_FW_ATTR_SCCLUN;
1059 #else
1060 			isp->isp_fwattr = 0;
1061 #endif
1062 		} else {
1063 			isp->isp_fwattr = mbs.param[6];
1064 			isp_prt(isp, ISP_LOGDEBUG0, "Firmware Attributes = 0x%x", mbs.param[6]);
1065 		}
1066 	} else {
1067 #ifndef	ISP_TARGET_MODE
1068 		isp->isp_fwattr = ISP_FW_ATTR_TMODE;
1069 #else
1070 		isp->isp_fwattr = 0;
1071 #endif
1072 	}
1073 
1074 	if (!IS_24XX(isp)) {
1075 		MBSINIT(&mbs, MBOX_GET_FIRMWARE_STATUS, MBLOGALL, 0);
1076 		isp_mboxcmd(isp, &mbs);
1077 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1078 			ISP_RESET0(isp);
1079 			return;
1080 		}
1081 		if (isp->isp_maxcmds >= mbs.param[2]) {
1082 			isp->isp_maxcmds = mbs.param[2];
1083 		}
1084 	}
1085 	isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
1086 
1087 	/*
1088 	 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
1089 	 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
1090 	 * work for them).
1091 	 */
1092 	if (IS_FC(isp) && ISP_CAP_MULTI_ID(isp) == 0 && isp->isp_nchan > 1) {
1093 		isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, only can enable 1 of %d channels", isp->isp_nchan);
1094 		isp->isp_nchan = 1;
1095 	}
1096 
1097 	for (i = 0; i < isp->isp_nchan; i++) {
1098 		isp_fw_state(isp, i);
1099 	}
1100 	if (isp->isp_dead) {
1101 		isp_shutdown(isp);
1102 		ISP_DISABLE_INTS(isp);
1103 		return;
1104 	}
1105 
1106 	isp->isp_state = ISP_RESETSTATE;
1107 
1108 	/*
1109 	 * Okay- now that we have new firmware running, we now (re)set our
1110 	 * notion of how many luns we support. This is somewhat tricky because
1111 	 * if we haven't loaded firmware, we sometimes do not have an easy way
1112 	 * of knowing how many luns we support.
1113 	 *
1114 	 * Expanded lun firmware gives you 32 luns for SCSI cards and
1115 	 * 16384 luns for Fibre Channel cards.
1116 	 *
1117 	 * It turns out that even for QLogic 2100s with ROM 1.10 and above
1118 	 * we do get a firmware attributes word returned in mailbox register 6.
1119 	 *
1120 	 * Because the lun is in a different position in the Request Queue
1121 	 * Entry structure for Fibre Channel with expanded lun firmware, we
1122 	 * can only support one lun (lun zero) when we don't know what kind
1123 	 * of firmware we're running.
1124 	 */
1125 	if (IS_SCSI(isp)) {
1126 		if (dodnld) {
1127 			if (IS_ULTRA2(isp) || IS_ULTRA3(isp)) {
1128 				isp->isp_maxluns = 32;
1129 			} else {
1130 				isp->isp_maxluns = 8;
1131 			}
1132 		} else {
1133 			isp->isp_maxluns = 8;
1134 		}
1135 	} else {
1136 		if (ISP_CAP_SCCFW(isp)) {
1137 			isp->isp_maxluns = 16384;
1138 		} else {
1139 			isp->isp_maxluns = 16;
1140 		}
1141 	}
1142 
1143 	/*
1144 	 * We get some default values established. As a side
1145 	 * effect, NVRAM is read here (unless overriden by
1146 	 * a configuration flag).
1147 	 */
1148 	if (do_load_defaults) {
1149 		if (IS_SCSI(isp)) {
1150 			isp_setdfltsdparm(isp);
1151 		} else {
1152 			for (i = 0; i < isp->isp_nchan; i++) {
1153 				isp_setdfltfcparm(isp, i);
1154 			}
1155 		}
1156 	}
1157 }
1158 
1159 /*
1160  * Initialize Parameters of Hardware to a known state.
1161  *
1162  * Locks are held before coming here.
1163  */
1164 
1165 void
1166 isp_init(ispsoftc_t *isp)
1167 {
1168 	if (IS_FC(isp)) {
1169 		if (IS_24XX(isp)) {
1170 			isp_fibre_init_2400(isp);
1171 		} else {
1172 			isp_fibre_init(isp);
1173 		}
1174 	} else {
1175 		isp_scsi_init(isp);
1176 	}
1177 	GET_NANOTIME(&isp->isp_init_time);
1178 }
1179 
1180 static void
1181 isp_scsi_init(ispsoftc_t *isp)
1182 {
1183 	sdparam *sdp_chan0, *sdp_chan1;
1184 	mbreg_t mbs;
1185 
1186 	sdp_chan0 = SDPARAM(isp, 0);
1187 	sdp_chan1 = sdp_chan0;
1188 	if (IS_DUALBUS(isp)) {
1189 		sdp_chan1 = SDPARAM(isp, 1);
1190 	}
1191 
1192 	/* First do overall per-card settings. */
1193 
1194 	/*
1195 	 * If we have fast memory timing enabled, turn it on.
1196 	 */
1197 	if (sdp_chan0->isp_fast_mttr) {
1198 		ISP_WRITE(isp, RISC_MTR, 0x1313);
1199 	}
1200 
1201 	/*
1202 	 * Set Retry Delay and Count.
1203 	 * You set both channels at the same time.
1204 	 */
1205 	MBSINIT(&mbs, MBOX_SET_RETRY_COUNT, MBLOGALL, 0);
1206 	mbs.param[1] = sdp_chan0->isp_retry_count;
1207 	mbs.param[2] = sdp_chan0->isp_retry_delay;
1208 	mbs.param[6] = sdp_chan1->isp_retry_count;
1209 	mbs.param[7] = sdp_chan1->isp_retry_delay;
1210 	isp_mboxcmd(isp, &mbs);
1211 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1212 		return;
1213 	}
1214 
1215 	/*
1216 	 * Set ASYNC DATA SETUP time. This is very important.
1217 	 */
1218 	MBSINIT(&mbs, MBOX_SET_ASYNC_DATA_SETUP_TIME, MBLOGALL, 0);
1219 	mbs.param[1] = sdp_chan0->isp_async_data_setup;
1220 	mbs.param[2] = sdp_chan1->isp_async_data_setup;
1221 	isp_mboxcmd(isp, &mbs);
1222 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1223 		return;
1224 	}
1225 
1226 	/*
1227 	 * Set ACTIVE Negation State.
1228 	 */
1229 	MBSINIT(&mbs, MBOX_SET_ACT_NEG_STATE, MBLOGNONE, 0);
1230 	mbs.param[1] =
1231 	    (sdp_chan0->isp_req_ack_active_neg << 4) |
1232 	    (sdp_chan0->isp_data_line_active_neg << 5);
1233 	mbs.param[2] =
1234 	    (sdp_chan1->isp_req_ack_active_neg << 4) |
1235 	    (sdp_chan1->isp_data_line_active_neg << 5);
1236 	isp_mboxcmd(isp, &mbs);
1237 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1238 		isp_prt(isp, ISP_LOGERR,
1239 		    "failed to set active negation state (%d,%d), (%d,%d)",
1240 		    sdp_chan0->isp_req_ack_active_neg,
1241 		    sdp_chan0->isp_data_line_active_neg,
1242 		    sdp_chan1->isp_req_ack_active_neg,
1243 		    sdp_chan1->isp_data_line_active_neg);
1244 		/*
1245 		 * But don't return.
1246 		 */
1247 	}
1248 
1249 	/*
1250 	 * Set the Tag Aging limit
1251 	 */
1252 	MBSINIT(&mbs, MBOX_SET_TAG_AGE_LIMIT, MBLOGALL, 0);
1253 	mbs.param[1] = sdp_chan0->isp_tag_aging;
1254 	mbs.param[2] = sdp_chan1->isp_tag_aging;
1255 	isp_mboxcmd(isp, &mbs);
1256 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1257 		isp_prt(isp, ISP_LOGERR, "failed to set tag age limit (%d,%d)",
1258 		    sdp_chan0->isp_tag_aging, sdp_chan1->isp_tag_aging);
1259 		return;
1260 	}
1261 
1262 	/*
1263 	 * Set selection timeout.
1264 	 */
1265 	MBSINIT(&mbs, MBOX_SET_SELECT_TIMEOUT, MBLOGALL, 0);
1266 	mbs.param[1] = sdp_chan0->isp_selection_timeout;
1267 	mbs.param[2] = sdp_chan1->isp_selection_timeout;
1268 	isp_mboxcmd(isp, &mbs);
1269 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1270 		return;
1271 	}
1272 
1273 	/* now do per-channel settings */
1274 	isp_scsi_channel_init(isp, 0);
1275 	if (IS_DUALBUS(isp))
1276 		isp_scsi_channel_init(isp, 1);
1277 
1278 	/*
1279 	 * Now enable request/response queues
1280 	 */
1281 
1282 	if (IS_ULTRA2(isp) || IS_1240(isp)) {
1283 		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE_A64, MBLOGALL, 0);
1284 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1285 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1286 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1287 		mbs.param[4] = 0;
1288 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1289 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1290 		isp_mboxcmd(isp, &mbs);
1291 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1292 			return;
1293 		}
1294 		isp->isp_residx = mbs.param[5];
1295 
1296 		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE_A64, MBLOGALL, 0);
1297 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1298 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1299 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1300 		mbs.param[5] = 0;
1301 		mbs.param[6] = DMA_WD3(isp->isp_result_dma);
1302 		mbs.param[7] = DMA_WD2(isp->isp_result_dma);
1303 		isp_mboxcmd(isp, &mbs);
1304 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1305 			return;
1306 		}
1307 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1308 	} else {
1309 		MBSINIT(&mbs, MBOX_INIT_RES_QUEUE, MBLOGALL, 0);
1310 		mbs.param[1] = RESULT_QUEUE_LEN(isp);
1311 		mbs.param[2] = DMA_WD1(isp->isp_result_dma);
1312 		mbs.param[3] = DMA_WD0(isp->isp_result_dma);
1313 		mbs.param[4] = 0;
1314 		isp_mboxcmd(isp, &mbs);
1315 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1316 			return;
1317 		}
1318 		isp->isp_residx = mbs.param[5];
1319 
1320 		MBSINIT(&mbs, MBOX_INIT_REQ_QUEUE, MBLOGALL, 0);
1321 		mbs.param[1] = RQUEST_QUEUE_LEN(isp);
1322 		mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
1323 		mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
1324 		mbs.param[5] = 0;
1325 		isp_mboxcmd(isp, &mbs);
1326 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1327 			return;
1328 		}
1329 		isp->isp_reqidx = isp->isp_reqodx = mbs.param[4];
1330 	}
1331 
1332 	/*
1333 	 * Turn on LVD transitions for ULTRA2 or better and other features
1334 	 *
1335 	 * Now that we have 32 bit handles, don't do any fast posting
1336 	 * any more. For Ultra2/Ultra3 cards, we can turn on 32 bit RIO
1337 	 * operation or use fast posting. To be conservative, we'll only
1338 	 * do this for Ultra3 cards now because the other cards are so
1339 	 * rare for this author to find and test with.
1340 	 */
1341 
1342 	MBSINIT(&mbs, MBOX_SET_FW_FEATURES, MBLOGALL, 0);
1343 	if (IS_ULTRA2(isp))
1344 		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
1345 #ifdef	ISP_NO_RIO
1346 	if (IS_ULTRA3(isp))
1347 		mbs.param[1] |= FW_FEATURE_FAST_POST;
1348 #else
1349 	if (IS_ULTRA3(isp))
1350 		mbs.param[1] |= FW_FEATURE_RIO_32BIT;
1351 #endif
1352 	if (mbs.param[1] != 0) {
1353 		uint16_t sfeat = mbs.param[1];
1354 		isp_mboxcmd(isp, &mbs);
1355 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1356 			isp_prt(isp, ISP_LOGINFO,
1357 			    "Enabled FW features (0x%x)", sfeat);
1358 		}
1359 	}
1360 
1361 	isp->isp_state = ISP_INITSTATE;
1362 }
1363 
1364 static void
1365 isp_scsi_channel_init(ispsoftc_t *isp, int chan)
1366 {
1367 	sdparam *sdp;
1368 	mbreg_t mbs;
1369 	int tgt;
1370 
1371 	sdp = SDPARAM(isp, chan);
1372 
1373 	/*
1374 	 * Set (possibly new) Initiator ID.
1375 	 */
1376 	MBSINIT(&mbs, MBOX_SET_INIT_SCSI_ID, MBLOGALL, 0);
1377 	mbs.param[1] = (chan << 7) | sdp->isp_initiator_id;
1378 	isp_mboxcmd(isp, &mbs);
1379 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1380 		return;
1381 	}
1382 	isp_prt(isp, ISP_LOGINFO, "Chan %d Initiator ID is %d",
1383 	    chan, sdp->isp_initiator_id);
1384 
1385 
1386 	/*
1387 	 * Set current per-target parameters to an initial safe minimum.
1388 	 */
1389 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1390 		int lun;
1391 		uint16_t sdf;
1392 
1393 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
1394 			continue;
1395 		}
1396 #ifndef	ISP_TARGET_MODE
1397 		sdf = sdp->isp_devparam[tgt].goal_flags;
1398 		sdf &= DPARM_SAFE_DFLT;
1399 		/*
1400 		 * It is not quite clear when this changed over so that
1401 		 * we could force narrow and async for 1000/1020 cards,
1402 		 * but assume that this is only the case for loaded
1403 		 * firmware.
1404 		 */
1405 		if (isp->isp_loaded_fw) {
1406 			sdf |= DPARM_NARROW | DPARM_ASYNC;
1407 		}
1408 #else
1409 		/*
1410 		 * The !$*!)$!$)* f/w uses the same index into some
1411 		 * internal table to decide how to respond to negotiations,
1412 		 * so if we've said "let's be safe" for ID X, and ID X
1413 		 * selects *us*, the negotiations will back to 'safe'
1414 		 * (as in narrow/async). What the f/w *should* do is
1415 		 * use the initiator id settings to decide how to respond.
1416 		 */
1417 		sdp->isp_devparam[tgt].goal_flags = sdf = DPARM_DEFAULT;
1418 #endif
1419 		MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGNONE, 0);
1420 		mbs.param[1] = (chan << 15) | (tgt << 8);
1421 		mbs.param[2] = sdf;
1422 		if ((sdf & DPARM_SYNC) == 0) {
1423 			mbs.param[3] = 0;
1424 		} else {
1425 			mbs.param[3] =
1426 			    (sdp->isp_devparam[tgt].goal_offset << 8) |
1427 			    (sdp->isp_devparam[tgt].goal_period);
1428 		}
1429 		isp_prt(isp, ISP_LOGDEBUG0, "Initial Settings bus%d tgt%d flags 0x%x off 0x%x per 0x%x",
1430 		    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
1431 		isp_mboxcmd(isp, &mbs);
1432 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1433 			sdf = DPARM_SAFE_DFLT;
1434 			MBSINIT(&mbs, MBOX_SET_TARGET_PARAMS, MBLOGALL, 0);
1435 			mbs.param[1] = (tgt << 8) | (chan << 15);
1436 			mbs.param[2] = sdf;
1437 			mbs.param[3] = 0;
1438 			isp_mboxcmd(isp, &mbs);
1439 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1440 				continue;
1441 			}
1442 		}
1443 
1444 		/*
1445 		 * We don't update any information directly from the f/w
1446 		 * because we need to run at least one command to cause a
1447 		 * new state to be latched up. So, we just assume that we
1448 		 * converge to the values we just had set.
1449 		 *
1450 		 * Ensure that we don't believe tagged queuing is enabled yet.
1451 		 * It turns out that sometimes the ISP just ignores our
1452 		 * attempts to set parameters for devices that it hasn't
1453 		 * seen yet.
1454 		 */
1455 		sdp->isp_devparam[tgt].actv_flags = sdf & ~DPARM_TQING;
1456 		for (lun = 0; lun < (int) isp->isp_maxluns; lun++) {
1457 			MBSINIT(&mbs, MBOX_SET_DEV_QUEUE_PARAMS, MBLOGALL, 0);
1458 			mbs.param[1] = (chan << 15) | (tgt << 8) | lun;
1459 			mbs.param[2] = sdp->isp_max_queue_depth;
1460 			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1461 			isp_mboxcmd(isp, &mbs);
1462 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1463 				break;
1464 			}
1465 		}
1466 	}
1467 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
1468 		if (sdp->isp_devparam[tgt].dev_refresh) {
1469 			sdp->sendmarker = 1;
1470 			sdp->update = 1;
1471 			break;
1472 		}
1473 	}
1474 }
1475 
1476 /*
1477  * Fibre Channel specific initialization.
1478  */
1479 static void
1480 isp_fibre_init(ispsoftc_t *isp)
1481 {
1482 	fcparam *fcp;
1483 	isp_icb_t local, *icbp = &local;
1484 	mbreg_t mbs;
1485 	int ownloopid;
1486 
1487 	/*
1488 	 * We only support one channel on non-24XX cards
1489 	 */
1490 	fcp = FCPARAM(isp, 0);
1491 	if (fcp->role == ISP_ROLE_NONE) {
1492 		isp->isp_state = ISP_INITSTATE;
1493 		return;
1494 	}
1495 
1496 	ISP_MEMZERO(icbp, sizeof (*icbp));
1497 	icbp->icb_version = ICB_VERSION1;
1498 	icbp->icb_fwoptions = fcp->isp_fwoptions;
1499 
1500 	/*
1501 	 * Firmware Options are either retrieved from NVRAM or
1502 	 * are patched elsewhere. We check them for sanity here
1503 	 * and make changes based on board revision, but otherwise
1504 	 * let others decide policy.
1505 	 */
1506 
1507 	/*
1508 	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1509 	 */
1510 	if (IS_2100(isp) && isp->isp_revision < 5) {
1511 		icbp->icb_fwoptions &= ~ICBOPT_FAIRNESS;
1512 	}
1513 
1514 	/*
1515 	 * We have to use FULL LOGIN even though it resets the loop too much
1516 	 * because otherwise port database entries don't get updated after
1517 	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1518 	 */
1519 	if (!ISP_FW_NEWER_THAN(isp, 1, 17, 0)) {
1520 		icbp->icb_fwoptions |= ICBOPT_FULL_LOGIN;
1521 	}
1522 
1523 	/*
1524 	 * Insist on Port Database Update Async notifications
1525 	 */
1526 	icbp->icb_fwoptions |= ICBOPT_PDBCHANGE_AE;
1527 
1528 	/*
1529 	 * Make sure that target role reflects into fwoptions.
1530 	 */
1531 	if (fcp->role & ISP_ROLE_TARGET) {
1532 		icbp->icb_fwoptions |= ICBOPT_TGT_ENABLE;
1533 	} else {
1534 		icbp->icb_fwoptions &= ~ICBOPT_TGT_ENABLE;
1535 	}
1536 
1537 	if (fcp->role & ISP_ROLE_INITIATOR) {
1538 		icbp->icb_fwoptions &= ~ICBOPT_INI_DISABLE;
1539 	} else {
1540 		icbp->icb_fwoptions |= ICBOPT_INI_DISABLE;
1541 	}
1542 
1543 	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1544 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1545 		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1546 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1547 	}
1548 	icbp->icb_maxalloc = fcp->isp_maxalloc;
1549 	if (icbp->icb_maxalloc < 1) {
1550 		isp_prt(isp, ISP_LOGERR, "bad maximum allocation (%d)- using 16", fcp->isp_maxalloc);
1551 		icbp->icb_maxalloc = 16;
1552 	}
1553 	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1554 	if (icbp->icb_execthrottle < 1) {
1555 		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1556 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1557 	}
1558 	icbp->icb_retry_delay = fcp->isp_retry_delay;
1559 	icbp->icb_retry_count = fcp->isp_retry_count;
1560 	icbp->icb_hardaddr = fcp->isp_loopid;
1561 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
1562 	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1563 		icbp->icb_hardaddr = 0;
1564 		ownloopid = 0;
1565 	}
1566 
1567 	/*
1568 	 * Our life seems so much better with 2200s and later with
1569 	 * the latest f/w if we set Hard Address.
1570 	 */
1571 	if (ownloopid || ISP_FW_NEWER_THAN(isp, 2, 2, 5)) {
1572 		icbp->icb_fwoptions |= ICBOPT_HARD_ADDRESS;
1573 	}
1574 
1575 	/*
1576 	 * Right now we just set extended options to prefer point-to-point
1577 	 * over loop based upon some soft config options.
1578 	 *
1579 	 * NB: for the 2300, ICBOPT_EXTENDED is required.
1580 	 */
1581 	if (IS_2200(isp) || IS_23XX(isp)) {
1582 		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1583 		/*
1584 		 * Prefer or force Point-To-Point instead Loop?
1585 		 */
1586 		switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1587 		case ISP_CFG_NPORT:
1588 			icbp->icb_xfwoptions |= ICBXOPT_PTP_2_LOOP;
1589 			break;
1590 		case ISP_CFG_NPORT_ONLY:
1591 			icbp->icb_xfwoptions |= ICBXOPT_PTP_ONLY;
1592 			break;
1593 		case ISP_CFG_LPORT_ONLY:
1594 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_ONLY;
1595 			break;
1596 		default:
1597 			icbp->icb_xfwoptions |= ICBXOPT_LOOP_2_PTP;
1598 			break;
1599 		}
1600 		if (IS_2200(isp)) {
1601 			/*
1602 			 * We can't have Fast Posting any more- we now
1603 			 * have 32 bit handles.
1604 			 *
1605 			 * RIO seemed to have to much breakage.
1606 			 *
1607 			 * Just opt for safety.
1608 			 */
1609 			icbp->icb_xfwoptions &= ~ICBXOPT_RIO_16BIT;
1610 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1611 		} else {
1612 			/*
1613 			 * QLogic recommends that FAST Posting be turned
1614 			 * off for 23XX cards and instead allow the HBA
1615 			 * to write response queue entries and interrupt
1616 			 * after a delay (ZIO).
1617 			 */
1618 			icbp->icb_fwoptions &= ~ICBOPT_FAST_POST;
1619 			if ((fcp->isp_xfwoptions & ICBXOPT_TIMER_MASK) == ICBXOPT_ZIO) {
1620 				icbp->icb_xfwoptions |= ICBXOPT_ZIO;
1621 				icbp->icb_idelaytimer = 10;
1622 			}
1623 			if (isp->isp_confopts & ISP_CFG_ONEGB) {
1624 				icbp->icb_zfwoptions |= ICBZOPT_RATE_ONEGB;
1625 			} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1626 				icbp->icb_zfwoptions |= ICBZOPT_RATE_TWOGB;
1627 			} else {
1628 				icbp->icb_zfwoptions |= ICBZOPT_RATE_AUTO;
1629 			}
1630 			if (fcp->isp_zfwoptions & ICBZOPT_50_OHM) {
1631 				icbp->icb_zfwoptions |= ICBZOPT_50_OHM;
1632 			}
1633 		}
1634 	}
1635 
1636 
1637 	/*
1638 	 * For 22XX > 2.1.26 && 23XX, set some options.
1639 	 */
1640 	if (ISP_FW_NEWER_THAN(isp, 2, 26, 0)) {
1641 		MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1642 		mbs.param[1] = IFCOPT1_DISF7SWTCH|IFCOPT1_LIPASYNC|IFCOPT1_LIPF8;
1643 		mbs.param[2] = 0;
1644 		mbs.param[3] = 0;
1645 		if (ISP_FW_NEWER_THAN(isp, 3, 16, 0)) {
1646 			mbs.param[1] |= IFCOPT1_EQFQASYNC|IFCOPT1_CTIO_RETRY;
1647 			if (fcp->role & ISP_ROLE_TARGET) {
1648 				mbs.param[3] = IFCOPT3_NOPRLI;
1649 			}
1650 		}
1651 		isp_mboxcmd(isp, &mbs);
1652 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1653 			return;
1654 		}
1655 	}
1656 	icbp->icb_logintime = ICB_LOGIN_TOV;
1657 	icbp->icb_lunetimeout = ICB_LUN_ENABLE_TOV;
1658 
1659 	if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1660 		icbp->icb_fwoptions |= ICBOPT_BOTH_WWNS;
1661 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1662 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1663 		isp_prt(isp, ISP_LOGDEBUG1,
1664 		    "Setting ICB Node 0x%08x%08x Port 0x%08x%08x",
1665 		    ((uint32_t) (fcp->isp_wwnn >> 32)),
1666 		    ((uint32_t) (fcp->isp_wwnn)),
1667 		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1668 		    ((uint32_t) (fcp->isp_wwpn)));
1669 	} else if (fcp->isp_wwpn) {
1670 		icbp->icb_fwoptions &= ~ICBOPT_BOTH_WWNS;
1671 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1672 		isp_prt(isp, ISP_LOGDEBUG1,
1673 		    "Setting ICB Port 0x%08x%08x",
1674 		    ((uint32_t) (fcp->isp_wwpn >> 32)),
1675 		    ((uint32_t) (fcp->isp_wwpn)));
1676 	} else {
1677 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1678 		return;
1679 	}
1680 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1681 	if (icbp->icb_rqstqlen < 1) {
1682 		isp_prt(isp, ISP_LOGERR, "bad request queue length");
1683 	}
1684 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1685 	if (icbp->icb_rsltqlen < 1) {
1686 		isp_prt(isp, ISP_LOGERR, "bad result queue length");
1687 	}
1688 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1689 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1690 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1691 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1692 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1693 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1694 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1695 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1696 
1697 	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1698 		isp_prt(isp, ISP_LOGERR, sacq);
1699 		return;
1700 	}
1701 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init: fwopt 0x%x xfwopt 0x%x zfwopt 0x%x",
1702 	    icbp->icb_fwoptions, icbp->icb_xfwoptions, icbp->icb_zfwoptions);
1703 
1704 	isp_put_icb(isp, icbp, (isp_icb_t *)fcp->isp_scratch);
1705 
1706 	/*
1707 	 * Init the firmware
1708 	 */
1709 	MBSINIT(&mbs, MBOX_INIT_FIRMWARE, MBLOGALL, 30000000);
1710 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1711 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1712 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1713 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1714 	mbs.logval = MBLOGALL;
1715 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %p (%08x%08x)",
1716 	    fcp->isp_scratch, (uint32_t) ((uint64_t)fcp->isp_scdma >> 32),
1717 	    (uint32_t) fcp->isp_scdma);
1718 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1719 	isp_mboxcmd(isp, &mbs);
1720 	FC_SCRATCH_RELEASE(isp, 0);
1721 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1722 		isp_print_bytes(isp, "isp_fibre_init", sizeof (*icbp), icbp);
1723 		return;
1724 	}
1725 	isp->isp_reqidx = 0;
1726 	isp->isp_reqodx = 0;
1727 	isp->isp_residx = 0;
1728 
1729 	/*
1730 	 * Whatever happens, we're now committed to being here.
1731 	 */
1732 	isp->isp_state = ISP_INITSTATE;
1733 }
1734 
1735 static void
1736 isp_fibre_init_2400(ispsoftc_t *isp)
1737 {
1738 	fcparam *fcp;
1739 	isp_icb_2400_t local, *icbp = &local;
1740 	mbreg_t mbs;
1741 	int chan;
1742 
1743 	/*
1744 	 * Check to see whether all channels have *some* kind of role
1745 	 */
1746 	for (chan = 0; chan < isp->isp_nchan; chan++) {
1747 		fcp = FCPARAM(isp, chan);
1748 		if (fcp->role != ISP_ROLE_NONE) {
1749 			break;
1750 		}
1751 	}
1752 	if (chan == isp->isp_nchan) {
1753 		isp_prt(isp, ISP_LOGDEBUG0, "all %d channels with role 'none'", chan);
1754 		isp->isp_state = ISP_INITSTATE;
1755 		return;
1756 	}
1757 
1758 	/*
1759 	 * Start with channel 0.
1760 	 */
1761 	fcp = FCPARAM(isp, 0);
1762 
1763 	/*
1764 	 * Turn on LIP F8 async event (1)
1765 	 */
1766 	MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
1767 	mbs.param[1] = 1;
1768 	isp_mboxcmd(isp, &mbs);
1769 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1770 		return;
1771 	}
1772 
1773 	ISP_MEMZERO(icbp, sizeof (*icbp));
1774 	icbp->icb_fwoptions1 = fcp->isp_fwoptions;
1775 	if (fcp->role & ISP_ROLE_TARGET) {
1776 		icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
1777 	} else {
1778 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
1779 	}
1780 
1781 	if (fcp->role & ISP_ROLE_INITIATOR) {
1782 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
1783 	} else {
1784 		icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
1785 	}
1786 
1787 	icbp->icb_version = ICB_VERSION1;
1788 	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
1789 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1790 		isp_prt(isp, ISP_LOGERR, "bad frame length (%d) from NVRAM- using %d", DEFAULT_FRAMESIZE(isp), ICB_DFLT_FRMLEN);
1791 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1792 	}
1793 
1794 	icbp->icb_execthrottle = DEFAULT_EXEC_THROTTLE(isp);
1795 	if (icbp->icb_execthrottle < 1) {
1796 		isp_prt(isp, ISP_LOGERR, "bad execution throttle of %d- using %d", DEFAULT_EXEC_THROTTLE(isp), ICB_DFLT_THROTTLE);
1797 		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1798 	}
1799 
1800 	if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
1801 		/*
1802 		 * Get current resource count
1803 		 */
1804 		MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
1805 		mbs.obits = 0x4cf;
1806 		isp_mboxcmd(isp, &mbs);
1807 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1808 			return;
1809 		}
1810 		icbp->icb_xchgcnt = mbs.param[3];
1811 	}
1812 
1813 
1814 	icbp->icb_hardaddr = fcp->isp_loopid;
1815 	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
1816 		icbp->icb_hardaddr = 0;
1817 	}
1818 
1819 	/*
1820 	 * Force this on.
1821 	 */
1822 	icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
1823 
1824 	icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
1825 	switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
1826 #if	0
1827 	case ISP_CFG_NPORT:
1828 		/*
1829 		 * XXX: This causes the f/w to crash.
1830 		 */
1831 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1832 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_2_LOOP;
1833 		break;
1834 #endif
1835 	case ISP_CFG_NPORT_ONLY:
1836 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1837 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
1838 		break;
1839 	case ISP_CFG_LPORT_ONLY:
1840 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1841 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
1842 		break;
1843 	default:
1844 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
1845 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
1846 		break;
1847 	}
1848 
1849 	/* force this on for now */
1850 	icbp->icb_fwoptions2 |= ICB2400_OPT2_ZIO;
1851 
1852 	switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1853 	case ICB2400_OPT2_ZIO:
1854 	case ICB2400_OPT2_ZIO1:
1855 		icbp->icb_idelaytimer = 0;
1856 		break;
1857 	case 0:
1858 		break;
1859 	default:
1860 		isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1861 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1862 		break;
1863 	}
1864 
1865 	/*
1866 	 * We don't support FCTAPE, so clear it.
1867 	 */
1868 	icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
1869 
1870 	icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
1871 	icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_AUTO;
1872 	if (isp->isp_confopts & ISP_CFG_ONEGB) {
1873 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_ONEGB;
1874 	} else if (isp->isp_confopts & ISP_CFG_TWOGB) {
1875 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_TWOGB;
1876 	} else if (isp->isp_confopts & ISP_CFG_FOURGB) {
1877 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_FOURGB;
1878 	} else {
1879 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1880 	}
1881 
1882 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
1883 		icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1884 	}
1885 	icbp->icb_logintime = ICB_LOGIN_TOV;
1886 
1887 	if (fcp->isp_wwnn && fcp->isp_wwpn && (fcp->isp_wwnn >> 60) != 2) {
1888 		icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1889 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1890 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1891 		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node 0x%08x%08x Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwnn >> 32)), ((uint32_t) (fcp->isp_wwnn)),
1892 		    ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1893 	} else if (fcp->isp_wwpn) {
1894 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1895 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1896 		isp_prt(isp, ISP_LOGDEBUG1, "Setting ICB Node to be same as Port 0x%08x%08x", ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1897 	} else {
1898 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1899 		return;
1900 	}
1901 	icbp->icb_retry_count = fcp->isp_retry_count;
1902 
1903 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1904 	if (icbp->icb_rqstqlen < 8) {
1905 		isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1906 		return;
1907 	}
1908 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1909 	if (icbp->icb_rsltqlen < 8) {
1910 		isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1911 		    icbp->icb_rsltqlen);
1912 		return;
1913 	}
1914 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1915 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1916 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1917 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1918 
1919 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1920 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1921 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1922 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1923 
1924 #ifdef	ISP_TARGET_MODE
1925 	/* unconditionally set up the ATIO queue if we support target mode */
1926 	icbp->icb_atioqlen = RESULT_QUEUE_LEN(isp);
1927 	if (icbp->icb_atioqlen < 8) {
1928 		isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1929 		return;
1930 	}
1931 	icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1932 	icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1933 	icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1934 	icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1935 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1936 	    DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1937 #endif
1938 
1939 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1940 
1941 	isp_prt(isp, ISP_LOGDEBUG0, "isp_fibre_init_2400: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1942 	    DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1943 	    DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1944 
1945 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
1946 		isp_print_bytes(isp, "isp_fibre_init_2400", sizeof (*icbp), icbp);
1947 	}
1948 
1949 	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1950 		isp_prt(isp, ISP_LOGERR, sacq);
1951 		return;
1952 	}
1953 	ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1954 	isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1955 
1956 	/*
1957 	 * Now fill in information about any additional channels
1958 	 */
1959 	if (isp->isp_nchan > 1) {
1960 		isp_icb_2400_vpinfo_t vpinfo, *vdst;
1961 		vp_port_info_t pi, *pdst;
1962 		size_t amt = 0;
1963 		uint8_t *off;
1964 
1965 		vpinfo.vp_count = isp->isp_nchan - 1;
1966 		vpinfo.vp_global_options = 0;
1967 		off = fcp->isp_scratch;
1968 		off += ICB2400_VPINFO_OFF;
1969 		vdst = (isp_icb_2400_vpinfo_t *) off;
1970 		isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1971 		amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1972 		for (chan = 1; chan < isp->isp_nchan; chan++) {
1973 			fcparam *fcp2;
1974 
1975 			ISP_MEMZERO(&pi, sizeof (pi));
1976 			fcp2 = FCPARAM(isp, chan);
1977 			if (fcp2->role != ISP_ROLE_NONE) {
1978 				pi.vp_port_options = ICB2400_VPOPT_ENABLED;
1979 				if (fcp2->role & ISP_ROLE_INITIATOR) {
1980 					pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1981 				}
1982 				if ((fcp2->role & ISP_ROLE_TARGET) == 0) {
1983 					pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
1984 				}
1985 				MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
1986 				MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
1987 			}
1988 			off = fcp->isp_scratch;
1989 			off += ICB2400_VPINFO_PORT_OFF(chan);
1990 			pdst = (vp_port_info_t *) off;
1991 			isp_put_vp_port_info(isp, &pi, pdst);
1992 			amt += ICB2400_VPOPT_WRITE_SIZE;
1993 		}
1994 	}
1995 
1996 	/*
1997 	 * Init the firmware
1998 	 */
1999 	MBSINIT(&mbs, 0, MBLOGALL, 30000000);
2000 	if (isp->isp_nchan > 1) {
2001 		mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
2002 	} else {
2003 		mbs.param[0] = MBOX_INIT_FIRMWARE;
2004 	}
2005 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2006 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2007 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2008 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2009 	isp_prt(isp, ISP_LOGDEBUG0, "INIT F/W from %04x%04x%04x%04x", DMA_WD3(fcp->isp_scdma), DMA_WD2(fcp->isp_scdma), DMA_WD1(fcp->isp_scdma), DMA_WD0(fcp->isp_scdma));
2010 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
2011 	isp_mboxcmd(isp, &mbs);
2012 	FC_SCRATCH_RELEASE(isp, 0);
2013 
2014 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2015 		return;
2016 	}
2017 	isp->isp_reqidx = 0;
2018 	isp->isp_reqodx = 0;
2019 	isp->isp_residx = 0;
2020 
2021 	/*
2022 	 * Whatever happens, we're now committed to being here.
2023 	 */
2024 	isp->isp_state = ISP_INITSTATE;
2025 }
2026 
2027 static void
2028 isp_mark_portdb(ispsoftc_t *isp, int chan, int disposition)
2029 {
2030 	fcparam *fcp = FCPARAM(isp, chan);
2031 	int i;
2032 
2033 	if (chan < 0 || chan >= isp->isp_nchan) {
2034 		isp_prt(isp, ISP_LOGWARN, "isp_mark_portdb: bad channel %d", chan);
2035 		return;
2036 	}
2037 	for (i = 0; i < MAX_FC_TARG; i++) {
2038 		if (fcp->portdb[i].target_mode) {
2039 			if (disposition < 0) {
2040 				isp_prt(isp, ISP_LOGTINFO, "isp_mark_portdb: Chan %d zeroing handle 0x" "%04x port 0x%06x", chan,
2041 				    fcp->portdb[i].handle, fcp->portdb[i].portid);
2042 				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2043 			}
2044 			continue;
2045 		}
2046 		if (disposition == 0) {
2047 			ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2048 		} else {
2049 			switch (fcp->portdb[i].state) {
2050 			case FC_PORTDB_STATE_CHANGED:
2051 			case FC_PORTDB_STATE_PENDING_VALID:
2052 			case FC_PORTDB_STATE_VALID:
2053 			case FC_PORTDB_STATE_PROBATIONAL:
2054 				fcp->portdb[i].state = FC_PORTDB_STATE_PROBATIONAL;
2055 				break;
2056 			case FC_PORTDB_STATE_ZOMBIE:
2057 				break;
2058 			case FC_PORTDB_STATE_NIL:
2059 			default:
2060 				ISP_MEMZERO(&fcp->portdb[i], sizeof (fcportdb_t));
2061 				fcp->portdb[i].state = FC_PORTDB_STATE_NIL;
2062 				break;
2063 			}
2064 		}
2065 	}
2066 }
2067 
2068 /*
2069  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
2070  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
2071  */
2072 static int
2073 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags, int gs)
2074 {
2075 	mbreg_t mbs;
2076 	uint8_t q[QENTRY_LEN];
2077 	isp_plogx_t *plp;
2078 	fcparam *fcp;
2079 	uint8_t *scp;
2080 	uint32_t sst, parm1;
2081 	int rval, lev;
2082 	const char *msg;
2083 	char buf[64];
2084 
2085 	if (!IS_24XX(isp)) {
2086 		int action = flags & PLOGX_FLG_CMD_MASK;
2087 		if (action == PLOGX_FLG_CMD_PLOGI) {
2088 			return (isp_port_login(isp, handle, portid));
2089 		} else if (action == PLOGX_FLG_CMD_LOGO) {
2090 			return (isp_port_logout(isp, handle, portid));
2091 		} else {
2092 			return (MBOX_INVALID_COMMAND);
2093 		}
2094 	}
2095 
2096 	ISP_MEMZERO(q, QENTRY_LEN);
2097 	plp = (isp_plogx_t *) q;
2098 	plp->plogx_header.rqs_entry_count = 1;
2099 	plp->plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
2100 	plp->plogx_handle = 0xffffffff;
2101 	plp->plogx_nphdl = handle;
2102 	plp->plogx_vphdl = chan;
2103 	plp->plogx_portlo = portid;
2104 	plp->plogx_rspsz_porthi = (portid >> 16) & 0xff;
2105 	plp->plogx_flags = flags;
2106 
2107 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2108 		isp_print_bytes(isp, "IOCB LOGX", QENTRY_LEN, plp);
2109 	}
2110 
2111 	if (gs == 0) {
2112 		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2113 			isp_prt(isp, ISP_LOGERR, sacq);
2114 			return (-1);
2115 		}
2116 	}
2117 	fcp = FCPARAM(isp, chan);
2118 	scp = fcp->isp_scratch;
2119 	isp_put_plogx(isp, plp, (isp_plogx_t *) scp);
2120 
2121 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
2122 	mbs.param[1] = QENTRY_LEN;
2123 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2124 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2125 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2126 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2127 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
2128 	isp_mboxcmd(isp, &mbs);
2129 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2130 		rval = mbs.param[0];
2131 		goto out;
2132 	}
2133 	MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
2134 	scp += QENTRY_LEN;
2135 	isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
2136 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2137 		isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
2138 	}
2139 
2140 	if (plp->plogx_status == PLOGX_STATUS_OK) {
2141 		rval = 0;
2142 		goto out;
2143 	} else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
2144 		isp_prt(isp, ISP_LOGWARN,
2145 		    "status 0x%x on port login IOCB chanel %d",
2146 		    plp->plogx_status, chan);
2147 		rval = -1;
2148 		goto out;
2149 	}
2150 
2151 	sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
2152 	parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
2153 
2154 	rval = -1;
2155 	lev = ISP_LOGERR;
2156 	msg = NULL;
2157 
2158 	switch (sst) {
2159 	case PLOGX_IOCBERR_NOLINK:
2160 		msg = "no link";
2161 		break;
2162 	case PLOGX_IOCBERR_NOIOCB:
2163 		msg = "no IOCB buffer";
2164 		break;
2165 	case PLOGX_IOCBERR_NOXGHG:
2166 		msg = "no Exchange Control Block";
2167 		break;
2168 	case PLOGX_IOCBERR_FAILED:
2169 		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
2170 		msg = buf;
2171 		break;
2172 	case PLOGX_IOCBERR_NOFABRIC:
2173 		msg = "no fabric";
2174 		break;
2175 	case PLOGX_IOCBERR_NOTREADY:
2176 		msg = "firmware not ready";
2177 		break;
2178 	case PLOGX_IOCBERR_NOLOGIN:
2179 		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
2180 		msg = buf;
2181 		rval = MBOX_NOT_LOGGED_IN;
2182 		break;
2183 	case PLOGX_IOCBERR_REJECT:
2184 		ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2185 		msg = buf;
2186 		break;
2187 	case PLOGX_IOCBERR_NOPCB:
2188 		msg = "no PCB allocated";
2189 		break;
2190 	case PLOGX_IOCBERR_EINVAL:
2191 		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
2192 		msg = buf;
2193 		break;
2194 	case PLOGX_IOCBERR_PORTUSED:
2195 		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2196 		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
2197 		msg = buf;
2198 		rval = MBOX_PORT_ID_USED | (parm1 << 16);
2199 		break;
2200 	case PLOGX_IOCBERR_HNDLUSED:
2201 		lev = ISP_LOGSANCFG|ISP_LOGDEBUG0;
2202 		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
2203 		msg = buf;
2204 		rval = MBOX_LOOP_ID_USED;
2205 		break;
2206 	case PLOGX_IOCBERR_NOHANDLE:
2207 		msg = "no handle allocated";
2208 		break;
2209 	case PLOGX_IOCBERR_NOFLOGI:
2210 		msg = "no FLOGI_ACC";
2211 		break;
2212 	default:
2213 		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
2214 		msg = buf;
2215 		break;
2216 	}
2217 	if (msg) {
2218 		isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
2219 	}
2220 out:
2221 	if (gs == 0) {
2222 		FC_SCRATCH_RELEASE(isp, chan);
2223 	}
2224 	return (rval);
2225 }
2226 
2227 static int
2228 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2229 {
2230 	mbreg_t mbs;
2231 
2232 	MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2233 	if (ISP_CAP_2KLOGIN(isp)) {
2234 		mbs.param[1] = handle;
2235 		mbs.ibits = (1 << 10);
2236 	} else {
2237 		mbs.param[1] = handle << 8;
2238 	}
2239 	mbs.param[2] = portid >> 16;
2240 	mbs.param[3] = portid;
2241 	mbs.logval = MBLOGNONE;
2242 	mbs.timeout = 500000;
2243 	isp_mboxcmd(isp, &mbs);
2244 
2245 	switch (mbs.param[0]) {
2246 	case MBOX_PORT_ID_USED:
2247 		isp_prt(isp, ISP_LOGDEBUG0,
2248 		    "isp_port_login: portid 0x%06x already logged in as %u",
2249 		    portid, mbs.param[1]);
2250 		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2251 
2252 	case MBOX_LOOP_ID_USED:
2253 		isp_prt(isp, ISP_LOGDEBUG0,
2254 		    "isp_port_login: handle 0x%04x in use for port id 0x%02xXXXX",
2255 		    handle, mbs.param[1] & 0xff);
2256 		return (MBOX_LOOP_ID_USED);
2257 
2258 	case MBOX_COMMAND_COMPLETE:
2259 		return (0);
2260 
2261 	case MBOX_COMMAND_ERROR:
2262 		isp_prt(isp, ISP_LOGINFO,
2263 		    "isp_port_login: error 0x%x in PLOGI to port 0x%06x",
2264 		    mbs.param[1], portid);
2265 		return (MBOX_COMMAND_ERROR);
2266 
2267 	case MBOX_ALL_IDS_USED:
2268 		isp_prt(isp, ISP_LOGINFO,
2269 		    "isp_port_login: all IDs used for fabric login");
2270 		return (MBOX_ALL_IDS_USED);
2271 
2272 	default:
2273 		isp_prt(isp, ISP_LOGINFO,
2274 		    "isp_port_login: error 0x%x on port login of 0x%06x@0x%0x",
2275 		    mbs.param[0], portid, handle);
2276 		return (mbs.param[0]);
2277 	}
2278 }
2279 
2280 static int
2281 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2282 {
2283 	mbreg_t mbs;
2284 
2285 	MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2286 	if (ISP_CAP_2KLOGIN(isp)) {
2287 		mbs.param[1] = handle;
2288 		mbs.ibits = (1 << 10);
2289 	} else {
2290 		mbs.param[1] = handle << 8;
2291 	}
2292 	isp_mboxcmd(isp, &mbs);
2293 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2294 }
2295 
2296 static int
2297 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2298 {
2299 	fcparam *fcp = FCPARAM(isp, chan);
2300 	mbreg_t mbs;
2301 	union {
2302 		isp_pdb_21xx_t fred;
2303 		isp_pdb_24xx_t bill;
2304 	} un;
2305 
2306 	MBSINIT(&mbs, MBOX_GET_PORT_DB, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 250000);
2307 	if (IS_24XX(isp)) {
2308 		mbs.ibits = (1 << 9)|(1 << 10);
2309 		mbs.param[1] = id;
2310 		mbs.param[9] = chan;
2311 	} else if (ISP_CAP_2KLOGIN(isp)) {
2312 		mbs.param[1] = id;
2313 	} else {
2314 		mbs.param[1] = id << 8;
2315 	}
2316 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2317 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2318 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2319 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2320 	if (dolock) {
2321 		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2322 			isp_prt(isp, ISP_LOGERR, sacq);
2323 			return (-1);
2324 		}
2325 	}
2326 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
2327 	isp_mboxcmd(isp, &mbs);
2328 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2329 		if (dolock) {
2330 			FC_SCRATCH_RELEASE(isp, chan);
2331 		}
2332 		return (mbs.param[0]);
2333 	}
2334 	if (IS_24XX(isp)) {
2335 		isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2336 		pdb->handle = un.bill.pdb_handle;
2337 		pdb->s3_role = un.bill.pdb_prli_svc3;
2338 		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2339 		ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2340 		ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2341 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2342 		    "Chan %d Port 0x%06x flags 0x%x curstate %x",
2343 		    chan, pdb->portid, un.bill.pdb_flags,
2344 		    un.bill.pdb_curstate);
2345 		if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE ||
2346 		    un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2347 			mbs.param[0] = MBOX_NOT_LOGGED_IN;
2348 			if (dolock) {
2349 				FC_SCRATCH_RELEASE(isp, chan);
2350 			}
2351 			return (mbs.param[0]);
2352 		}
2353 	} else {
2354 		isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2355 		pdb->handle = un.fred.pdb_loopid;
2356 		pdb->s3_role = un.fred.pdb_prli_svc3;
2357 		pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2358 		ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2359 		ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2360 	}
2361 	if (dolock) {
2362 		FC_SCRATCH_RELEASE(isp, chan);
2363 	}
2364 	return (0);
2365 }
2366 
2367 static void
2368 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2369 {
2370 	isp_pdb_t pdb;
2371 	int lim, loopid;
2372 
2373 	if (ISP_CAP_2KLOGIN(isp)) {
2374 		lim = NPH_MAX_2K;
2375 	} else {
2376 		lim = NPH_MAX;
2377 	}
2378 	for (loopid = 0; loopid != lim; loopid++) {
2379 		if (isp_getpdb(isp, chan, loopid, &pdb, dolock)) {
2380 			continue;
2381 		}
2382 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGINFO, "Chan %d Loopid 0x%04x "
2383 		    "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2384 		    chan, loopid, pdb.portid, pdb.portname[0], pdb.portname[1],
2385 		    pdb.portname[2], pdb.portname[3], pdb.portname[4],
2386 		    pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2387 	}
2388 }
2389 
2390 static uint64_t
2391 isp_get_wwn(ispsoftc_t *isp, int chan, int loopid, int nodename)
2392 {
2393 	uint64_t wwn = INI_NONE;
2394 	fcparam *fcp = FCPARAM(isp, chan);
2395 	mbreg_t mbs;
2396 
2397 	if (fcp->isp_fwstate < FW_READY ||
2398 	    fcp->isp_loopstate < LOOP_PDB_RCVD) {
2399 		return (wwn);
2400 	}
2401 	MBSINIT(&mbs, MBOX_GET_PORT_NAME, MBLOGALL & ~MBOX_COMMAND_PARAM_ERROR, 500000);
2402 	if (ISP_CAP_2KLOGIN(isp)) {
2403 		mbs.param[1] = loopid;
2404 		mbs.ibits = (1 << 10);
2405 		if (nodename) {
2406 			mbs.param[10] = 1;
2407 		}
2408 		if (ISP_CAP_MULTI_ID(isp)) {
2409 			mbs.ibits |= (1 << 9);
2410 			mbs.param[9] = chan;
2411 		}
2412 	} else {
2413 		mbs.param[1] = loopid << 8;
2414 		if (nodename) {
2415 			mbs.param[1] |= 1;
2416 		}
2417 	}
2418 	isp_mboxcmd(isp, &mbs);
2419 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2420 		return (wwn);
2421 	}
2422 	if (IS_24XX(isp)) {
2423 		wwn =
2424 		    (((uint64_t)(mbs.param[2] >> 8))	<< 56) |
2425 		    (((uint64_t)(mbs.param[2] & 0xff))	<< 48) |
2426 		    (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
2427 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 32) |
2428 		    (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
2429 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 16) |
2430 		    (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
2431 		    (((uint64_t)(mbs.param[7] & 0xff)));
2432 	} else {
2433 		wwn =
2434 		    (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2435 		    (((uint64_t)(mbs.param[2] >> 8))	<< 48) |
2436 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 40) |
2437 		    (((uint64_t)(mbs.param[3] >> 8))	<< 32) |
2438 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 24) |
2439 		    (((uint64_t)(mbs.param[6] >> 8))	<< 16) |
2440 		    (((uint64_t)(mbs.param[7] & 0xff))	<<  8) |
2441 		    (((uint64_t)(mbs.param[7] >> 8)));
2442 	}
2443 	return (wwn);
2444 }
2445 
2446 /*
2447  * Make sure we have good FC link.
2448  */
2449 
2450 static int
2451 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2452 {
2453 	mbreg_t mbs;
2454 	int count, check_for_fabric, r;
2455 	uint8_t lwfs;
2456 	int loopid;
2457 	fcparam *fcp;
2458 	fcportdb_t *lp;
2459 	isp_pdb_t pdb;
2460 
2461 	fcp = FCPARAM(isp, chan);
2462 
2463 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Entry", chan);
2464 	ISP_MARK_PORTDB(isp, chan, 1);
2465 
2466 	/*
2467 	 * Wait up to N microseconds for F/W to go to a ready state.
2468 	 */
2469 	lwfs = FW_CONFIG_WAIT;
2470 	count = 0;
2471 	while (count < usdelay) {
2472 		uint64_t enano;
2473 		uint32_t wrk;
2474 		NANOTIME_T hra, hrb;
2475 
2476 		GET_NANOTIME(&hra);
2477 		isp_fw_state(isp, chan);
2478 		if (lwfs != fcp->isp_fwstate) {
2479 			isp_prt(isp, ISP_LOGCONFIG|ISP_LOGSANCFG, "Chan %d Firmware State <%s->%s>", chan, isp_fc_fw_statename((int)lwfs), isp_fc_fw_statename((int)fcp->isp_fwstate));
2480 			lwfs = fcp->isp_fwstate;
2481 		}
2482 		if (fcp->isp_fwstate == FW_READY) {
2483 			break;
2484 		}
2485 		GET_NANOTIME(&hrb);
2486 
2487 		/*
2488 		 * Get the elapsed time in nanoseconds.
2489 		 * Always guaranteed to be non-zero.
2490 		 */
2491 		enano = NANOTIME_SUB(&hrb, &hra);
2492 
2493 		isp_prt(isp, ISP_LOGDEBUG1, "usec%d: 0x%lx->0x%lx enano 0x%x%08x", count, (long) GET_NANOSEC(&hra), (long) GET_NANOSEC(&hrb), (uint32_t)(enano >> 32), (uint32_t)(enano));
2494 
2495 		/*
2496 		 * If the elapsed time is less than 1 millisecond,
2497 		 * delay a period of time up to that millisecond of
2498 		 * waiting.
2499 		 *
2500 		 * This peculiar code is an attempt to try and avoid
2501 		 * invoking uint64_t math support functions for some
2502 		 * platforms where linkage is a problem.
2503 		 */
2504 		if (enano < (1000 * 1000)) {
2505 			count += 1000;
2506 			enano = (1000 * 1000) - enano;
2507 			while (enano > (uint64_t) 4000000000U) {
2508 				ISP_SLEEP(isp, 4000000);
2509 				enano -= (uint64_t) 4000000000U;
2510 			}
2511 			wrk = enano;
2512 			wrk /= 1000;
2513 			ISP_SLEEP(isp, wrk);
2514 		} else {
2515 			while (enano > (uint64_t) 4000000000U) {
2516 				count += 4000000;
2517 				enano -= (uint64_t) 4000000000U;
2518 			}
2519 			wrk = enano;
2520 			count += (wrk / 1000);
2521 		}
2522 	}
2523 
2524 
2525 
2526 	/*
2527 	 * If we haven't gone to 'ready' state, return.
2528 	 */
2529 	if (fcp->isp_fwstate != FW_READY) {
2530 		isp_prt(isp, ISP_LOGSANCFG, "%s: chan %d not at FW_READY state", __func__, chan);
2531 		return (-1);
2532 	}
2533 
2534 	/*
2535 	 * Get our Loop ID and Port ID.
2536 	 */
2537 	MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2538 	if (ISP_CAP_MULTI_ID(isp)) {
2539 		mbs.param[9] = chan;
2540 		mbs.ibits = (1 << 9);
2541 		mbs.obits = (1 << 7);
2542 	}
2543 	isp_mboxcmd(isp, &mbs);
2544 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2545 		return (-1);
2546 	}
2547 
2548 	if (ISP_CAP_2KLOGIN(isp)) {
2549 		fcp->isp_loopid = mbs.param[1];
2550 	} else {
2551 		fcp->isp_loopid = mbs.param[1] & 0xff;
2552 	}
2553 
2554 	if (IS_2100(isp)) {
2555 		fcp->isp_topo = TOPO_NL_PORT;
2556 	} else {
2557 		int topo = (int) mbs.param[6];
2558 		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2559 			topo = TOPO_PTP_STUB;
2560 		}
2561 		fcp->isp_topo = topo;
2562 	}
2563 	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2564 
2565 	if (IS_2100(isp)) {
2566 		/*
2567 		 * Don't bother with fabric if we are using really old
2568 		 * 2100 firmware. It's just not worth it.
2569 		 */
2570 		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37)) {
2571 			check_for_fabric = 1;
2572 		} else {
2573 			check_for_fabric = 0;
2574 		}
2575 	} else if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_F_PORT) {
2576 		check_for_fabric = 1;
2577 	} else {
2578 		check_for_fabric = 0;
2579 	}
2580 
2581 	/*
2582 	 * Check to make sure we got a valid loopid
2583 	 * The 24XX seems to mess this up for multiple channels.
2584 	 */
2585 	if (fcp->isp_topo == TOPO_FL_PORT || fcp->isp_topo == TOPO_NL_PORT) {
2586 		uint8_t alpa = fcp->isp_portid;
2587 
2588 		if (alpa == 0) {
2589 			/* "Cannot Happen" */
2590 			isp_prt(isp, ISP_LOGWARN, "Zero AL_PA for Loop Topology?");
2591 		} else {
2592 			int i;
2593 			for (i = 0; alpa_map[i]; i++) {
2594 				if (alpa_map[i] == alpa) {
2595 					break;
2596 				}
2597 			}
2598 			if (alpa_map[i] && fcp->isp_loopid != i) {
2599 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d deriving loopid %d from AL_PA map  (AL_PA 0x%x) and ignoring returned value %d (AL_PA 0x%x)", chan, i, alpa_map[i], fcp->isp_loopid, alpa);
2600 				fcp->isp_loopid = i;
2601 			}
2602 		}
2603 	}
2604 
2605 
2606 	if (IS_24XX(isp)) { /* XXX SHOULDN'T THIS BE FOR 2K F/W? XXX */
2607 		loopid = NPH_FL_ID;
2608 	} else {
2609 		loopid = FL_ID;
2610 	}
2611 	if (check_for_fabric) {
2612 		r = isp_getpdb(isp, chan, loopid, &pdb, 1);
2613 		if (r && (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT)) {
2614 			isp_prt(isp, ISP_LOGWARN, "fabric topology but cannot get info about fabric controller (0x%x)", r);
2615 			fcp->isp_topo = TOPO_PTP_STUB;
2616 		}
2617 	} else {
2618 		r = -1;
2619 	}
2620 	if (r == 0) {
2621 		if (IS_2100(isp)) {
2622 			fcp->isp_topo = TOPO_FL_PORT;
2623 		}
2624 		if (pdb.portid == 0) {
2625 			/*
2626 			 * Crock.
2627 			 */
2628 			fcp->isp_topo = TOPO_NL_PORT;
2629 			goto not_on_fabric;
2630 		}
2631 
2632 		/*
2633 		 * Save the Fabric controller's port database entry.
2634 		 */
2635 		lp = &fcp->portdb[FL_ID];
2636 		lp->state = FC_PORTDB_STATE_PENDING_VALID;
2637 		MAKE_WWN_FROM_NODE_NAME(lp->node_wwn, pdb.nodename);
2638 		MAKE_WWN_FROM_NODE_NAME(lp->port_wwn, pdb.portname);
2639 		lp->roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
2640 		lp->portid = pdb.portid;
2641 		lp->handle = pdb.handle;
2642 		lp->new_portid = lp->portid;
2643 		lp->new_roles = lp->roles;
2644 		if (IS_24XX(isp)) {
2645 			fcp->inorder = (mbs.param[7] & ISP24XX_INORDER) != 0;
2646 			if (ISP_FW_NEWER_THAN(isp, 4, 0, 27)) {
2647 				fcp->npiv_fabric = (mbs.param[7] & ISP24XX_NPIV_SAN) != 0;
2648 				if (fcp->npiv_fabric) {
2649 					isp_prt(isp, ISP_LOGCONFIG, "fabric supports NP-IV");
2650 				}
2651 			}
2652 			if (chan) {
2653 				fcp->isp_sns_hdl = NPH_SNS_HDLBASE + chan;
2654 				r = isp_plogx(isp, chan, fcp->isp_sns_hdl, SNS_PORT_ID, PLOGX_FLG_CMD_PLOGI | PLOGX_FLG_COND_PLOGI | PLOGX_FLG_SKIP_PRLI, 0);
2655 				if (r) {
2656 					isp_prt(isp, ISP_LOGWARN, "%s: Chan %d cannot log into SNS", __func__, chan);
2657 					return (-1);
2658 				}
2659 			} else {
2660 				fcp->isp_sns_hdl = NPH_SNS_ID;
2661 			}
2662 			r = isp_register_fc4_type_24xx(isp, chan);
2663 		} else {
2664 			fcp->isp_sns_hdl = SNS_ID;
2665 			r = isp_register_fc4_type(isp, chan);
2666 		}
2667 		if (r) {
2668 			isp_prt(isp, ISP_LOGWARN|ISP_LOGSANCFG, "%s: register fc4 type failed", __func__);
2669 			return (-1);
2670 		}
2671 	} else {
2672 not_on_fabric:
2673 		fcp->portdb[FL_ID].state = FC_PORTDB_STATE_NIL;
2674 	}
2675 
2676 	fcp->isp_gbspeed = 1;
2677 	if (IS_23XX(isp) || IS_24XX(isp)) {
2678 		MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2679 		mbs.param[1] = MBGSD_GET_RATE;
2680 		/* mbs.param[2] undefined if we're just getting rate */
2681 		isp_mboxcmd(isp, &mbs);
2682 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2683 			if (mbs.param[1] == MBGSD_EIGHTGB) {
2684 				isp_prt(isp, ISP_LOGINFO, "Chan %d 8Gb link speed", chan);
2685 				fcp->isp_gbspeed = 8;
2686 			} else if (mbs.param[1] == MBGSD_FOURGB) {
2687 				isp_prt(isp, ISP_LOGINFO, "Chan %d 4Gb link speed", chan);
2688 				fcp->isp_gbspeed = 4;
2689 			} else if (mbs.param[1] == MBGSD_TWOGB) {
2690 				isp_prt(isp, ISP_LOGINFO, "Chan %d 2Gb link speed", chan);
2691 				fcp->isp_gbspeed = 2;
2692 			} else if (mbs.param[1] == MBGSD_ONEGB) {
2693 				isp_prt(isp, ISP_LOGINFO, "Chan %d 1Gb link speed", chan);
2694 				fcp->isp_gbspeed = 1;
2695 			}
2696 		}
2697 	}
2698 
2699 	/*
2700 	 * Announce ourselves, too.
2701 	 */
2702 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGCONFIG, topology, chan, (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) fcp->isp_wwpn, fcp->isp_portid, fcp->isp_loopid, isp_fc_toponame(fcp));
2703 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0, "Chan %d FC Link Test Complete", chan);
2704 	return (0);
2705 }
2706 
2707 /*
2708  * Complete the synchronization of our Port Database.
2709  *
2710  * At this point, we've scanned the local loop (if any) and the fabric
2711  * and performed fabric logins on all new devices.
2712  *
2713  * Our task here is to go through our port database and remove any entities
2714  * that are still marked probational (issuing PLOGO for ones which we had
2715  * PLOGI'd into) or are dead.
2716  *
2717  * Our task here is to also check policy to decide whether devices which
2718  * have *changed* in some way should still be kept active. For example,
2719  * if a device has just changed PortID, we can either elect to treat it
2720  * as an old device or as a newly arrived device (and notify the outer
2721  * layer appropriately).
2722  *
2723  * We also do initiator map target id assignment here for new initiator
2724  * devices and refresh old ones ot make sure that they point to the corret
2725  * entities.
2726  */
2727 static int
2728 isp_pdb_sync(ispsoftc_t *isp, int chan)
2729 {
2730 	fcparam *fcp = FCPARAM(isp, chan);
2731 	fcportdb_t *lp;
2732 	uint16_t dbidx;
2733 
2734 	if (fcp->isp_loopstate == LOOP_READY) {
2735 		return (0);
2736 	}
2737 
2738 	/*
2739 	 * Make sure we're okay for doing this right now.
2740 	 */
2741 	if (fcp->isp_loopstate != LOOP_PDB_RCVD &&
2742 	    fcp->isp_loopstate != LOOP_FSCAN_DONE &&
2743 	    fcp->isp_loopstate != LOOP_LSCAN_DONE) {
2744 		isp_prt(isp, ISP_LOGWARN, "isp_pdb_sync: bad loopstate %d",
2745 		    fcp->isp_loopstate);
2746 		return (-1);
2747 	}
2748 
2749 	if (fcp->isp_topo == TOPO_FL_PORT ||
2750 	    fcp->isp_topo == TOPO_NL_PORT ||
2751 	    fcp->isp_topo == TOPO_N_PORT) {
2752 		if (fcp->isp_loopstate < LOOP_LSCAN_DONE) {
2753 			if (isp_scan_loop(isp, chan) != 0) {
2754 				isp_prt(isp, ISP_LOGWARN,
2755 				    "isp_pdb_sync: isp_scan_loop failed");
2756 				return (-1);
2757 			}
2758 		}
2759 	}
2760 
2761 	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2762 		if (fcp->isp_loopstate < LOOP_FSCAN_DONE) {
2763 			if (isp_scan_fabric(isp, chan) != 0) {
2764 				isp_prt(isp, ISP_LOGWARN,
2765 				    "isp_pdb_sync: isp_scan_fabric failed");
2766 				return (-1);
2767 			}
2768 		}
2769 	}
2770 
2771 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2772 	    "Chan %d Synchronizing PDBs", chan);
2773 
2774 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
2775 
2776 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
2777 		lp = &fcp->portdb[dbidx];
2778 
2779 		if (lp->state == FC_PORTDB_STATE_NIL || lp->target_mode) {
2780 			continue;
2781 		}
2782 
2783 		if (lp->state == FC_PORTDB_STATE_VALID) {
2784 			if (dbidx != FL_ID) {
2785 				isp_prt(isp,
2786 				    ISP_LOGERR, "portdb idx %d already valid",
2787 			    	    dbidx);
2788 			}
2789 			continue;
2790 		}
2791 
2792 		switch (lp->state) {
2793 		case FC_PORTDB_STATE_PROBATIONAL:
2794 		case FC_PORTDB_STATE_DEAD:
2795 			/*
2796 			 * It's up to the outer layers to clear isp_dev_map.
2797 			 */
2798 			lp->state = FC_PORTDB_STATE_NIL;
2799 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
2800 			if (lp->autologin == 0) {
2801 				(void) isp_plogx(isp, chan, lp->handle,
2802 				    lp->portid,
2803 				    PLOGX_FLG_CMD_LOGO |
2804 				    PLOGX_FLG_IMPLICIT |
2805 				    PLOGX_FLG_FREE_NPHDL, 0);
2806 			} else {
2807 				lp->autologin = 0;
2808 			}
2809 			lp->new_roles = 0;
2810 			lp->new_portid = 0;
2811 			/*
2812 			 * Note that we might come out of this with our state
2813 			 * set to FC_PORTDB_STATE_ZOMBIE.
2814 			 */
2815 			break;
2816 		case FC_PORTDB_STATE_NEW:
2817 			/*
2818 			 * It's up to the outer layers to assign a virtual
2819 			 * target id in isp_dev_map (if any).
2820 			 */
2821 			lp->portid = lp->new_portid;
2822 			lp->roles = lp->new_roles;
2823 			lp->state = FC_PORTDB_STATE_VALID;
2824 			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
2825 			lp->new_roles = 0;
2826 			lp->new_portid = 0;
2827 			lp->reserved = 0;
2828 			lp->new_reserved = 0;
2829 			break;
2830 		case FC_PORTDB_STATE_CHANGED:
2831 /*
2832  * XXXX FIX THIS
2833  */
2834 			lp->state = FC_PORTDB_STATE_VALID;
2835 			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
2836 			lp->new_roles = 0;
2837 			lp->new_portid = 0;
2838 			lp->reserved = 0;
2839 			lp->new_reserved = 0;
2840 			break;
2841 		case FC_PORTDB_STATE_PENDING_VALID:
2842 			lp->portid = lp->new_portid;
2843 			lp->roles = lp->new_roles;
2844 			if (lp->dev_map_idx) {
2845 				int t = lp->dev_map_idx - 1;
2846 				fcp->isp_dev_map[t] = dbidx + 1;
2847 			}
2848 			lp->state = FC_PORTDB_STATE_VALID;
2849 			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
2850 			if (dbidx != FL_ID) {
2851 				lp->new_roles = 0;
2852 				lp->new_portid = 0;
2853 			}
2854 			lp->reserved = 0;
2855 			lp->new_reserved = 0;
2856 			break;
2857 		case FC_PORTDB_STATE_ZOMBIE:
2858 			break;
2859 		default:
2860 			isp_prt(isp, ISP_LOGWARN,
2861 			    "isp_scan_loop: state %d for idx %d",
2862 			    lp->state, dbidx);
2863 			isp_dump_portdb(isp, chan);
2864 		}
2865 	}
2866 
2867 	/*
2868 	 * If we get here, we've for sure seen not only a valid loop
2869 	 * but know what is or isn't on it, so mark this for usage
2870 	 * in isp_start.
2871 	 */
2872 	fcp->loop_seen_once = 1;
2873 	fcp->isp_loopstate = LOOP_READY;
2874 	return (0);
2875 }
2876 
2877 /*
2878  * Scan local loop for devices.
2879  */
2880 static int
2881 isp_scan_loop(ispsoftc_t *isp, int chan)
2882 {
2883 	fcportdb_t *lp, tmp;
2884 	fcparam *fcp = FCPARAM(isp, chan);
2885 	int i;
2886 	isp_pdb_t pdb;
2887 	uint16_t handle, lim = 0;
2888 
2889 	if (fcp->isp_fwstate < FW_READY ||
2890 	    fcp->isp_loopstate < LOOP_PDB_RCVD) {
2891 		return (-1);
2892 	}
2893 
2894 	if (fcp->isp_loopstate > LOOP_SCANNING_LOOP) {
2895 		return (0);
2896 	}
2897 
2898 	/*
2899 	 * Check our connection topology.
2900 	 *
2901 	 * If we're a public or private loop, we scan 0..125 as handle values.
2902 	 * The firmware has (typically) peformed a PLOGI for us. We skip this
2903 	 * step if we're a ISP_24XX in NP-IV mode.
2904 	 *
2905 	 * If we're a N-port connection, we treat this is a short loop (0..1).
2906 	 */
2907 	switch (fcp->isp_topo) {
2908 	case TOPO_NL_PORT:
2909 		lim = LOCAL_LOOP_LIM;
2910 		break;
2911 	case TOPO_FL_PORT:
2912 		if (IS_24XX(isp) && isp->isp_nchan > 1) {
2913 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2914 			    "Chan %d Skipping Local Loop Scan", chan);
2915 			fcp->isp_loopstate = LOOP_LSCAN_DONE;
2916 			return (0);
2917 		}
2918 		lim = LOCAL_LOOP_LIM;
2919 		break;
2920 	case TOPO_N_PORT:
2921 		lim = 2;
2922 		break;
2923 	default:
2924 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2925 		    "Chan %d no loop topology to scan", chan);
2926 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
2927 		return (0);
2928 	}
2929 
2930 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
2931 
2932 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2933 	    "Chan %d FC scan loop 0..%d", chan, lim-1);
2934 
2935 
2936 	/*
2937 	 * Run through the list and get the port database info for each one.
2938 	 */
2939 	for (handle = 0; handle < lim; handle++) {
2940 		int r;
2941 		/*
2942 		 * Don't scan "special" ids.
2943 		 */
2944 		if (handle >= FL_ID && handle <= SNS_ID) {
2945 			continue;
2946 		}
2947 		if (ISP_CAP_2KLOGIN(isp)) {
2948 			if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
2949 				continue;
2950 			}
2951 		}
2952 		/*
2953 		 * In older cards with older f/w GET_PORT_DATABASE has been
2954 		 * known to hang. This trick gets around that problem.
2955 		 */
2956 		if (IS_2100(isp) || IS_2200(isp)) {
2957 			uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
2958 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2959 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2960 				    "Chan %d FC scan loop DONE (bad)", chan);
2961 				return (-1);
2962 			}
2963 			if (node_wwn == INI_NONE) {
2964 				continue;
2965 			}
2966 		}
2967 
2968 		/*
2969 		 * Get the port database entity for this index.
2970 		 */
2971 		r = isp_getpdb(isp, chan, handle, &pdb, 1);
2972 		if (r != 0) {
2973 			isp_prt(isp, ISP_LOGDEBUG1,
2974 			    "Chan %d FC scan loop handle %d returned %x",
2975 			    chan, handle, r);
2976 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2977 				ISP_MARK_PORTDB(isp, chan, 1);
2978 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2979 				    "Chan %d FC scan loop DONE (bad)", chan);
2980 				return (-1);
2981 			}
2982 			continue;
2983 		}
2984 
2985 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2986 			ISP_MARK_PORTDB(isp, chan, 1);
2987 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
2988 			    "Chan %d FC scan loop DONE (bad)", chan);
2989 			return (-1);
2990 		}
2991 
2992 		/*
2993 		 * On *very* old 2100 firmware we would end up sometimes
2994 		 * with the firmware returning the port database entry
2995 		 * for something else. We used to restart this, but
2996 		 * now we just punt.
2997 		 */
2998 		if (IS_2100(isp) && pdb.handle != handle) {
2999 			isp_prt(isp, ISP_LOGWARN,
3000 			    "Chan %d cannot synchronize port database", chan);
3001 			ISP_MARK_PORTDB(isp, chan, 1);
3002 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3003 			    "Chan %d FC scan loop DONE (bad)", chan);
3004 			return (-1);
3005 		}
3006 
3007 		/*
3008 		 * Save the pertinent info locally.
3009 		 */
3010 		MAKE_WWN_FROM_NODE_NAME(tmp.node_wwn, pdb.nodename);
3011 		MAKE_WWN_FROM_NODE_NAME(tmp.port_wwn, pdb.portname);
3012 		tmp.roles = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3013 		tmp.portid = pdb.portid;
3014 		tmp.handle = pdb.handle;
3015 
3016 		/*
3017 		 * Check to make sure it's still a valid entry. The 24XX seems
3018 		 * to return a portid but not a WWPN/WWNN or role for devices
3019 		 * which shift on a loop.
3020 		 */
3021 		if (tmp.node_wwn == 0 || tmp.port_wwn == 0 || tmp.portid == 0) {
3022 			int a, b, c;
3023 			a = (tmp.node_wwn == 0);
3024 			b = (tmp.port_wwn == 0);
3025 			c = (tmp.portid == 0);
3026 			if (a == 0 && b == 0) {
3027 				tmp.node_wwn =
3028 				    isp_get_wwn(isp, chan, handle, 1);
3029 				tmp.port_wwn =
3030 				    isp_get_wwn(isp, chan, handle, 0);
3031 				if (tmp.node_wwn && tmp.port_wwn) {
3032 					isp_prt(isp, ISP_LOGINFO, "DODGED!");
3033 					goto cont;
3034 				}
3035 			}
3036 			isp_prt(isp, ISP_LOGWARN,
3037 			    "Chan %d bad pdb (%1d%1d%1d) @ handle 0x%x", chan,
3038 			    a, b, c, handle);
3039 			isp_dump_portdb(isp, chan);
3040 			continue;
3041 		}
3042   cont:
3043 
3044 		/*
3045 		 * Now search the entire port database
3046 		 * for the same Port and Node WWN.
3047 		 */
3048 		for (i = 0; i < MAX_FC_TARG; i++) {
3049 			lp = &fcp->portdb[i];
3050 
3051 			if (lp->state == FC_PORTDB_STATE_NIL ||
3052 			    lp->target_mode) {
3053 				continue;
3054 			}
3055 			if (lp->node_wwn != tmp.node_wwn) {
3056 				continue;
3057 			}
3058 			if (lp->port_wwn != tmp.port_wwn) {
3059 				continue;
3060 			}
3061 
3062 			/*
3063 			 * Okay- we've found a non-nil entry that matches.
3064 			 * Check to make sure it's probational or a zombie.
3065 			 */
3066 			if (lp->state != FC_PORTDB_STATE_PROBATIONAL &&
3067 			    lp->state != FC_PORTDB_STATE_ZOMBIE) {
3068 				isp_prt(isp, ISP_LOGERR,
3069 				    "Chan %d [%d] not probational/zombie (0x%x)",
3070 				    chan, i, lp->state);
3071 				isp_dump_portdb(isp, chan);
3072 				ISP_MARK_PORTDB(isp, chan, 1);
3073 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3074 				    "Chan %d FC scan loop DONE (bad)", chan);
3075 				return (-1);
3076 			}
3077 
3078 			/*
3079 			 * Mark the device as something the f/w logs into
3080 			 * automatically.
3081 			 */
3082 			lp->autologin = 1;
3083 
3084 			/*
3085 			 * Check to make see if really still the same
3086 			 * device. If it is, we mark it pending valid.
3087 			 */
3088 			if (lp->portid == tmp.portid &&
3089 			    lp->handle == tmp.handle &&
3090 			    lp->roles == tmp.roles) {
3091 				lp->new_portid = tmp.portid;
3092 				lp->new_roles = tmp.roles;
3093 				lp->state = FC_PORTDB_STATE_PENDING_VALID;
3094 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3095 				    "Chan %d Loop Port 0x%06x@0x%04x Pending "
3096 				    "Valid", chan, tmp.portid, tmp.handle);
3097 				break;
3098 			}
3099 
3100 			/*
3101 			 * We can wipe out the old handle value
3102 			 * here because it's no longer valid.
3103 			 */
3104 			lp->handle = tmp.handle;
3105 
3106 			/*
3107 			 * Claim that this has changed and let somebody else
3108 			 * decide what to do.
3109 			 */
3110 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3111 			    "Chan %d Loop Port 0x%06x@0x%04x changed",
3112 			    chan, tmp.portid, tmp.handle);
3113 			lp->state = FC_PORTDB_STATE_CHANGED;
3114 			lp->new_portid = tmp.portid;
3115 			lp->new_roles = tmp.roles;
3116 			break;
3117 		}
3118 
3119 		/*
3120 		 * Did we find and update an old entry?
3121 		 */
3122 		if (i < MAX_FC_TARG) {
3123 			continue;
3124 		}
3125 
3126 		/*
3127 		 * Ah. A new device entry. Find an empty slot
3128 		 * for it and save info for later disposition.
3129 		 */
3130 		for (i = 0; i < MAX_FC_TARG; i++) {
3131 			if (fcp->portdb[i].target_mode) {
3132 				continue;
3133 			}
3134 			if (fcp->portdb[i].state == FC_PORTDB_STATE_NIL) {
3135 				break;
3136 			}
3137 		}
3138 		if (i == MAX_FC_TARG) {
3139 			isp_prt(isp, ISP_LOGERR,
3140 			    "Chan %d out of portdb entries", chan);
3141 			continue;
3142 		}
3143 		lp = &fcp->portdb[i];
3144 
3145 		ISP_MEMZERO(lp, sizeof (fcportdb_t));
3146 		lp->autologin = 1;
3147 		lp->state = FC_PORTDB_STATE_NEW;
3148 		lp->new_portid = tmp.portid;
3149 		lp->new_roles = tmp.roles;
3150 		lp->handle = tmp.handle;
3151 		lp->port_wwn = tmp.port_wwn;
3152 		lp->node_wwn = tmp.node_wwn;
3153 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3154 		    "Chan %d Loop Port 0x%06x@0x%04x is New Entry",
3155 		    chan, tmp.portid, tmp.handle);
3156 	}
3157 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
3158 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3159 	    "Chan %d FC scan loop DONE", chan);
3160 	return (0);
3161 }
3162 
3163 /*
3164  * Scan the fabric for devices and add them to our port database.
3165  *
3166  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3167  *
3168  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3169  * name server commands to the switch management server via the QLogic f/w.
3170  *
3171  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3172  * mailbox command.
3173  *
3174  * The net result is to leave the list of Port IDs setting untranslated in
3175  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3176  * host order at OGPOFF.
3177  */
3178 
3179 /*
3180  * Take less than half of our scratch area to store Port IDs
3181  */
3182 #define	GIDLEN	((ISP_FC_SCRLEN >> 1) - 16 - SNS_GID_FT_REQ_SIZE)
3183 #define	NGENT	((GIDLEN - 16) >> 2)
3184 
3185 #define	IGPOFF	(2 * QENTRY_LEN)
3186 #define	OGPOFF	(ISP_FC_SCRLEN >> 1)
3187 #define	ZTXOFF	(ISP_FC_SCRLEN - (1 * QENTRY_LEN))
3188 #define	CTXOFF	(ISP_FC_SCRLEN - (2 * QENTRY_LEN))
3189 #define	XTXOFF	(ISP_FC_SCRLEN - (3 * QENTRY_LEN))
3190 
3191 static int
3192 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3193 {
3194 	union {
3195 		sns_gid_ft_req_t _x;
3196 		uint8_t _y[SNS_GID_FT_REQ_SIZE];
3197 	} un;
3198 	fcparam *fcp = FCPARAM(isp, chan);
3199 	sns_gid_ft_req_t *rq = &un._x;
3200 	mbreg_t mbs;
3201 
3202 	isp_prt(isp, ISP_LOGDEBUG0,
3203 	    "Chan %d scanning fabric (GID_FT) via SNS", chan);
3204 
3205 	ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3206 	rq->snscb_rblen = GIDLEN >> 1;
3207 	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3208 	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3209 	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3210 	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3211 	rq->snscb_sblen = 6;
3212 	rq->snscb_cmd = SNS_GID_FT;
3213 	rq->snscb_mword_div_2 = NGENT;
3214 	rq->snscb_fc4_type = FC4_SCSI;
3215 
3216 	isp_put_gid_ft_request(isp, rq, fcp->isp_scratch);
3217 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
3218 
3219 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3220 	mbs.param[0] = MBOX_SEND_SNS;
3221 	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3222 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3223 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3224 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3225 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3226 	isp_mboxcmd(isp, &mbs);
3227 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3228 		if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3229 			return (1);
3230 		} else {
3231 			return (-1);
3232 		}
3233 	}
3234 	return (0);
3235 }
3236 
3237 static int
3238 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3239 {
3240 	mbreg_t mbs;
3241 	fcparam *fcp = FCPARAM(isp, chan);
3242 	union {
3243 		isp_ct_pt_t plocal;
3244 		ct_hdr_t clocal;
3245 		uint8_t q[QENTRY_LEN];
3246 	} un;
3247 	isp_ct_pt_t *pt;
3248 	ct_hdr_t *ct;
3249 	uint32_t *rp;
3250 	uint8_t *scp = fcp->isp_scratch;
3251 
3252 	isp_prt(isp, ISP_LOGDEBUG0,
3253 	    "Chan %d scanning fabric (GID_FT) via CT", chan);
3254 
3255 	if (!IS_24XX(isp)) {
3256 		return (1);
3257 	}
3258 
3259 	/*
3260 	 * Build a Passthrough IOCB in memory.
3261 	 */
3262 	pt = &un.plocal;
3263 	ISP_MEMZERO(un.q, QENTRY_LEN);
3264 	pt->ctp_header.rqs_entry_count = 1;
3265 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3266 	pt->ctp_handle = 0xffffffff;
3267 	pt->ctp_nphdl = fcp->isp_sns_hdl;
3268 	pt->ctp_cmd_cnt = 1;
3269 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3270 	pt->ctp_time = 30;
3271 	pt->ctp_rsp_cnt = 1;
3272 	pt->ctp_rsp_bcnt = GIDLEN;
3273 	pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3274 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3275 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3276 	pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3277 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3278 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3279 	pt->ctp_dataseg[1].ds_count = GIDLEN;
3280 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3281 		isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3282 	}
3283 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3284 
3285 	/*
3286 	 * Build the CT header and command in memory.
3287 	 *
3288 	 * Note that the CT header has to end up as Big Endian format in memory.
3289 	 */
3290 	ct = &un.clocal;
3291 	ISP_MEMZERO(ct, sizeof (*ct));
3292 	ct->ct_revision = CT_REVISION;
3293 	ct->ct_fcs_type = CT_FC_TYPE_FC;
3294 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3295 	ct->ct_cmd_resp = SNS_GID_FT;
3296 	ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3297 
3298 	isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3299 	rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3300 	ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3301 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3302 		isp_print_bytes(isp, "CT HDR + payload after put",
3303 		    sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3304 	}
3305 	ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3306 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3307 	mbs.param[1] = QENTRY_LEN;
3308 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3309 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3310 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3311 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3312 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
3313 	isp_mboxcmd(isp, &mbs);
3314 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3315 		return (-1);
3316 	}
3317 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
3318 	pt = &un.plocal;
3319 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3320 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3321 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3322 	}
3323 
3324 	if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3325 		isp_prt(isp, ISP_LOGWARN,
3326 		    "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3327 		    chan, pt->ctp_status);
3328 		return (-1);
3329 	}
3330 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN + 16, chan);
3331 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3332 		isp_print_bytes(isp, "CT response", GIDLEN+16, &scp[IGPOFF]);
3333 	}
3334 	return (0);
3335 }
3336 
3337 static int
3338 isp_scan_fabric(ispsoftc_t *isp, int chan)
3339 {
3340 	fcparam *fcp = FCPARAM(isp, chan);
3341 	uint32_t portid;
3342 	uint16_t handle, oldhandle, loopid;
3343 	isp_pdb_t pdb;
3344 	int portidx, portlim, r;
3345 	sns_gid_ft_rsp_t *rs0, *rs1;
3346 
3347 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3348 	    "Chan %d FC Scan Fabric", chan);
3349 	if (fcp->isp_fwstate != FW_READY ||
3350 	    fcp->isp_loopstate < LOOP_LSCAN_DONE) {
3351 		return (-1);
3352 	}
3353 	if (fcp->isp_loopstate > LOOP_SCANNING_FABRIC) {
3354 		return (0);
3355 	}
3356 	if (fcp->isp_topo != TOPO_FL_PORT && fcp->isp_topo != TOPO_F_PORT) {
3357 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3358 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3359 		    "Chan %d FC Scan Fabric Done (no fabric)", chan);
3360 		return (0);
3361 	}
3362 
3363 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3364 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3365 		isp_prt(isp, ISP_LOGERR, sacq);
3366 		ISP_MARK_PORTDB(isp, chan, 1);
3367 		return (-1);
3368 	}
3369 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3370 		FC_SCRATCH_RELEASE(isp, chan);
3371 		ISP_MARK_PORTDB(isp, chan, 1);
3372 		return (-1);
3373 	}
3374 
3375 	/*
3376 	 * Make sure we still are logged into the fabric controller.
3377 	 */
3378 	if (IS_24XX(isp)) {	/* XXX SHOULDN'T THIS BE TRUE FOR 2K F/W? XXX */
3379 		loopid = NPH_FL_ID;
3380 	} else {
3381 		loopid = FL_ID;
3382 	}
3383 	r = isp_getpdb(isp, chan, loopid, &pdb, 0);
3384 	if (r == MBOX_NOT_LOGGED_IN) {
3385 		isp_dump_chip_portdb(isp, chan, 0);
3386 	}
3387 	if (r) {
3388 		fcp->isp_loopstate = LOOP_PDB_RCVD;
3389 		FC_SCRATCH_RELEASE(isp, chan);
3390 		ISP_MARK_PORTDB(isp, chan, 1);
3391 		return (-1);
3392 	}
3393 
3394 	if (IS_24XX(isp)) {
3395 		r = isp_gid_ft_ct_passthru(isp, chan);
3396 	} else {
3397 		r = isp_gid_ft_sns(isp, chan);
3398 	}
3399 
3400 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3401 		FC_SCRATCH_RELEASE(isp, chan);
3402 		ISP_MARK_PORTDB(isp, chan, 1);
3403 		return (-1);
3404 	}
3405 
3406 	if (r > 0) {
3407 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3408 		FC_SCRATCH_RELEASE(isp, chan);
3409 		return (0);
3410 	} else if (r < 0) {
3411 		fcp->isp_loopstate = LOOP_PDB_RCVD;	/* try again */
3412 		FC_SCRATCH_RELEASE(isp, chan);
3413 		return (0);
3414 	}
3415 
3416 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
3417 	rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3418 	rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3419 	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3420 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3421 		FC_SCRATCH_RELEASE(isp, chan);
3422 		ISP_MARK_PORTDB(isp, chan, 1);
3423 		return (-1);
3424 	}
3425 	if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3426 		int level;
3427 		if (rs1->snscb_cthdr.ct_reason == 9 &&
3428 		    rs1->snscb_cthdr.ct_explanation == 7) {
3429 			level = ISP_LOGSANCFG|ISP_LOGDEBUG0;
3430 		} else {
3431 			level = ISP_LOGWARN;
3432 		}
3433 		isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3434 		    " (Reason=0x%x Expl=0x%x)", chan,
3435 		    rs1->snscb_cthdr.ct_reason,
3436 		    rs1->snscb_cthdr.ct_explanation);
3437 		FC_SCRATCH_RELEASE(isp, chan);
3438 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3439 		return (0);
3440 	}
3441 
3442 
3443 	/*
3444 	 * If we get this far, we certainly still have the fabric controller.
3445 	 */
3446 	fcp->portdb[FL_ID].state = FC_PORTDB_STATE_PENDING_VALID;
3447 
3448 	/*
3449 	 * Prime the handle we will start using.
3450 	 */
3451 	oldhandle = FCPARAM(isp, 0)->isp_lasthdl;
3452 
3453 	/*
3454 	 * Go through the list and remove duplicate port ids.
3455 	 */
3456 
3457 	portlim = 0;
3458 	portidx = 0;
3459 	for (portidx = 0; portidx < NGENT-1; portidx++) {
3460 		if (rs1->snscb_ports[portidx].control & 0x80) {
3461 			break;
3462 		}
3463 	}
3464 
3465 	/*
3466 	 * If we're not at the last entry, our list wasn't big enough.
3467 	 */
3468 	if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3469 		isp_prt(isp, ISP_LOGWARN,
3470 		    "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3471 	}
3472 	portlim = portidx + 1;
3473 	isp_prt(isp, ISP_LOGSANCFG,
3474 	    "Chan %d got %d ports back from name server", chan, portlim);
3475 
3476 	for (portidx = 0; portidx < portlim; portidx++) {
3477 		int npidx;
3478 
3479 		portid =
3480 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3481 		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3482 		    ((rs1->snscb_ports[portidx].portid[2]));
3483 
3484 		for (npidx = portidx + 1; npidx < portlim; npidx++) {
3485 			uint32_t new_portid =
3486 			    ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3487 			    ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3488 			    ((rs1->snscb_ports[npidx].portid[2]));
3489 			if (new_portid == portid) {
3490 				break;
3491 			}
3492 		}
3493 
3494 		if (npidx < portlim) {
3495 			rs1->snscb_ports[npidx].portid[0] = 0;
3496 			rs1->snscb_ports[npidx].portid[1] = 0;
3497 			rs1->snscb_ports[npidx].portid[2] = 0;
3498 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3499 			    "Chan %d removing duplicate PortID 0x%06x"
3500 			    " entry from list", chan, portid);
3501 		}
3502 	}
3503 
3504 	/*
3505 	 * We now have a list of Port IDs for all FC4 SCSI devices
3506 	 * that the Fabric Name server knows about.
3507 	 *
3508 	 * For each entry on this list go through our port database looking
3509 	 * for probational entries- if we find one, then an old entry is
3510 	 * maybe still this one. We get some information to find out.
3511 	 *
3512 	 * Otherwise, it's a new fabric device, and we log into it
3513 	 * (unconditionally). After searching the entire database
3514 	 * again to make sure that we never ever ever ever have more
3515 	 * than one entry that has the same PortID or the same
3516 	 * WWNN/WWPN duple, we enter the device into our database.
3517 	 */
3518 
3519 	for (portidx = 0; portidx < portlim; portidx++) {
3520 		fcportdb_t *lp;
3521 		uint64_t wwnn, wwpn;
3522 		int dbidx, nr;
3523 
3524 		portid =
3525 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3526 		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3527 		    ((rs1->snscb_ports[portidx].portid[2]));
3528 
3529 		if (portid == 0) {
3530 			isp_prt(isp, ISP_LOGSANCFG,
3531 			    "Chan %d skipping null PortID at idx %d",
3532 			    chan, portidx);
3533 			continue;
3534 		}
3535 
3536 		/*
3537 		 * Skip ourselves here and on other channels. If we're
3538 		 * multi-id, we can't check the portids in other FCPARAM
3539 		 * arenas because the resolutions here aren't synchronized.
3540 		 * The best way to do this is to exclude looking at portids
3541 		 * that have the same domain and area code as our own
3542 		 * portid.
3543 		 */
3544 		if (ISP_CAP_MULTI_ID(isp)) {
3545 			if ((portid >> 8) == (fcp->isp_portid >> 8)) {
3546 				isp_prt(isp, ISP_LOGSANCFG,
3547 				    "Chan %d skip PortID 0x%06x",
3548 				    chan, portid);
3549 				continue;
3550 			}
3551 		} else if (portid == fcp->isp_portid) {
3552 			isp_prt(isp, ISP_LOGSANCFG,
3553 			    "Chan %d skip ourselves on @ PortID 0x%06x",
3554 			    chan, portid);
3555 			continue;
3556 		}
3557 
3558 		isp_prt(isp, ISP_LOGSANCFG,
3559 		    "Chan %d Checking Fabric Port 0x%06x", chan, portid);
3560 
3561 		/*
3562 		 * We now search our Port Database for any
3563 		 * probational entries with this PortID. We don't
3564 		 * look for zombies here- only probational
3565 		 * entries (we've already logged out of zombies).
3566 		 */
3567 		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3568 			lp = &fcp->portdb[dbidx];
3569 
3570 			if (lp->state != FC_PORTDB_STATE_PROBATIONAL ||
3571 			    lp->target_mode) {
3572 				continue;
3573 			}
3574 			if (lp->portid == portid) {
3575 				break;
3576 			}
3577 		}
3578 
3579 		/*
3580 		 * We found a probational entry with this Port ID.
3581 		 */
3582 		if (dbidx < MAX_FC_TARG) {
3583 			int handle_changed = 0;
3584 
3585 			lp = &fcp->portdb[dbidx];
3586 
3587 			/*
3588 			 * See if we're still logged into it.
3589 			 *
3590 			 * If we aren't, mark it as a dead device and
3591 			 * leave the new portid in the database entry
3592 			 * for somebody further along to decide what to
3593 			 * do (policy choice).
3594 			 *
3595 			 * If we are, check to see if it's the same
3596 			 * device still (it should be). If for some
3597 			 * reason it isn't, mark it as a changed device
3598 			 * and leave the new portid and role in the
3599 			 * database entry for somebody further along to
3600 			 * decide what to do (policy choice).
3601 			 *
3602 			 */
3603 
3604 			r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3605 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3606 				FC_SCRATCH_RELEASE(isp, chan);
3607 				ISP_MARK_PORTDB(isp, chan, 1);
3608 				return (-1);
3609 			}
3610 			if (r != 0) {
3611 				lp->new_portid = portid;
3612 				lp->state = FC_PORTDB_STATE_DEAD;
3613 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3614 				    "Chan %d Fabric Port 0x%06x is dead",
3615 				    chan, portid);
3616 				continue;
3617 			}
3618 
3619 
3620 			/*
3621 			 * Check to make sure that handle, portid, WWPN and
3622 			 * WWNN agree. If they don't, then the association
3623 			 * between this PortID and the stated handle has been
3624 			 * broken by the firmware.
3625 			 */
3626 			MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3627 			MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3628 			if (pdb.handle != lp->handle ||
3629 			    pdb.portid != portid ||
3630 			    wwpn != lp->port_wwn ||
3631 			    wwnn != lp->node_wwn) {
3632 				isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3633 				    fconf, chan, dbidx, pdb.handle, pdb.portid,
3634 				    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3635 				    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3636 				    lp->handle, portid,
3637 				    (uint32_t) (lp->node_wwn >> 32),
3638 				    (uint32_t) lp->node_wwn,
3639 				    (uint32_t) (lp->port_wwn >> 32),
3640 				    (uint32_t) lp->port_wwn);
3641 				/*
3642 				 * Try to re-login to this device using a
3643 				 * new handle. If that fails, mark it dead.
3644 				 *
3645 				 * isp_login_device will check for handle and
3646 				 * portid consistency after re-login.
3647 				 *
3648 				 */
3649 				if (isp_login_device(isp, chan, portid, &pdb,
3650 				    &oldhandle)) {
3651 					lp->new_portid = portid;
3652 					lp->state = FC_PORTDB_STATE_DEAD;
3653 					if (fcp->isp_loopstate !=
3654 					    LOOP_SCANNING_FABRIC) {
3655 						FC_SCRATCH_RELEASE(isp, chan);
3656 						ISP_MARK_PORTDB(isp, chan, 1);
3657 						return (-1);
3658 					}
3659 					continue;
3660 				}
3661 				if (fcp->isp_loopstate !=
3662 				    LOOP_SCANNING_FABRIC) {
3663 					FC_SCRATCH_RELEASE(isp, chan);
3664 					ISP_MARK_PORTDB(isp, chan, 1);
3665 					return (-1);
3666 				}
3667 				FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3668 				MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3669 				MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3670 				if (wwpn != lp->port_wwn ||
3671 				    wwnn != lp->node_wwn) {
3672 					isp_prt(isp, ISP_LOGWARN, "changed WWN"
3673 					    " after relogin");
3674 					lp->new_portid = portid;
3675 					lp->state = FC_PORTDB_STATE_DEAD;
3676 					continue;
3677 				}
3678 
3679 				lp->handle = pdb.handle;
3680 				handle_changed++;
3681 			}
3682 
3683 			nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3684 
3685 			/*
3686 			 * Check to see whether the portid and roles have
3687 			 * stayed the same. If they have stayed the same,
3688 			 * we believe that this is the same device and it
3689 			 * hasn't become disconnected and reconnected, so
3690 			 * mark it as pending valid.
3691 			 *
3692 			 * If they aren't the same, mark the device as a
3693 			 * changed device and save the new port id and role
3694 			 * and let somebody else decide.
3695 			 */
3696 
3697 			lp->new_portid = portid;
3698 			lp->new_roles = nr;
3699 			if (pdb.portid != lp->portid || nr != lp->roles ||
3700 			    handle_changed) {
3701 				isp_prt(isp, ISP_LOGSANCFG,
3702 				    "Chan %d Fabric Port 0x%06x changed",
3703 				    chan, portid);
3704 				lp->state = FC_PORTDB_STATE_CHANGED;
3705 			} else {
3706 				isp_prt(isp, ISP_LOGSANCFG,
3707 				    "Chan %d Fabric Port 0x%06x "
3708 				    "Now Pending Valid", chan, portid);
3709 				lp->state = FC_PORTDB_STATE_PENDING_VALID;
3710 			}
3711 			continue;
3712 		}
3713 
3714 		/*
3715 		 * Ah- a new entry. Search the database again for all non-NIL
3716 		 * entries to make sure we never ever make a new database entry
3717 		 * with the same port id. While we're at it, mark where the
3718 		 * last free entry was.
3719 		 */
3720 
3721 		dbidx = MAX_FC_TARG;
3722 		for (lp = fcp->portdb; lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
3723 			if (lp >= &fcp->portdb[FL_ID] &&
3724 			    lp <= &fcp->portdb[SNS_ID]) {
3725 				continue;
3726 			}
3727 			/*
3728 			 * Skip any target mode entries.
3729 			 */
3730 			if (lp->target_mode) {
3731 				continue;
3732 			}
3733 			if (lp->state == FC_PORTDB_STATE_NIL) {
3734 				if (dbidx == MAX_FC_TARG) {
3735 					dbidx = lp - fcp->portdb;
3736 				}
3737 				continue;
3738 			}
3739 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3740 				continue;
3741 			}
3742 			if (lp->portid == portid) {
3743 				break;
3744 			}
3745 		}
3746 
3747 		if (lp < &fcp->portdb[MAX_FC_TARG]) {
3748 			isp_prt(isp, ISP_LOGWARN, "Chan %d PortID 0x%06x "
3749 			    "already at %d handle %d state %d",
3750 			    chan, portid, dbidx, lp->handle, lp->state);
3751 			continue;
3752 		}
3753 
3754 		/*
3755 		 * We should have the index of the first free entry seen.
3756 		 */
3757 		if (dbidx == MAX_FC_TARG) {
3758 			isp_prt(isp, ISP_LOGERR,
3759 			    "port database too small to login PortID 0x%06x"
3760 			    "- increase MAX_FC_TARG", portid);
3761 			continue;
3762 		}
3763 
3764 		/*
3765 		 * Otherwise, point to our new home.
3766 		 */
3767 		lp = &fcp->portdb[dbidx];
3768 
3769 		/*
3770 		 * Try to see if we are logged into this device,
3771 		 * and maybe log into it.
3772 		 *
3773 		 * isp_login_device will check for handle and
3774 		 * portid consistency after login.
3775 		 */
3776 		if (isp_login_device(isp, chan, portid, &pdb, &oldhandle)) {
3777 			if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3778 				FC_SCRATCH_RELEASE(isp, chan);
3779 				ISP_MARK_PORTDB(isp, chan, 1);
3780 				return (-1);
3781 			}
3782 			continue;
3783 		}
3784 		if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3785 			FC_SCRATCH_RELEASE(isp, chan);
3786 			ISP_MARK_PORTDB(isp, chan, 1);
3787 			return (-1);
3788 		}
3789 		FCPARAM(isp, 0)->isp_lasthdl = oldhandle;
3790 
3791 		handle = pdb.handle;
3792 		MAKE_WWN_FROM_NODE_NAME(wwnn, pdb.nodename);
3793 		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3794 		nr = (pdb.s3_role & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
3795 
3796 		/*
3797 		 * And go through the database *one* more time to make sure
3798 		 * that we do not make more than one entry that has the same
3799 		 * WWNN/WWPN duple
3800 		 */
3801 		for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3802 			if (dbidx >= FL_ID && dbidx <= SNS_ID) {
3803 				continue;
3804 			}
3805 			if (fcp->portdb[dbidx].target_mode) {
3806 				continue;
3807 			}
3808 			if (fcp->portdb[dbidx].node_wwn == wwnn &&
3809 			    fcp->portdb[dbidx].port_wwn == wwpn) {
3810 				break;
3811 			}
3812 		}
3813 
3814 		if (dbidx == MAX_FC_TARG) {
3815 			ISP_MEMZERO(lp, sizeof (fcportdb_t));
3816 			lp->handle = handle;
3817 			lp->node_wwn = wwnn;
3818 			lp->port_wwn = wwpn;
3819 			lp->new_portid = portid;
3820 			lp->new_roles = nr;
3821 			lp->state = FC_PORTDB_STATE_NEW;
3822 			isp_prt(isp, ISP_LOGSANCFG,
3823 			    "Chan %d Fabric Port 0x%06x is a New Entry",
3824 			    chan, portid);
3825 			continue;
3826 		}
3827 
3828     		if (fcp->portdb[dbidx].state != FC_PORTDB_STATE_ZOMBIE) {
3829 			isp_prt(isp, ISP_LOGWARN,
3830 			    "Chan %d PortID 0x%x 0x%08x%08x/0x%08x%08x %ld "
3831 			    "already at idx %d, state 0x%x", chan, portid,
3832 			    (uint32_t) (wwnn >> 32), (uint32_t) wwnn,
3833 			    (uint32_t) (wwpn >> 32), (uint32_t) wwpn,
3834 			    (long) (lp - fcp->portdb), dbidx,
3835 			    fcp->portdb[dbidx].state);
3836 			continue;
3837 		}
3838 
3839 		/*
3840 		 * We found a zombie entry that matches us.
3841 		 * Revive it. We know that WWN and WWPN
3842 		 * are the same. For fabric devices, we
3843 		 * don't care that handle is different
3844 		 * as we assign that. If role or portid
3845 		 * are different, it maybe a changed device.
3846 		 */
3847 		lp = &fcp->portdb[dbidx];
3848 		lp->handle = handle;
3849 		lp->new_portid = portid;
3850 		lp->new_roles = nr;
3851 		if (lp->portid != portid || lp->roles != nr) {
3852 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3853 			    "Chan %d Zombie Fabric Port 0x%06x Now Changed",
3854 			    chan, portid);
3855 			lp->state = FC_PORTDB_STATE_CHANGED;
3856 		} else {
3857 			isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3858 			    "Chan %d Zombie Fabric Port 0x%06x "
3859 			    "Now Pending Valid", chan, portid);
3860 			lp->state = FC_PORTDB_STATE_PENDING_VALID;
3861 		}
3862 	}
3863 
3864 	FC_SCRATCH_RELEASE(isp, chan);
3865 	if (fcp->isp_loopstate != LOOP_SCANNING_FABRIC) {
3866 		ISP_MARK_PORTDB(isp, chan, 1);
3867 		return (-1);
3868 	}
3869 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
3870 	isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
3871 	    "Chan %d FC Scan Fabric Done", chan);
3872 	return (0);
3873 }
3874 
3875 /*
3876  * Find an unused handle and try and use to login to a port.
3877  */
3878 static int
3879 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
3880 {
3881 	int lim, i, r;
3882 	uint16_t handle;
3883 
3884 	if (ISP_CAP_2KLOGIN(isp)) {
3885 		lim = NPH_MAX_2K;
3886 	} else {
3887 		lim = NPH_MAX;
3888 	}
3889 
3890 	handle = isp_nxt_handle(isp, chan, *ohp);
3891 	for (i = 0; i < lim; i++) {
3892 		/*
3893 		 * See if we're still logged into something with
3894 		 * this handle and that something agrees with this
3895 		 * port id.
3896 		 */
3897 		r = isp_getpdb(isp, chan, handle, p, 0);
3898 		if (r == 0 && p->portid != portid) {
3899 			(void) isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1);
3900 		} else if (r == 0) {
3901 			break;
3902 		}
3903 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3904 			return (-1);
3905 		}
3906 		/*
3907 		 * Now try and log into the device
3908 		 */
3909 		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3910 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3911 			return (-1);
3912 		}
3913 		if (r == 0) {
3914 			*ohp = handle;
3915 			break;
3916 		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3917 			/*
3918 			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
3919 			 * handle. We need to break that association. We used to try and just substitute the handle, but then
3920 			 * failed to get any data via isp_getpdb (below).
3921 			 */
3922 			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
3923 				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
3924 			}
3925 			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3926 				return (-1);
3927 			}
3928 			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3929 			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3930 				return (-1);
3931 			}
3932 			if (r == 0) {
3933 				*ohp = handle;
3934 			} else {
3935 				i = lim;
3936 			}
3937 			break;
3938 		} else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
3939 			/*
3940 			 * Try the next loop id.
3941 			 */
3942 			*ohp = handle;
3943 			handle = isp_nxt_handle(isp, chan, handle);
3944 		} else {
3945 			/*
3946 			 * Give up.
3947 			 */
3948 			i = lim;
3949 			break;
3950 		}
3951 	}
3952 
3953 	if (i == lim) {
3954 		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
3955 		return (-1);
3956 	}
3957 
3958 	/*
3959 	 * If we successfully logged into it, get the PDB for it
3960 	 * so we can crosscheck that it is still what we think it
3961 	 * is and that we also have the role it plays
3962 	 */
3963 	r = isp_getpdb(isp, chan, handle, p, 0);
3964 	if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC) {
3965 		return (-1);
3966 	}
3967 	if (r != 0) {
3968 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
3969 		return (-1);
3970 	}
3971 
3972 	if (p->handle != handle || p->portid != portid) {
3973 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3974 		    chan, portid, handle, p->portid, p->handle);
3975 		return (-1);
3976 	}
3977 	return (0);
3978 }
3979 
3980 static int
3981 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3982 {
3983 	fcparam *fcp = FCPARAM(isp, chan);
3984 	uint8_t local[SNS_RFT_ID_REQ_SIZE];
3985 	sns_screq_t *reqp = (sns_screq_t *) local;
3986 	mbreg_t mbs;
3987 
3988 	ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3989 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3990 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
3991 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
3992 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
3993 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
3994 	reqp->snscb_sblen = 22;
3995 	reqp->snscb_data[0] = SNS_RFT_ID;
3996 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
3997 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
3998 	reqp->snscb_data[6] = (1 << FC4_SCSI);
3999 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4000 		isp_prt(isp, ISP_LOGERR, sacq);
4001 		return (-1);
4002 	}
4003 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
4004 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
4005 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
4006 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4007 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4008 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4009 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4010 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan);
4011 	isp_mboxcmd(isp, &mbs);
4012 	FC_SCRATCH_RELEASE(isp, chan);
4013 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4014 		return (0);
4015 	} else {
4016 		return (-1);
4017 	}
4018 }
4019 
4020 static int
4021 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
4022 {
4023 	mbreg_t mbs;
4024 	fcparam *fcp = FCPARAM(isp, chan);
4025 	union {
4026 		isp_ct_pt_t plocal;
4027 		rft_id_t clocal;
4028 		uint8_t q[QENTRY_LEN];
4029 	} un;
4030 	isp_ct_pt_t *pt;
4031 	ct_hdr_t *ct;
4032 	rft_id_t *rp;
4033 	uint8_t *scp = fcp->isp_scratch;
4034 
4035 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4036 		isp_prt(isp, ISP_LOGERR, sacq);
4037 		return (-1);
4038 	}
4039 
4040 	/*
4041 	 * Build a Passthrough IOCB in memory.
4042 	 */
4043 	ISP_MEMZERO(un.q, QENTRY_LEN);
4044 	pt = &un.plocal;
4045 	pt->ctp_header.rqs_entry_count = 1;
4046 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
4047 	pt->ctp_handle = 0xffffffff;
4048 	pt->ctp_nphdl = fcp->isp_sns_hdl;
4049 	pt->ctp_cmd_cnt = 1;
4050 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
4051 	pt->ctp_time = 1;
4052 	pt->ctp_rsp_cnt = 1;
4053 	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
4054 	pt->ctp_cmd_bcnt = sizeof (rft_id_t);
4055 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
4056 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
4057 	pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
4058 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
4059 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
4060 	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
4061 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
4062 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4063 		isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
4064 	}
4065 
4066 	/*
4067 	 * Build the CT header and command in memory.
4068 	 *
4069 	 * Note that the CT header has to end up as Big Endian format in memory.
4070 	 */
4071 	ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
4072 	ct = &un.clocal.rftid_hdr;
4073 	ct->ct_revision = CT_REVISION;
4074 	ct->ct_fcs_type = CT_FC_TYPE_FC;
4075 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4076 	ct->ct_cmd_resp = SNS_RFT_ID;
4077 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
4078 	rp = &un.clocal;
4079 	rp->rftid_portid[0] = fcp->isp_portid >> 16;
4080 	rp->rftid_portid[1] = fcp->isp_portid >> 8;
4081 	rp->rftid_portid[2] = fcp->isp_portid;
4082 	rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
4083 	isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
4084 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4085 		isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4086 	}
4087 
4088 	ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4089 
4090 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4091 	mbs.param[1] = QENTRY_LEN;
4092 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4093 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4094 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4095 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4096 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
4097 	isp_mboxcmd(isp, &mbs);
4098 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4099 		FC_SCRATCH_RELEASE(isp, chan);
4100 		return (-1);
4101 	}
4102 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
4103 	pt = &un.plocal;
4104 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4105 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4106 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4107 	}
4108 	if (pt->ctp_status) {
4109 		FC_SCRATCH_RELEASE(isp, chan);
4110 		isp_prt(isp, ISP_LOGWARN,
4111 		    "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
4112 		    chan, pt->ctp_status);
4113 		return (1);
4114 	}
4115 
4116 	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4117 	FC_SCRATCH_RELEASE(isp, chan);
4118 
4119 	if (ct->ct_cmd_resp == LS_RJT) {
4120 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4121 		    "Chan %d Register FC4 Type rejected", chan);
4122 		return (-1);
4123 	} else if (ct->ct_cmd_resp == LS_ACC) {
4124 		isp_prt(isp, ISP_LOGSANCFG|ISP_LOGDEBUG0,
4125 		    "Chan %d Register FC4 Type accepted", chan);
4126 		return (0);
4127 	} else {
4128 		isp_prt(isp, ISP_LOGWARN,
4129 		    "Chan %d Register FC4 Type: 0x%x",
4130 		    chan, ct->ct_cmd_resp);
4131 		return (-1);
4132 	}
4133 }
4134 
4135 static uint16_t
4136 isp_nxt_handle(ispsoftc_t *isp, int chan, uint16_t handle)
4137 {
4138 	int i;
4139 	if (handle == NIL_HANDLE) {
4140 		if (FCPARAM(isp, chan)->isp_topo == TOPO_F_PORT) {
4141 			handle = 0;
4142 		} else {
4143 			handle = SNS_ID+1;
4144 		}
4145 	} else {
4146 		handle += 1;
4147 		if (handle >= FL_ID && handle <= SNS_ID) {
4148 			handle = SNS_ID+1;
4149 		}
4150 		if (handle >= NPH_RESERVED && handle <= NPH_FL_ID) {
4151 			handle = NPH_FL_ID+1;
4152 		}
4153 		if (ISP_CAP_2KLOGIN(isp)) {
4154 			if (handle == NPH_MAX_2K) {
4155 				handle = 0;
4156 			}
4157 		} else {
4158 			if (handle == NPH_MAX) {
4159 				handle = 0;
4160 			}
4161 		}
4162 	}
4163 	if (handle == FCPARAM(isp, chan)->isp_loopid) {
4164 		return (isp_nxt_handle(isp, chan, handle));
4165 	}
4166 	for (i = 0; i < MAX_FC_TARG; i++) {
4167 		if (FCPARAM(isp, chan)->portdb[i].state ==
4168 		    FC_PORTDB_STATE_NIL) {
4169 			continue;
4170 		}
4171 		if (FCPARAM(isp, chan)->portdb[i].handle == handle) {
4172 			return (isp_nxt_handle(isp, chan, handle));
4173 		}
4174 	}
4175 	return (handle);
4176 }
4177 
4178 /*
4179  * Start a command. Locking is assumed done in the caller.
4180  */
4181 
4182 int
4183 isp_start(XS_T *xs)
4184 {
4185 	ispsoftc_t *isp;
4186 	uint32_t handle, cdblen;
4187 	uint8_t local[QENTRY_LEN];
4188 	ispreq_t *reqp;
4189 	void *cdbp, *qep;
4190 	uint16_t *tptr;
4191 	int target, dmaresult, hdlidx = 0;
4192 
4193 	XS_INITERR(xs);
4194 	isp = XS_ISP(xs);
4195 
4196 	/*
4197 	 * Now make sure we're running.
4198 	 */
4199 
4200 	if (isp->isp_state != ISP_RUNSTATE) {
4201 		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4202 		XS_SETERR(xs, HBA_BOTCH);
4203 		return (CMD_COMPLETE);
4204 	}
4205 
4206 	/*
4207 	 * Check command CDB length, etc.. We really are limited to 16 bytes
4208 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4209 	 * but probably only if we're running fairly new firmware (we'll
4210 	 * let the old f/w choke on an extended command queue entry).
4211 	 */
4212 
4213 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4214 		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4215 		XS_SETERR(xs, HBA_BOTCH);
4216 		return (CMD_COMPLETE);
4217 	}
4218 
4219 	/*
4220 	 * Translate the target to device handle as appropriate, checking
4221 	 * for correct device state as well.
4222 	 */
4223 	target = XS_TGT(xs);
4224 	if (IS_FC(isp)) {
4225 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4226 
4227 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4228 			XS_SETERR(xs, HBA_SELTIMEOUT);
4229 			return (CMD_COMPLETE);
4230 		}
4231 
4232 		/*
4233 		 * Try again later.
4234 		 */
4235 		if (fcp->isp_fwstate != FW_READY || fcp->isp_loopstate != LOOP_READY) {
4236 			return (CMD_RQLATER);
4237 		}
4238 
4239 		if (XS_TGT(xs) >= MAX_FC_TARG) {
4240 			XS_SETERR(xs, HBA_SELTIMEOUT);
4241 			return (CMD_COMPLETE);
4242 		}
4243 
4244 		hdlidx = fcp->isp_dev_map[XS_TGT(xs)] - 1;
4245 		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d- hdlidx value %d", XS_TGT(xs), hdlidx);
4246 		if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4247 			XS_SETERR(xs, HBA_SELTIMEOUT);
4248 			return (CMD_COMPLETE);
4249 		}
4250 		if (fcp->portdb[hdlidx].state == FC_PORTDB_STATE_ZOMBIE) {
4251 			return (CMD_RQLATER);
4252 		}
4253 		if (fcp->portdb[hdlidx].state != FC_PORTDB_STATE_VALID) {
4254 			XS_SETERR(xs, HBA_SELTIMEOUT);
4255 			return (CMD_COMPLETE);
4256 		}
4257 		target = fcp->portdb[hdlidx].handle;
4258 		fcp->portdb[hdlidx].dirty = 1;
4259 	} else {
4260 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4261 		if ((sdp->role & ISP_ROLE_INITIATOR) == 0) {
4262 			XS_SETERR(xs, HBA_SELTIMEOUT);
4263 			return (CMD_COMPLETE);
4264 		}
4265 		if (sdp->update) {
4266 			isp_spi_update(isp, XS_CHANNEL(xs));
4267 		}
4268 	}
4269 
4270  start_again:
4271 
4272 	qep = isp_getrqentry(isp);
4273 	if (qep == NULL) {
4274 		isp_prt(isp, ISP_LOGDEBUG0, "Request Queue Overflow");
4275 		XS_SETERR(xs, HBA_BOTCH);
4276 		return (CMD_EAGAIN);
4277 	}
4278 	XS_SETERR(xs, HBA_NOERROR);
4279 
4280 	/*
4281 	 * Now see if we need to synchronize the ISP with respect to anything.
4282 	 * We do dual duty here (cough) for synchronizing for busses other
4283 	 * than which we got here to send a command to.
4284 	 */
4285 	reqp = (ispreq_t *) local;
4286 	ISP_MEMZERO(local, QENTRY_LEN);
4287 	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4288 		if (IS_24XX(isp)) {
4289 			isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4290 			m->mrk_header.rqs_entry_count = 1;
4291 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4292 			m->mrk_modifier = SYNC_ALL;
4293 			isp_put_marker_24xx(isp, m, qep);
4294 		} else {
4295 			isp_marker_t *m = (isp_marker_t *) reqp;
4296 			m->mrk_header.rqs_entry_count = 1;
4297 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4298 			m->mrk_target = (XS_CHANNEL(xs) << 7);	/* bus # */
4299 			m->mrk_modifier = SYNC_ALL;
4300 			isp_put_marker(isp, m, qep);
4301 		}
4302 		ISP_SYNC_REQUEST(isp);
4303 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4304 		goto start_again;
4305 	}
4306 
4307 	reqp->req_header.rqs_entry_count = 1;
4308 	if (IS_24XX(isp)) {
4309 		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4310 	} else if (IS_FC(isp)) {
4311 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4312 	} else {
4313 		if (XS_CDBLEN(xs) > 12) {
4314 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4315 		} else {
4316 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4317 		}
4318 	}
4319 
4320 	if (IS_24XX(isp)) {
4321 		int ttype;
4322 		if (XS_TAG_P(xs)) {
4323 			ttype = XS_TAG_TYPE(xs);
4324 		} else {
4325 			if (XS_CDBP(xs)[0] == 0x3) {
4326 				ttype = REQFLAG_HTAG;
4327 			} else {
4328 				ttype = REQFLAG_STAG;
4329 			}
4330 		}
4331 		if (ttype == REQFLAG_OTAG) {
4332 			ttype = FCP_CMND_TASK_ATTR_ORDERED;
4333 		} else if (ttype == REQFLAG_HTAG) {
4334 			ttype = FCP_CMND_TASK_ATTR_HEAD;
4335 		} else {
4336 			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4337 		}
4338 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4339 	} else if (IS_FC(isp)) {
4340 		/*
4341 		 * See comment in isp_intr
4342 		 */
4343 		/* XS_SET_RESID(xs, 0); */
4344 
4345 		/*
4346 		 * Fibre Channel always requires some kind of tag.
4347 		 * The Qlogic drivers seem be happy not to use a tag,
4348 		 * but this breaks for some devices (IBM drives).
4349 		 */
4350 		if (XS_TAG_P(xs)) {
4351 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4352 		} else {
4353 			/*
4354 			 * If we don't know what tag to use, use HEAD OF QUEUE
4355 			 * for Request Sense or Simple.
4356 			 */
4357 			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
4358 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4359 			else
4360 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4361 		}
4362 	} else {
4363 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4364 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4365 			reqp->req_flags = XS_TAG_TYPE(xs);
4366 		}
4367 	}
4368 
4369 	tptr = &reqp->req_time;
4370 
4371 	/*
4372 	 * NB: we do not support long CDBs
4373 	 */
4374 	cdblen = XS_CDBLEN(xs);
4375 
4376 	if (IS_SCSI(isp)) {
4377 		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4378 		reqp->req_lun_trn = XS_LUN(xs);
4379 		cdblen = ISP_MIN(cdblen, sizeof (reqp->req_cdb));
4380 		cdbp = reqp->req_cdb;
4381 		reqp->req_cdblen = cdblen;
4382 	} else if (IS_24XX(isp)) {
4383 		ispreqt7_t *t7 = (ispreqt7_t *)local;
4384 		fcportdb_t *lp;
4385 
4386 		lp = &FCPARAM(isp, XS_CHANNEL(xs))->portdb[hdlidx];
4387 		t7->req_nphdl = target;
4388 		t7->req_tidlo = lp->portid;
4389 		t7->req_tidhi = lp->portid >> 16;
4390 		t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4391 		if (XS_LUN(xs) > 256) {
4392 			t7->req_lun[0] = XS_LUN(xs) >> 8;
4393 			t7->req_lun[0] |= 0x40;
4394 		}
4395 		t7->req_lun[1] = XS_LUN(xs);
4396 		tptr = &t7->req_time;
4397 		cdbp = t7->req_cdb;
4398 		cdblen = ISP_MIN(cdblen, sizeof (t7->req_cdb));
4399 	} else if (ISP_CAP_2KLOGIN(isp)) {
4400 		ispreqt2e_t *t2e = (ispreqt2e_t *)local;
4401 		t2e->req_target = target;
4402 		t2e->req_scclun = XS_LUN(xs);
4403 		cdbp = t2e->req_cdb;
4404 		cdblen = ISP_MIN(cdblen, sizeof (t2e->req_cdb));
4405 	} else if (ISP_CAP_SCCFW(isp)) {
4406 		ispreqt2_t *t2 = (ispreqt2_t *)local;
4407 		t2->req_target = target;
4408 		t2->req_scclun = XS_LUN(xs);
4409 		cdbp = t2->req_cdb;
4410 		cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
4411 	} else {
4412 		ispreqt2_t *t2 = (ispreqt2_t *)local;
4413 		t2->req_target = target;
4414 		t2->req_lun_trn = XS_LUN(xs);
4415 		cdbp = t2->req_cdb;
4416 		cdblen = ISP_MIN(cdblen, sizeof (t2->req_cdb));
4417 	}
4418 	ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
4419 
4420 	*tptr = XS_TIME(xs) / 1000;
4421 	if (*tptr == 0 && XS_TIME(xs)) {
4422 		*tptr = 1;
4423 	}
4424 	if (IS_24XX(isp) && *tptr > 0x1999) {
4425 		*tptr = 0x1999;
4426 	}
4427 
4428 	if (isp_allocate_xs(isp, xs, &handle)) {
4429 		isp_prt(isp, ISP_LOGDEBUG0, "out of xflist pointers");
4430 		XS_SETERR(xs, HBA_BOTCH);
4431 		return (CMD_EAGAIN);
4432 	}
4433 	/* Whew. Thankfully the same for type 7 requests */
4434 	reqp->req_handle = handle;
4435 
4436 	/*
4437 	 * Set up DMA and/or do any platform dependent swizzling of the request entry
4438 	 * so that the Qlogic F/W understands what is being asked of it.
4439 	 *
4440 	 * The callee is responsible for adding all requests at this point.
4441 	 */
4442 	dmaresult = ISP_DMASETUP(isp, xs, reqp);
4443 	if (dmaresult != CMD_QUEUED) {
4444 		isp_destroy_handle(isp, handle);
4445 		/*
4446 		 * dmasetup sets actual error in packet, and
4447 		 * return what we were given to return.
4448 		 */
4449 		return (dmaresult);
4450 	}
4451 	isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4452 	isp->isp_nactive++;
4453 	return (CMD_QUEUED);
4454 }
4455 
4456 /*
4457  * isp control
4458  * Locks (ints blocked) assumed held.
4459  */
4460 
4461 int
4462 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4463 {
4464 	XS_T *xs;
4465 	mbreg_t *mbr, mbs;
4466 	int chan, tgt;
4467 	uint32_t handle;
4468 	va_list ap;
4469 
4470 	switch (ctl) {
4471 	case ISPCTL_RESET_BUS:
4472 		/*
4473 		 * Issue a bus reset.
4474 		 */
4475 		if (IS_24XX(isp)) {
4476 			isp_prt(isp, ISP_LOGWARN, "RESET BUS NOT IMPLEMENTED");
4477 			break;
4478 		} else if (IS_FC(isp)) {
4479 			mbs.param[1] = 10;
4480 			chan = 0;
4481 		} else {
4482 			va_start(ap, ctl);
4483 			chan = va_arg(ap, int);
4484 			va_end(ap);
4485 			mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4486 			if (mbs.param[1] < 2) {
4487 				mbs.param[1] = 2;
4488 			}
4489 			mbs.param[2] = chan;
4490 		}
4491 		MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4492 		ISP_SET_SENDMARKER(isp, chan, 1);
4493 		isp_mboxcmd(isp, &mbs);
4494 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4495 			break;
4496 		}
4497 		isp_prt(isp, ISP_LOGINFO,
4498 		    "driver initiated bus reset of bus %d", chan);
4499 		return (0);
4500 
4501 	case ISPCTL_RESET_DEV:
4502 		va_start(ap, ctl);
4503 		chan = va_arg(ap, int);
4504 		tgt = va_arg(ap, int);
4505 		va_end(ap);
4506 		if (IS_24XX(isp)) {
4507 			uint8_t local[QENTRY_LEN];
4508 			isp24xx_tmf_t *tmf;
4509 			isp24xx_statusreq_t *sp;
4510 			fcparam *fcp = FCPARAM(isp, chan);
4511 			fcportdb_t *lp;
4512 			int hdlidx;
4513 
4514 			hdlidx = fcp->isp_dev_map[tgt] - 1;
4515 			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4516 				isp_prt(isp, ISP_LOGWARN,
4517 				    "Chan %d bad handle %d trying to reset"
4518 				    "target %d", chan, hdlidx, tgt);
4519 				break;
4520 			}
4521 			lp = &fcp->portdb[hdlidx];
4522 			if (lp->state != FC_PORTDB_STATE_VALID) {
4523 				isp_prt(isp, ISP_LOGWARN,
4524 				    "Chan %d handle %d for abort of target %d "
4525 				    "no longer valid", chan,
4526 				    hdlidx, tgt);
4527 				break;
4528 			}
4529 
4530 			tmf = (isp24xx_tmf_t *) local;
4531 			ISP_MEMZERO(tmf, QENTRY_LEN);
4532 			tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4533 			tmf->tmf_header.rqs_entry_count = 1;
4534 			tmf->tmf_nphdl = lp->handle;
4535 			tmf->tmf_delay = 2;
4536 			tmf->tmf_timeout = 2;
4537 			tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4538 			tmf->tmf_tidlo = lp->portid;
4539 			tmf->tmf_tidhi = lp->portid >> 16;
4540 			tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4541 			isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4542 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4543 			mbs.param[1] = QENTRY_LEN;
4544 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4545 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4546 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4547 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4548 
4549 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4550 				isp_prt(isp, ISP_LOGERR, sacq);
4551 				break;
4552 			}
4553 			isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4554 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
4555 			fcp->sendmarker = 1;
4556 			isp_mboxcmd(isp, &mbs);
4557 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4558 				FC_SCRATCH_RELEASE(isp, chan);
4559 				break;
4560 			}
4561 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4562 			    QENTRY_LEN, chan);
4563 			sp = (isp24xx_statusreq_t *) local;
4564 			isp_get_24xx_response(isp,
4565 			    &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4566 			FC_SCRATCH_RELEASE(isp, chan);
4567 			if (sp->req_completion_status == 0) {
4568 				return (0);
4569 			}
4570 			isp_prt(isp, ISP_LOGWARN,
4571 			    "Chan %d reset of target %d returned 0x%x",
4572 			    chan, tgt, sp->req_completion_status);
4573 			break;
4574 		} else if (IS_FC(isp)) {
4575 			if (ISP_CAP_2KLOGIN(isp)) {
4576 				mbs.param[1] = tgt;
4577 				mbs.ibits = (1 << 10);
4578 			} else {
4579 				mbs.param[1] = (tgt << 8);
4580 			}
4581 		} else {
4582 			mbs.param[1] = (chan << 15) | (tgt << 8);
4583 		}
4584 		MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4585 		mbs.param[2] = 3;	/* 'delay', in seconds */
4586 		isp_mboxcmd(isp, &mbs);
4587 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4588 			break;
4589 		}
4590 		isp_prt(isp, ISP_LOGINFO,
4591 		    "Target %d on Bus %d Reset Succeeded", tgt, chan);
4592 		ISP_SET_SENDMARKER(isp, chan, 1);
4593 		return (0);
4594 
4595 	case ISPCTL_ABORT_CMD:
4596 		va_start(ap, ctl);
4597 		xs = va_arg(ap, XS_T *);
4598 		va_end(ap);
4599 
4600 		tgt = XS_TGT(xs);
4601 		chan = XS_CHANNEL(xs);
4602 
4603 		handle = isp_find_handle(isp, xs);
4604 		if (handle == 0) {
4605 			isp_prt(isp, ISP_LOGWARN,
4606 			    "cannot find handle for command to abort");
4607 			break;
4608 		}
4609 		if (IS_24XX(isp)) {
4610 			isp24xx_abrt_t local, *ab = &local, *ab2;
4611 			fcparam *fcp;
4612 			fcportdb_t *lp;
4613 			int hdlidx;
4614 
4615 			fcp = FCPARAM(isp, chan);
4616 			hdlidx = fcp->isp_dev_map[tgt] - 1;
4617 			if (hdlidx < 0 || hdlidx >= MAX_FC_TARG) {
4618 				isp_prt(isp, ISP_LOGWARN,
4619 				    "Chan %d bad handle %d trying to abort"
4620 				    "target %d", chan, hdlidx, tgt);
4621 				break;
4622 			}
4623 			lp = &fcp->portdb[hdlidx];
4624 			if (lp->state != FC_PORTDB_STATE_VALID) {
4625 				isp_prt(isp, ISP_LOGWARN,
4626 				    "Chan %d handle %d for abort of target %d "
4627 				    "no longer valid", chan, hdlidx, tgt);
4628 				break;
4629 			}
4630 			isp_prt(isp, ISP_LOGALL,
4631 			    "Chan %d Abort Cmd for N-Port 0x%04x @ Port "
4632 			    "0x%06x %p", chan, lp->handle, lp->portid, xs);
4633 			ISP_MEMZERO(ab, QENTRY_LEN);
4634 			ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4635 			ab->abrt_header.rqs_entry_count = 1;
4636 			ab->abrt_handle = lp->handle;
4637 			ab->abrt_cmd_handle = handle;
4638 			ab->abrt_tidlo = lp->portid;
4639 			ab->abrt_tidhi = lp->portid >> 16;
4640 			ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4641 
4642 			ISP_MEMZERO(&mbs, sizeof (mbs));
4643 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4644 			mbs.param[1] = QENTRY_LEN;
4645 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4646 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4647 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4648 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4649 
4650 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4651 				isp_prt(isp, ISP_LOGERR, sacq);
4652 				break;
4653 			}
4654 			isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4655 			ab2 = (isp24xx_abrt_t *)
4656 			    &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4657 			ab2->abrt_nphdl = 0xdeaf;
4658 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
4659 			isp_mboxcmd(isp, &mbs);
4660 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4661 				FC_SCRATCH_RELEASE(isp, chan);
4662 				break;
4663 			}
4664 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN,
4665 			    QENTRY_LEN, chan);
4666 			isp_get_24xx_abrt(isp, ab2, ab);
4667 			FC_SCRATCH_RELEASE(isp, chan);
4668 			if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4669 				return (0);
4670 			}
4671 			isp_prt(isp, ISP_LOGWARN,
4672 			    "Chan %d handle %d abort returned 0x%x", chan,
4673 			    hdlidx, ab->abrt_nphdl);
4674 			break;
4675 		} else if (IS_FC(isp)) {
4676 			if (ISP_CAP_SCCFW(isp)) {
4677 				if (ISP_CAP_2KLOGIN(isp)) {
4678 					mbs.param[1] = tgt;
4679 				} else {
4680 					mbs.param[1] = tgt << 8;
4681 				}
4682 				mbs.param[6] = XS_LUN(xs);
4683 			} else {
4684 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
4685 			}
4686 		} else {
4687 			mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4688 		}
4689 		MBSINIT(&mbs, MBOX_ABORT, MBLOGALL & ~MBOX_COMMAND_ERROR, 0);
4690 		mbs.param[2] = handle;
4691 		isp_mboxcmd(isp, &mbs);
4692 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4693 			break;
4694 		}
4695 		return (0);
4696 
4697 	case ISPCTL_UPDATE_PARAMS:
4698 
4699 		va_start(ap, ctl);
4700 		chan = va_arg(ap, int);
4701 		va_end(ap);
4702 		isp_spi_update(isp, chan);
4703 		return (0);
4704 
4705 	case ISPCTL_FCLINK_TEST:
4706 
4707 		if (IS_FC(isp)) {
4708 			int usdelay;
4709 			va_start(ap, ctl);
4710 			chan = va_arg(ap, int);
4711 			usdelay = va_arg(ap, int);
4712 			va_end(ap);
4713 			if (usdelay == 0) {
4714 				usdelay =  250000;
4715 			}
4716 			return (isp_fclink_test(isp, chan, usdelay));
4717 		}
4718 		break;
4719 
4720 	case ISPCTL_SCAN_FABRIC:
4721 
4722 		if (IS_FC(isp)) {
4723 			va_start(ap, ctl);
4724 			chan = va_arg(ap, int);
4725 			va_end(ap);
4726 			return (isp_scan_fabric(isp, chan));
4727 		}
4728 		break;
4729 
4730 	case ISPCTL_SCAN_LOOP:
4731 
4732 		if (IS_FC(isp)) {
4733 			va_start(ap, ctl);
4734 			chan = va_arg(ap, int);
4735 			va_end(ap);
4736 			return (isp_scan_loop(isp, chan));
4737 		}
4738 		break;
4739 
4740 	case ISPCTL_PDB_SYNC:
4741 
4742 		if (IS_FC(isp)) {
4743 			va_start(ap, ctl);
4744 			chan = va_arg(ap, int);
4745 			va_end(ap);
4746 			return (isp_pdb_sync(isp, chan));
4747 		}
4748 		break;
4749 
4750 	case ISPCTL_SEND_LIP:
4751 
4752 		if (IS_FC(isp) && !IS_24XX(isp)) {
4753 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4754 			if (ISP_CAP_2KLOGIN(isp)) {
4755 				mbs.ibits = (1 << 10);
4756 			}
4757 			isp_mboxcmd(isp, &mbs);
4758 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4759 				return (0);
4760 			}
4761 		}
4762 		break;
4763 
4764 	case ISPCTL_GET_PDB:
4765 		if (IS_FC(isp)) {
4766 			isp_pdb_t *pdb;
4767 			va_start(ap, ctl);
4768 			chan = va_arg(ap, int);
4769 			tgt = va_arg(ap, int);
4770 			pdb = va_arg(ap, isp_pdb_t *);
4771 			va_end(ap);
4772 			return (isp_getpdb(isp, chan, tgt, pdb, 1));
4773 		}
4774 		break;
4775 
4776 	case ISPCTL_GET_NAMES:
4777 	{
4778 		uint64_t *wwnn, *wwnp;
4779 		va_start(ap, ctl);
4780 		chan = va_arg(ap, int);
4781 		tgt = va_arg(ap, int);
4782 		wwnn = va_arg(ap, uint64_t *);
4783 		wwnp = va_arg(ap, uint64_t *);
4784 		va_end(ap);
4785 		if (wwnn == NULL && wwnp == NULL) {
4786 			break;
4787 		}
4788 		if (wwnn) {
4789 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
4790 			if (*wwnn == INI_NONE) {
4791 				break;
4792 			}
4793 		}
4794 		if (wwnp) {
4795 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
4796 			if (*wwnp == INI_NONE) {
4797 				break;
4798 			}
4799 		}
4800 		return (0);
4801 	}
4802 	case ISPCTL_RUN_MBOXCMD:
4803 	{
4804 		va_start(ap, ctl);
4805 		mbr = va_arg(ap, mbreg_t *);
4806 		va_end(ap);
4807 		isp_mboxcmd(isp, mbr);
4808 		return (0);
4809 	}
4810 	case ISPCTL_PLOGX:
4811 	{
4812 		isp_plcmd_t *p;
4813 		int r;
4814 
4815 		va_start(ap, ctl);
4816 		p = va_arg(ap, isp_plcmd_t *);
4817 		va_end(ap);
4818 
4819 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4820 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4821 		}
4822 		do {
4823 			p->handle = isp_nxt_handle(isp, p->channel, p->handle);
4824 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4825 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4826 				p->handle = r >> 16;
4827 				r = 0;
4828 				break;
4829 			}
4830 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4831 		return (r);
4832 	}
4833 	default:
4834 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4835 		break;
4836 
4837 	}
4838 	return (-1);
4839 }
4840 
4841 /*
4842  * Interrupt Service Routine(s).
4843  *
4844  * External (OS) framework has done the appropriate locking,
4845  * and the locking will be held throughout this function.
4846  */
4847 
4848 /*
4849  * Limit our stack depth by sticking with the max likely number
4850  * of completions on a request queue at any one time.
4851  */
4852 #ifndef	MAX_REQUESTQ_COMPLETIONS
4853 #define	MAX_REQUESTQ_COMPLETIONS	32
4854 #endif
4855 
4856 void
4857 isp_intr(ispsoftc_t *isp, uint32_t isr, uint16_t sema, uint16_t mbox)
4858 {
4859 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4860 	uint32_t iptr, optr, junk;
4861 	int i, nlooked = 0, ndone = 0;
4862 
4863 again:
4864 	optr = isp->isp_residx;
4865 	/*
4866 	 * Is this a mailbox related interrupt?
4867 	 * The mailbox semaphore will be nonzero if so.
4868 	 */
4869 	if (sema) {
4870  fmbox:
4871 		if (mbox & MBOX_COMMAND_COMPLETE) {
4872 			isp->isp_intmboxc++;
4873 			if (isp->isp_mboxbsy) {
4874 				int obits = isp->isp_obits;
4875 				isp->isp_mboxtmp[0] = mbox;
4876 				for (i = 1; i < MAX_MAILBOX(isp); i++) {
4877 					if ((obits & (1 << i)) == 0) {
4878 						continue;
4879 					}
4880 					isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4881 				}
4882 				if (isp->isp_mbxwrk0) {
4883 					if (isp_mbox_continue(isp) == 0) {
4884 						return;
4885 					}
4886 				}
4887 				MBOX_NOTIFY_COMPLETE(isp);
4888 			} else {
4889 				isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", mbox);
4890 			}
4891 		} else {
4892 			i = IS_FC(isp)? isp_parse_async_fc(isp, mbox) : isp_parse_async(isp, mbox);
4893 			if (i < 0) {
4894 				return;
4895 			}
4896 		}
4897 		if ((IS_FC(isp) && mbox != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
4898 			goto out;
4899 		}
4900 	}
4901 
4902 	/*
4903 	 * We can't be getting this now.
4904 	 */
4905 	if (isp->isp_state != ISP_RUNSTATE) {
4906 		/*
4907 		 * This seems to happen to 23XX and 24XX cards- don't know why.
4908 		 */
4909 		 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4910 			goto fmbox;
4911 		}
4912 		isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x) when not ready", isr, sema);
4913 		/*
4914 		 * Thank you very much!  *Burrrp*!
4915 		 */
4916 		ISP_WRITE(isp, isp->isp_respoutrp, ISP_READ(isp, isp->isp_respinrp));
4917 		if (IS_24XX(isp)) {
4918 			ISP_DISABLE_INTS(isp);
4919 		}
4920 		goto out;
4921 	}
4922 
4923 #ifdef	ISP_TARGET_MODE
4924 	/*
4925 	 * Check for ATIO Queue entries.
4926 	 */
4927 	if (IS_24XX(isp)) {
4928 		iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4929 		optr = ISP_READ(isp, BIU2400_ATIO_RSPOUTP);
4930 
4931 		while (optr != iptr) {
4932 			uint8_t qe[QENTRY_LEN];
4933 			isphdr_t *hp;
4934 			uint32_t oop;
4935 			void *addr;
4936 
4937 			oop = optr;
4938 			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
4939 			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4940 			isp_get_hdr(isp, addr, (isphdr_t *)qe);
4941 			hp = (isphdr_t *)qe;
4942 			switch (hp->rqs_entry_type) {
4943 			case RQSTYPE_NOTIFY:
4944 			case RQSTYPE_ATIO:
4945 				(void) isp_target_notify(isp, addr, &oop);
4946 				break;
4947 			default:
4948 				isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4949 				break;
4950 			}
4951 			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4952 			ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4953 		}
4954 		optr = isp->isp_residx;
4955 	}
4956 #endif
4957 
4958 	/*
4959 	 * Get the current Response Queue Out Pointer.
4960 	 *
4961 	 * If we're a 2300 or 2400, we can ask what hardware what it thinks.
4962 	 */
4963 	if (IS_23XX(isp) || IS_24XX(isp)) {
4964 		optr = ISP_READ(isp, isp->isp_respoutrp);
4965 		/*
4966 		 * Debug: to be taken out eventually
4967 		 */
4968 		if (isp->isp_residx != optr) {
4969 			isp_prt(isp, ISP_LOGINFO, "isp_intr: hard optr=%x, soft optr %x", optr, isp->isp_residx);
4970 			isp->isp_residx = optr;
4971 		}
4972 	} else {
4973 		optr = isp->isp_residx;
4974 	}
4975 
4976 	/*
4977 	 * You *must* read the Response Queue In Pointer
4978 	 * prior to clearing the RISC interrupt.
4979 	 *
4980 	 * Debounce the 2300 if revision less than 2.
4981 	 */
4982 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4983 		i = 0;
4984 		do {
4985 			iptr = ISP_READ(isp, isp->isp_respinrp);
4986 			junk = ISP_READ(isp, isp->isp_respinrp);
4987 		} while (junk != iptr && ++i < 1000);
4988 
4989 		if (iptr != junk) {
4990 			isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
4991 			goto out;
4992 		}
4993 	} else {
4994 		iptr = ISP_READ(isp, isp->isp_respinrp);
4995 	}
4996 	isp->isp_resodx = iptr;
4997 
4998 
4999 	if (optr == iptr && sema == 0) {
5000 		/*
5001 		 * There are a lot of these- reasons unknown- mostly on
5002 		 * faster Alpha machines.
5003 		 *
5004 		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
5005 		 * make sure the old interrupt went away (to avoid 'ringing'
5006 		 * effects), but that didn't stop this from occurring.
5007 		 */
5008 		if (IS_24XX(isp)) {
5009 			junk = 0;
5010 		} else if (IS_23XX(isp)) {
5011 			ISP_DELAY(100);
5012 			iptr = ISP_READ(isp, isp->isp_respinrp);
5013 			junk = ISP_READ(isp, BIU_R2HSTSLO);
5014 		} else {
5015 			junk = ISP_READ(isp, BIU_ISR);
5016 		}
5017 		if (optr == iptr) {
5018 			if (IS_23XX(isp) || IS_24XX(isp)) {
5019 				;
5020 			} else {
5021 				sema = ISP_READ(isp, BIU_SEMA);
5022 				mbox = ISP_READ(isp, OUTMAILBOX0);
5023 				if ((sema & 0x3) && (mbox & 0x8000)) {
5024 					goto again;
5025 				}
5026 			}
5027 			isp->isp_intbogus++;
5028 			isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
5029 		}
5030 	}
5031 	isp->isp_resodx = iptr;
5032 
5033 	while (optr != iptr) {
5034 		uint8_t qe[QENTRY_LEN];
5035 		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
5036 		isphdr_t *hp;
5037 		int buddaboom, etype, scsi_status, completion_status;
5038 		int req_status_flags, req_state_flags;
5039 		uint8_t *snsp, *resp;
5040 		uint32_t rlen, slen;
5041 		long resid;
5042 		uint16_t oop;
5043 
5044 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5045 		oop = optr;
5046 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5047 		nlooked++;
5048  read_again:
5049 		buddaboom = req_status_flags = req_state_flags = 0;
5050 		resid = 0L;
5051 
5052 		/*
5053 		 * Synchronize our view of this response queue entry.
5054 		 */
5055 		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
5056 		isp_get_hdr(isp, hp, &sp->req_header);
5057 		etype = sp->req_header.rqs_entry_type;
5058 
5059 		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5060 			isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5061 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5062 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5063 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5064 			}
5065 			scsi_status = sp2->req_scsi_status;
5066 			completion_status = sp2->req_completion_status;
5067 			req_state_flags = 0;
5068 			resid = sp2->req_resid;
5069 		} else if (etype == RQSTYPE_RESPONSE) {
5070 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5071 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5072 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5073 			}
5074 			scsi_status = sp->req_scsi_status;
5075 			completion_status = sp->req_completion_status;
5076 			req_status_flags = sp->req_status_flags;
5077 			req_state_flags = sp->req_state_flags;
5078 			resid = sp->req_resid;
5079 		} else if (etype == RQSTYPE_RIO1) {
5080 			isp_rio1_t *rio = (isp_rio1_t *) qe;
5081 			isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
5082 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5083 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5084 			}
5085 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5086 				isp_fastpost_complete(isp, rio->req_handles[i]);
5087 			}
5088 			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5089 				isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5090 			}
5091 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5092 			continue;
5093 		} else if (etype == RQSTYPE_RIO2) {
5094 			isp_prt(isp, ISP_LOGERR, "dropping RIO2 response\n");
5095 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5096 			continue;
5097 		} else {
5098 			/*
5099 			 * Somebody reachable via isp_handle_other_response
5100 			 * may have updated the response queue pointers for
5101 			 * us, so we reload our goal index.
5102 			 */
5103 			int r;
5104 			uint32_t tsto = oop;
5105 			r = isp_handle_other_response(isp, etype, hp, &tsto);
5106 			if (r < 0) {
5107 				goto read_again;
5108 			}
5109 			/*
5110 			 * If somebody updated the output pointer, then reset
5111 			 * optr to be one more than the updated amount.
5112 			 */
5113 			while (tsto != oop) {
5114 				optr = ISP_NXT_QENTRY(tsto,
5115 				    RESULT_QUEUE_LEN(isp));
5116 			}
5117 			if (r > 0) {
5118 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5119 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5120 				continue;
5121 			}
5122 
5123 			/*
5124 			 * After this point, we'll just look at the header as
5125 			 * we don't know how to deal with the rest of the
5126 			 * response.
5127 			 */
5128 
5129 			/*
5130 			 * It really has to be a bounced request just copied
5131 			 * from the request queue to the response queue. If
5132 			 * not, something bad has happened.
5133 			 */
5134 			if (etype != RQSTYPE_REQUEST) {
5135 				isp_prt(isp, ISP_LOGERR, notresp,
5136 				    etype, oop, optr, nlooked);
5137 				isp_print_bytes(isp,
5138 				    "Request Queue Entry", QENTRY_LEN, sp);
5139 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5140 				continue;
5141 			}
5142 			buddaboom = 1;
5143 			scsi_status = sp->req_scsi_status;
5144 			completion_status = sp->req_completion_status;
5145 			req_status_flags = sp->req_status_flags;
5146 			req_state_flags = sp->req_state_flags;
5147 			resid = sp->req_resid;
5148 		}
5149 
5150 		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5151 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5152 				isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5153 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5154 				continue;
5155 			}
5156 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5157 				isp_prt(isp, ISP_LOGDEBUG0, "internal queues full");
5158 				/*
5159 				 * We'll synthesize a QUEUE FULL message below.
5160 				 */
5161 			}
5162 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5163 				isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5164 				buddaboom++;
5165 			}
5166 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5167 				isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5168 				buddaboom++;
5169 			}
5170 			if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5171 				isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5172 				buddaboom++;
5173 			}
5174 			if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5175 				isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5176 				ISP_WRITE(isp, isp->isp_respoutrp, optr);
5177 				continue;
5178 			}
5179 		}
5180 
5181 		if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
5182 			isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
5183 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5184 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5185 			continue;
5186 		}
5187 		xs = isp_find_xs(isp, sp->req_handle);
5188 		if (xs == NULL) {
5189 			uint8_t ts = completion_status & 0xff;
5190 			/*
5191 			 * Only whine if this isn't the expected fallout of
5192 			 * aborting the command or resetting the target.
5193 			 */
5194 			if (etype != RQSTYPE_RESPONSE) {
5195 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5196 			} else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5197 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5198 			}
5199 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5200 			ISP_WRITE(isp, isp->isp_respoutrp, optr);
5201 			continue;
5202 		}
5203 		if (req_status_flags & RQSTF_BUS_RESET) {
5204 			XS_SETERR(xs, HBA_BUSRESET);
5205 			ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5206 		}
5207 		if (buddaboom) {
5208 			XS_SETERR(xs, HBA_BOTCH);
5209 		}
5210 
5211 		resp = NULL;
5212 		rlen = 0;
5213 		snsp = NULL;
5214 		slen = 0;
5215 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5216 			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5217 			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5218 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5219 			resp = sp->req_response;
5220 			rlen = sp->req_response_len;
5221 		}
5222 		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5223 			/*
5224 			 * Fibre Channel F/W doesn't say we got status
5225 			 * if there's Sense Data instead. I guess they
5226 			 * think it goes w/o saying.
5227 			 */
5228 			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5229 			if (IS_24XX(isp)) {
5230 				snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5231 				snsp += rlen;
5232 				slen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5233 			} else {
5234 				snsp = sp->req_sense_data;
5235 				slen = sp->req_sense_len;
5236 			}
5237 		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5238 			snsp = sp->req_sense_data;
5239 			slen = sp->req_sense_len;
5240 		}
5241 		if (req_state_flags & RQSF_GOT_STATUS) {
5242 			*XS_STSP(xs) = scsi_status & 0xff;
5243 		}
5244 
5245 		switch (etype) {
5246 		case RQSTYPE_RESPONSE:
5247 			if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5248 				const char *ptr;
5249 				char lb[64];
5250 				const char *rnames[6] = {
5251 					"Task Management Function Done",
5252 					"Data Length Differs From Burst Length",
5253 					"Invalid FCP Cmnd",
5254 					"FCP DATA RO mismatch with FCP DATA_XFR_RDY RO",
5255 					"Task Management Function Rejected",
5256 					"Task Management Function Failed",
5257 				};
5258 				if (resp[FCP_RSPNS_CODE_OFFSET] > 5) {
5259 					ISP_SNPRINTF(lb, sizeof lb, "Unknown FCP Response Code 0x%x", resp[FCP_RSPNS_CODE_OFFSET]);
5260 					ptr = lb;
5261 				} else {
5262 					ptr = rnames[resp[FCP_RSPNS_CODE_OFFSET]];
5263 				}
5264 				isp_xs_prt(isp, xs, ISP_LOGWARN, "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x", rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5265 				if (resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5266 					XS_SETERR(xs, HBA_BOTCH);
5267 				}
5268 			}
5269 			if (IS_24XX(isp)) {
5270 				isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5271 			} else {
5272 				isp_parse_status(isp, (void *)sp, xs, &resid);
5273 			}
5274 			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5275 				XS_SETERR(xs, HBA_TGTBSY);
5276 			}
5277 			if (IS_SCSI(isp)) {
5278 				XS_SET_RESID(xs, resid);
5279 				/*
5280 				 * A new synchronous rate was negotiated for
5281 				 * this target. Mark state such that we'll go
5282 				 * look up that which has changed later.
5283 				 */
5284 				if (req_status_flags & RQSTF_NEGOTIATION) {
5285 					int t = XS_TGT(xs);
5286 					sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5287 					sdp->isp_devparam[t].dev_refresh = 1;
5288 					sdp->update = 1;
5289 				}
5290 			} else {
5291 				if (req_status_flags & RQSF_XFER_COMPLETE) {
5292 					XS_SET_RESID(xs, 0);
5293 				} else if (scsi_status & RQCS_RESID) {
5294 					XS_SET_RESID(xs, resid);
5295 				} else {
5296 					XS_SET_RESID(xs, 0);
5297 				}
5298 			}
5299 			if (snsp && slen) {
5300 				XS_SAVE_SENSE(xs, snsp, slen);
5301 			} else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5302 				isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5303 				isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5304 			}
5305 			isp_prt(isp, ISP_LOGDEBUG2, "asked for %ld got raw resid %ld settled for %ld", (long) XS_XFRLEN(xs), resid, (long) XS_GET_RESID(xs));
5306 			break;
5307 		case RQSTYPE_REQUEST:
5308 		case RQSTYPE_A64:
5309 		case RQSTYPE_T2RQS:
5310 		case RQSTYPE_T3RQS:
5311 		case RQSTYPE_T7RQS:
5312 			if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5313 				/*
5314 				 * Force Queue Full status.
5315 				 */
5316 				*XS_STSP(xs) = SCSI_QFULL;
5317 				XS_SETERR(xs, HBA_NOERROR);
5318 			} else if (XS_NOERR(xs)) {
5319 				XS_SETERR(xs, HBA_BOTCH);
5320 			}
5321 			XS_SET_RESID(xs, XS_XFRLEN(xs));
5322 			break;
5323 		default:
5324 			isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5325 			if (XS_NOERR(xs)) {
5326 				XS_SETERR(xs, HBA_BOTCH);
5327 			}
5328 			break;
5329 		}
5330 
5331 		/*
5332 		 * Free any DMA resources. As a side effect, this may
5333 		 * also do any cache flushing necessary for data coherence.
5334 		 */
5335 		if (XS_XFRLEN(xs)) {
5336 			ISP_DMAFREE(isp, xs, sp->req_handle);
5337 		}
5338 		isp_destroy_handle(isp, sp->req_handle);
5339 
5340 		if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5341 		    ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
5342 			isp_prt_endcmd(isp, xs);
5343 		}
5344 		if (isp->isp_nactive > 0) {
5345 		    isp->isp_nactive--;
5346 		}
5347 		complist[ndone++] = xs;	/* defer completion call until later */
5348 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5349 		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5350 			break;
5351 		}
5352 	}
5353 
5354 	/*
5355 	 * If we looked at any commands, then it's valid to find out
5356 	 * what the outpointer is. It also is a trigger to update the
5357 	 * ISP's notion of what we've seen so far.
5358 	 */
5359 	if (nlooked) {
5360 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
5361 		/*
5362 		 * While we're at it, read the requst queue out pointer.
5363 		 */
5364 		isp->isp_reqodx = ISP_READ(isp, isp->isp_rqstoutrp);
5365 		if (isp->isp_rscchiwater < ndone) {
5366 			isp->isp_rscchiwater = ndone;
5367 		}
5368 	}
5369 
5370 out:
5371 
5372 	if (IS_24XX(isp)) {
5373 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5374 	} else {
5375 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5376 		ISP_WRITE(isp, BIU_SEMA, 0);
5377 	}
5378 
5379 	isp->isp_residx = optr;
5380 	for (i = 0; i < ndone; i++) {
5381 		xs = complist[i];
5382 		if (xs) {
5383 			isp->isp_rsltccmplt++;
5384 			isp_done(xs);
5385 		}
5386 	}
5387 }
5388 
5389 /*
5390  * Support routines.
5391  */
5392 
5393 void
5394 isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
5395 {
5396 	char cdbstr[16 * 5 + 1];
5397 	int i, lim;
5398 
5399 	lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
5400 	ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
5401 	for (i = 1; i < lim; i++) {
5402 		ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
5403 	}
5404 	if (XS_SENSE_VALID(xs)) {
5405 		isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s KEY/ASC/ASCQ=0x%02x/0x%02x/0x%02x",
5406 		    XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, XS_SNSKEY(xs), XS_SNSASC(xs), XS_SNSASCQ(xs));
5407 	} else {
5408 		isp_xs_prt(isp, xs, ISP_LOGALL, "FIN dl%d resid %ld CDB=%s STS 0x%x XS_ERR=0x%x", XS_XFRLEN(xs), (long) XS_GET_RESID(xs), cdbstr, *XS_STSP(xs), XS_ERR(xs));
5409 	}
5410 }
5411 
5412 /*
5413  * Parse an ASYNC mailbox complete
5414  *
5415  * Return non-zero if the event has been acknowledged.
5416  */
5417 static int
5418 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5419 {
5420 	int acked = 0;
5421 	uint32_t h1 = 0, h2 = 0;
5422 	uint16_t chan = 0;
5423 
5424 	/*
5425 	 * Pick up the channel, but not if this is a ASYNC_RIO32_2,
5426 	 * where Mailboxes 6/7 have the second handle.
5427 	 */
5428 	if (mbox != ASYNC_RIO32_2) {
5429 		if (IS_DUALBUS(isp)) {
5430 			chan = ISP_READ(isp, OUTMAILBOX6);
5431 		}
5432 	}
5433 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5434 
5435 	switch (mbox) {
5436 	case ASYNC_BUS_RESET:
5437 		ISP_SET_SENDMARKER(isp, chan, 1);
5438 #ifdef	ISP_TARGET_MODE
5439 		if (isp_target_async(isp, chan, mbox)) {
5440 			acked = 1;
5441 		}
5442 #endif
5443 		isp_async(isp, ISPASYNC_BUS_RESET, chan);
5444 		break;
5445 	case ASYNC_SYSTEM_ERROR:
5446 		isp->isp_dead = 1;
5447 		isp->isp_state = ISP_CRASHED;
5448 		/*
5449 		 * Were we waiting for a mailbox command to complete?
5450 		 * If so, it's dead, so wake up the waiter.
5451 		 */
5452 		if (isp->isp_mboxbsy) {
5453 			isp->isp_obits = 1;
5454 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5455 			MBOX_NOTIFY_COMPLETE(isp);
5456 		}
5457 		/*
5458 		 * It's up to the handler for isp_async to reinit stuff and
5459 		 * restart the firmware
5460 		 */
5461 		isp_async(isp, ISPASYNC_FW_CRASH);
5462 		acked = 1;
5463 		break;
5464 
5465 	case ASYNC_RQS_XFER_ERR:
5466 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5467 		break;
5468 
5469 	case ASYNC_RSP_XFER_ERR:
5470 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5471 		break;
5472 
5473 	case ASYNC_QWAKEUP:
5474 		/*
5475 		 * We've just been notified that the Queue has woken up.
5476 		 * We don't need to be chatty about this- just unlatch things
5477 		 * and move on.
5478 		 */
5479 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5480 		break;
5481 
5482 	case ASYNC_TIMEOUT_RESET:
5483 		isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
5484 		ISP_SET_SENDMARKER(isp, chan, 1);
5485 #ifdef	ISP_TARGET_MODE
5486 		if (isp_target_async(isp, chan, mbox)) {
5487 			acked = 1;
5488 		}
5489 #endif
5490 		break;
5491 
5492 	case ASYNC_DEVICE_RESET:
5493 		isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5494 		ISP_SET_SENDMARKER(isp, chan, 1);
5495 #ifdef	ISP_TARGET_MODE
5496 		if (isp_target_async(isp, chan, mbox)) {
5497 			acked = 1;
5498 		}
5499 #endif
5500 		break;
5501 
5502 	case ASYNC_EXTMSG_UNDERRUN:
5503 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5504 		break;
5505 
5506 	case ASYNC_SCAM_INT:
5507 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5508 		break;
5509 
5510 	case ASYNC_HUNG_SCSI:
5511 		isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
5512 		/* XXX: Need to issue SCSI reset at this point */
5513 		break;
5514 
5515 	case ASYNC_KILLED_BUS:
5516 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5517 		break;
5518 
5519 	case ASYNC_BUS_TRANSIT:
5520 		mbox = ISP_READ(isp, OUTMAILBOX2);
5521 		switch (mbox & SXP_PINS_MODE_MASK) {
5522 		case SXP_PINS_LVD_MODE:
5523 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5524 			SDPARAM(isp, chan)->isp_diffmode = 0;
5525 			SDPARAM(isp, chan)->isp_ultramode = 0;
5526 			SDPARAM(isp, chan)->isp_lvdmode = 1;
5527 			break;
5528 		case SXP_PINS_HVD_MODE:
5529 			isp_prt(isp, ISP_LOGINFO,
5530 			    "Transition to Differential mode");
5531 			SDPARAM(isp, chan)->isp_diffmode = 1;
5532 			SDPARAM(isp, chan)->isp_ultramode = 0;
5533 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5534 			break;
5535 		case SXP_PINS_SE_MODE:
5536 			isp_prt(isp, ISP_LOGINFO,
5537 			    "Transition to Single Ended mode");
5538 			SDPARAM(isp, chan)->isp_diffmode = 0;
5539 			SDPARAM(isp, chan)->isp_ultramode = 1;
5540 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5541 			break;
5542 		default:
5543 			isp_prt(isp, ISP_LOGWARN,
5544 			    "Transition to Unknown Mode 0x%x", mbox);
5545 			break;
5546 		}
5547 		/*
5548 		 * XXX: Set up to renegotiate again!
5549 		 */
5550 		/* Can only be for a 1080... */
5551 		ISP_SET_SENDMARKER(isp, chan, 1);
5552 		break;
5553 
5554 	case ASYNC_CMD_CMPLT:
5555 	case ASYNC_RIO32_1:
5556 		if (!IS_ULTRA3(isp)) {
5557 			isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
5558 			break;
5559 		}
5560 		/* FALLTHROUGH */
5561 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5562 		break;
5563 
5564 	case ASYNC_RIO32_2:
5565 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5566 		h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
5567 		break;
5568 
5569 	case ASYNC_RIO16_5:
5570 	case ASYNC_RIO16_4:
5571 	case ASYNC_RIO16_3:
5572 	case ASYNC_RIO16_2:
5573 	case ASYNC_RIO16_1:
5574 		isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
5575 		break;
5576 	default:
5577 		isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
5578 		break;
5579 	}
5580 
5581 	if (h1 || h2) {
5582 		isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
5583 		isp_fastpost_complete(isp, h1);
5584 		if (h2) {
5585 			isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
5586 			isp_fastpost_complete(isp, h2);
5587 			if (isp->isp_fpcchiwater < 2) {
5588 				isp->isp_fpcchiwater = 2;
5589 			}
5590 		} else {
5591 			if (isp->isp_fpcchiwater < 1) {
5592 				isp->isp_fpcchiwater = 1;
5593 			}
5594 		}
5595 	} else {
5596 		isp->isp_intoasync++;
5597 	}
5598 	return (acked);
5599 }
5600 
5601 #define	GET_24XX_BUS(isp, chan, msg)										\
5602 	if (IS_24XX(isp)) {											\
5603 		chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;							\
5604 		if (chan >= isp->isp_nchan) {									\
5605 			isp_prt(isp, ISP_LOGERR, "bogus channel %u for %s at line %d",	chan, msg, __LINE__);	\
5606 			break;											\
5607 		}												\
5608 	}
5609 
5610 
5611 static int
5612 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
5613 {
5614 	int acked = 0;
5615 	uint16_t chan;
5616 
5617 	if (IS_DUALBUS(isp)) {
5618 		chan = ISP_READ(isp, OUTMAILBOX6);
5619 	} else {
5620 		chan = 0;
5621 	}
5622 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5623 
5624 	switch (mbox) {
5625 	case ASYNC_SYSTEM_ERROR:
5626 		isp->isp_dead = 1;
5627 		isp->isp_state = ISP_CRASHED;
5628 		FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5629 		FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5630 		/*
5631 		 * Were we waiting for a mailbox command to complete?
5632 		 * If so, it's dead, so wake up the waiter.
5633 		 */
5634 		if (isp->isp_mboxbsy) {
5635 			isp->isp_obits = 1;
5636 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5637 			MBOX_NOTIFY_COMPLETE(isp);
5638 		}
5639 		/*
5640 		 * It's up to the handler for isp_async to reinit stuff and
5641 		 * restart the firmware
5642 		 */
5643 		isp_async(isp, ISPASYNC_FW_CRASH);
5644 		acked = 1;
5645 		break;
5646 
5647 	case ASYNC_RQS_XFER_ERR:
5648 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5649 		break;
5650 
5651 	case ASYNC_RSP_XFER_ERR:
5652 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5653 		break;
5654 
5655 	case ASYNC_QWAKEUP:
5656 #ifdef	ISP_TARGET_MODE
5657 		if (IS_24XX(isp)) {
5658 			isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5659 			break;
5660 		}
5661 #endif
5662 		isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
5663 		break;
5664 
5665 	case ASYNC_CMD_CMPLT:
5666 		isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
5667 		if (isp->isp_fpcchiwater < 1) {
5668 			isp->isp_fpcchiwater = 1;
5669 		}
5670 		break;
5671 
5672 	case ASYNC_RIOZIO_STALL:
5673 		break;
5674 
5675 	case ASYNC_CTIO_DONE:
5676 #ifdef	ISP_TARGET_MODE
5677 		if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
5678 			acked = 1;
5679 		} else {
5680 			isp->isp_fphccmplt++;
5681 		}
5682 #else
5683 		isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
5684 #endif
5685 		break;
5686 	case ASYNC_LIP_ERROR:
5687 	case ASYNC_LIP_F8:
5688 	case ASYNC_LIP_OCCURRED:
5689 	case ASYNC_PTPMODE:
5690 		/*
5691 		 * These are broadcast events that have to be sent across
5692 		 * all active channels.
5693 		 */
5694 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5695 			fcparam *fcp = FCPARAM(isp, chan);
5696 			int topo = fcp->isp_topo;
5697 
5698 			if (fcp->role == ISP_ROLE_NONE) {
5699 				continue;
5700 			}
5701 
5702 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5703 			fcp->isp_loopstate = LOOP_LIP_RCVD;
5704 			ISP_SET_SENDMARKER(isp, chan, 1);
5705 			ISP_MARK_PORTDB(isp, chan, 1);
5706 			isp_async(isp, ISPASYNC_LIP, chan);
5707 #ifdef	ISP_TARGET_MODE
5708 			if (isp_target_async(isp, chan, mbox)) {
5709 				acked = 1;
5710 			}
5711 #endif
5712 			/*
5713 			 * We've had problems with data corruption occuring on
5714 			 * commands that complete (with no apparent error) after
5715 			 * we receive a LIP. This has been observed mostly on
5716 			 * Local Loop topologies. To be safe, let's just mark
5717 			 * all active initiator commands as dead.
5718 			 */
5719 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5720 				int i, j;
5721 				for (i = j = 0; i < isp->isp_maxcmds; i++) {
5722 					XS_T *xs;
5723 					isp_hdl_t *hdp;
5724 
5725 					hdp = &isp->isp_xflist[i];
5726 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5727 						continue;
5728 					}
5729 					xs = hdp->cmd;
5730 					if (XS_CHANNEL(xs) != chan) {
5731 						continue;
5732 					}
5733 					j++;
5734 					XS_SETERR(xs, HBA_BUSRESET);
5735 				}
5736 				if (j) {
5737 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5738 				}
5739 			}
5740 		}
5741 		break;
5742 
5743 	case ASYNC_LOOP_UP:
5744 		/*
5745 		 * This is a broadcast event that has to be sent across
5746 		 * all active channels.
5747 		 */
5748 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5749 			fcparam *fcp = FCPARAM(isp, chan);
5750 
5751 			if (fcp->role == ISP_ROLE_NONE) {
5752 				continue;
5753 			}
5754 
5755 			ISP_SET_SENDMARKER(isp, chan, 1);
5756 
5757 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5758 			fcp->isp_loopstate = LOOP_LIP_RCVD;
5759 			ISP_MARK_PORTDB(isp, chan, 1);
5760 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
5761 #ifdef	ISP_TARGET_MODE
5762 			if (isp_target_async(isp, chan, mbox)) {
5763 				acked = 1;
5764 			}
5765 #endif
5766 		}
5767 		break;
5768 
5769 	case ASYNC_LOOP_DOWN:
5770 		/*
5771 		 * This is a broadcast event that has to be sent across
5772 		 * all active channels.
5773 		 */
5774 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5775 			fcparam *fcp = FCPARAM(isp, chan);
5776 
5777 			if (fcp->role == ISP_ROLE_NONE) {
5778 				continue;
5779 			}
5780 
5781 			ISP_SET_SENDMARKER(isp, chan, 1);
5782 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5783 			fcp->isp_loopstate = LOOP_NIL;
5784 			ISP_MARK_PORTDB(isp, chan, 1);
5785 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5786 #ifdef	ISP_TARGET_MODE
5787 			if (isp_target_async(isp, chan, mbox)) {
5788 				acked = 1;
5789 			}
5790 #endif
5791 		}
5792 		break;
5793 
5794 	case ASYNC_LOOP_RESET:
5795 		/*
5796 		 * This is a broadcast event that has to be sent across
5797 		 * all active channels.
5798 		 */
5799 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5800 			fcparam *fcp = FCPARAM(isp, chan);
5801 
5802 			if (fcp->role == ISP_ROLE_NONE) {
5803 				continue;
5804 			}
5805 
5806 			ISP_SET_SENDMARKER(isp, chan, 1);
5807 			fcp->isp_fwstate = FW_CONFIG_WAIT;
5808 			fcp->isp_loopstate = LOOP_NIL;
5809 			ISP_MARK_PORTDB(isp, chan, 1);
5810 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5811 #ifdef	ISP_TARGET_MODE
5812 			if (isp_target_async(isp, chan, mbox)) {
5813 				acked = 1;
5814 			}
5815 #endif
5816 		}
5817 		break;
5818 
5819 	case ASYNC_PDB_CHANGED:
5820 	{
5821 		int nphdl, nlstate, reason;
5822 		/*
5823 		 * We *should* get a channel out of the 24XX, but we don't seem
5824 		 * to get more than a PDB CHANGED on channel 0, so turn it into
5825 		 * a broadcast event.
5826 		 */
5827 		if (IS_24XX(isp)) {
5828 			nphdl = ISP_READ(isp, OUTMAILBOX1);
5829 			nlstate = ISP_READ(isp, OUTMAILBOX2);
5830 			reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5831 		} else {
5832 			nphdl = NIL_HANDLE;
5833 			nlstate = reason = 0;
5834 		}
5835 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5836 			fcparam *fcp = FCPARAM(isp, chan);
5837 
5838 			if (fcp->role == ISP_ROLE_NONE) {
5839 				continue;
5840 			}
5841 			ISP_SET_SENDMARKER(isp, chan, 1);
5842 			fcp->isp_loopstate = LOOP_PDB_RCVD;
5843 			ISP_MARK_PORTDB(isp, chan, 1);
5844 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5845 		}
5846 		break;
5847 	}
5848 	case ASYNC_CHANGE_NOTIFY:
5849 	{
5850 		int lochan, hichan;
5851 
5852 		if (ISP_FW_NEWER_THAN(isp, 4, 0, 25) && ISP_CAP_MULTI_ID(isp)) {
5853 			GET_24XX_BUS(isp, chan, "ASYNC_CHANGE_NOTIFY");
5854 			lochan = chan;
5855 			hichan = chan + 1;
5856 		} else {
5857 			lochan = 0;
5858 			hichan = isp->isp_nchan;
5859 		}
5860 		for (chan = lochan; chan < hichan; chan++) {
5861 			fcparam *fcp = FCPARAM(isp, chan);
5862 
5863 			if (fcp->role == ISP_ROLE_NONE) {
5864 				continue;
5865 			}
5866 
5867 			if (fcp->isp_topo == TOPO_F_PORT) {
5868 				fcp->isp_loopstate = LOOP_LSCAN_DONE;
5869 			} else {
5870 				fcp->isp_loopstate = LOOP_PDB_RCVD;
5871 			}
5872 			ISP_MARK_PORTDB(isp, chan, 1);
5873 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_SNS);
5874 		}
5875 		break;
5876 	}
5877 
5878 	case ASYNC_CONNMODE:
5879 		/*
5880 		 * This only applies to 2100 amd 2200 cards
5881 		 */
5882 		if (!IS_2200(isp) && !IS_2100(isp)) {
5883 			isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
5884 			break;
5885 		}
5886 		chan = 0;
5887 		mbox = ISP_READ(isp, OUTMAILBOX1);
5888 		ISP_MARK_PORTDB(isp, chan, 1);
5889 		switch (mbox) {
5890 		case ISP_CONN_LOOP:
5891 			isp_prt(isp, ISP_LOGINFO,
5892 			    "Point-to-Point -> Loop mode");
5893 			break;
5894 		case ISP_CONN_PTP:
5895 			isp_prt(isp, ISP_LOGINFO,
5896 			    "Loop -> Point-to-Point mode");
5897 			break;
5898 		case ISP_CONN_BADLIP:
5899 			isp_prt(isp, ISP_LOGWARN,
5900 			    "Point-to-Point -> Loop mode (BAD LIP)");
5901 			break;
5902 		case ISP_CONN_FATAL:
5903 			isp->isp_dead = 1;
5904 			isp->isp_state = ISP_CRASHED;
5905 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5906 			isp_async(isp, ISPASYNC_FW_CRASH);
5907 			return (-1);
5908 		case ISP_CONN_LOOPBACK:
5909 			isp_prt(isp, ISP_LOGWARN,
5910 			    "Looped Back in Point-to-Point mode");
5911 			break;
5912 		default:
5913 			isp_prt(isp, ISP_LOGWARN,
5914 			    "Unknown connection mode (0x%x)", mbox);
5915 			break;
5916 		}
5917 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
5918 		FCPARAM(isp, chan)->sendmarker = 1;
5919 		FCPARAM(isp, chan)->isp_fwstate = FW_CONFIG_WAIT;
5920 		FCPARAM(isp, chan)->isp_loopstate = LOOP_LIP_RCVD;
5921 		break;
5922 
5923 	case ASYNC_RCV_ERR:
5924 		if (IS_24XX(isp)) {
5925 			isp_prt(isp, ISP_LOGWARN, "Receive Error");
5926 		} else {
5927 			isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
5928 		}
5929 		break;
5930 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5931 		if (IS_24XX(isp)) {
5932 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5933 			break;
5934 		} else if (IS_2200(isp)) {
5935 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5936 			break;
5937 		}
5938 		/* FALLTHROUGH */
5939 	default:
5940 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5941 		break;
5942 	}
5943 	if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
5944 		isp->isp_intoasync++;
5945 	}
5946 	return (acked);
5947 }
5948 
5949 /*
5950  * Handle other response entries. A pointer to the request queue output
5951  * index is here in case we want to eat several entries at once, although
5952  * this is not used currently.
5953  */
5954 
5955 static int
5956 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
5957 {
5958 	switch (type) {
5959 	case RQSTYPE_STATUS_CONT:
5960 		isp_prt(isp, ISP_LOGDEBUG0, "Ignored Continuation Response");
5961 		return (1);
5962 	case RQSTYPE_MARKER:
5963 		isp_prt(isp, ISP_LOGDEBUG0, "Marker Response");
5964 		return (1);
5965 	case RQSTYPE_ATIO:
5966 	case RQSTYPE_CTIO:
5967 	case RQSTYPE_ENABLE_LUN:
5968 	case RQSTYPE_MODIFY_LUN:
5969 	case RQSTYPE_NOTIFY:
5970 	case RQSTYPE_NOTIFY_ACK:
5971 	case RQSTYPE_CTIO1:
5972 	case RQSTYPE_ATIO2:
5973 	case RQSTYPE_CTIO2:
5974 	case RQSTYPE_CTIO3:
5975 	case RQSTYPE_CTIO7:
5976 	case RQSTYPE_ABTS_RCVD:
5977 	case RQSTYPE_ABTS_RSP:
5978 		isp->isp_rsltccmplt++;	/* count as a response completion */
5979 #ifdef	ISP_TARGET_MODE
5980 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
5981 			return (1);
5982 		}
5983 #endif
5984 		/* FALLTHROUGH */
5985 	case RQSTYPE_RPT_ID_ACQ:
5986 		if (IS_24XX(isp)) {
5987 			isp_ridacq_t rid;
5988 			isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
5989 			if (rid.ridacq_format == 0) {
5990 			}
5991 			return (1);
5992 		}
5993 		/* FALLTHROUGH */
5994 	case RQSTYPE_REQUEST:
5995 	default:
5996 		ISP_DELAY(100);
5997 		if (type != isp_get_response_type(isp, hp)) {
5998 			/*
5999 			 * This is questionable- we're just papering over
6000 			 * something we've seen on SMP linux in target
6001 			 * mode- we don't really know what's happening
6002 			 * here that causes us to think we've gotten
6003 			 * an entry, but that either the entry isn't
6004 			 * filled out yet or our CPU read data is stale.
6005 			 */
6006 			isp_prt(isp, ISP_LOGINFO,
6007 				"unstable type in response queue");
6008 			return (-1);
6009 		}
6010 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
6011 		    isp_get_response_type(isp, hp));
6012 		return (0);
6013 	}
6014 }
6015 
6016 static void
6017 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
6018 {
6019 	switch (sp->req_completion_status & 0xff) {
6020 	case RQCS_COMPLETE:
6021 		if (XS_NOERR(xs)) {
6022 			XS_SETERR(xs, HBA_NOERROR);
6023 		}
6024 		return;
6025 
6026 	case RQCS_INCOMPLETE:
6027 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6028 			isp_xs_prt(isp, xs, ISP_LOGDEBUG1, "Selection Timeout");
6029 			if (XS_NOERR(xs)) {
6030 				XS_SETERR(xs, HBA_SELTIMEOUT);
6031 				*rp = XS_XFRLEN(xs);
6032 			}
6033 			return;
6034 		}
6035 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
6036 		break;
6037 
6038 	case RQCS_DMA_ERROR:
6039 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
6040 		*rp = XS_XFRLEN(xs);
6041 		break;
6042 
6043 	case RQCS_TRANSPORT_ERROR:
6044 	{
6045 		char buf[172];
6046 		ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6047 		if (sp->req_state_flags & RQSF_GOT_BUS) {
6048 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6049 		}
6050 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
6051 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6052 		}
6053 		if (sp->req_state_flags & RQSF_SENT_CDB) {
6054 			ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6055 		}
6056 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
6057 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6058 		}
6059 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
6060 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6061 		}
6062 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
6063 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6064 		}
6065 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6066 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6067 		}
6068 		ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6069 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
6070 			ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6071 		}
6072 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6073 			ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6074 		}
6075 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6076 			ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6077 		}
6078 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
6079 			ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6080 		}
6081 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6082 			ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6083 		}
6084 		if (sp->req_status_flags & RQSTF_ABORTED) {
6085 			ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6086 		}
6087 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
6088 			ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6089 		}
6090 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6091 			ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6092 		}
6093 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
6094 		*rp = XS_XFRLEN(xs);
6095 		break;
6096 	}
6097 	case RQCS_RESET_OCCURRED:
6098 	{
6099 		int chan;
6100 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
6101 		for (chan = 0; chan < isp->isp_nchan; chan++) {
6102 			FCPARAM(isp, chan)->sendmarker = 1;
6103 		}
6104 		if (XS_NOERR(xs)) {
6105 			XS_SETERR(xs, HBA_BUSRESET);
6106 		}
6107 		*rp = XS_XFRLEN(xs);
6108 		return;
6109 	}
6110 	case RQCS_ABORTED:
6111 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6112 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6113 		if (XS_NOERR(xs)) {
6114 			XS_SETERR(xs, HBA_ABORTED);
6115 		}
6116 		return;
6117 
6118 	case RQCS_TIMEOUT:
6119 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
6120 		/*
6121 	 	 * XXX: Check to see if we logged out of the device.
6122 		 */
6123 		if (XS_NOERR(xs)) {
6124 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6125 		}
6126 		return;
6127 
6128 	case RQCS_DATA_OVERRUN:
6129 		XS_SET_RESID(xs, sp->req_resid);
6130 		isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
6131 		if (XS_NOERR(xs)) {
6132 			XS_SETERR(xs, HBA_DATAOVR);
6133 		}
6134 		return;
6135 
6136 	case RQCS_COMMAND_OVERRUN:
6137 		isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
6138 		break;
6139 
6140 	case RQCS_STATUS_OVERRUN:
6141 		isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
6142 		break;
6143 
6144 	case RQCS_BAD_MESSAGE:
6145 		isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
6146 		break;
6147 
6148 	case RQCS_NO_MESSAGE_OUT:
6149 		isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
6150 		break;
6151 
6152 	case RQCS_EXT_ID_FAILED:
6153 		isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
6154 		break;
6155 
6156 	case RQCS_IDE_MSG_FAILED:
6157 		isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
6158 		break;
6159 
6160 	case RQCS_ABORT_MSG_FAILED:
6161 		isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
6162 		break;
6163 
6164 	case RQCS_REJECT_MSG_FAILED:
6165 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
6166 		break;
6167 
6168 	case RQCS_NOP_MSG_FAILED:
6169 		isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
6170 		break;
6171 
6172 	case RQCS_PARITY_ERROR_MSG_FAILED:
6173 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
6174 		break;
6175 
6176 	case RQCS_DEVICE_RESET_MSG_FAILED:
6177 		isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
6178 		break;
6179 
6180 	case RQCS_ID_MSG_FAILED:
6181 		isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
6182 		break;
6183 
6184 	case RQCS_UNEXP_BUS_FREE:
6185 		isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
6186 		break;
6187 
6188 	case RQCS_DATA_UNDERRUN:
6189 	{
6190 		if (IS_FC(isp)) {
6191 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6192 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6193 				isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6194 				if (XS_NOERR(xs)) {
6195 					XS_SETERR(xs, HBA_BOTCH);
6196 				}
6197 				return;
6198 			}
6199 		}
6200 		XS_SET_RESID(xs, sp->req_resid);
6201 		if (XS_NOERR(xs)) {
6202 			XS_SETERR(xs, HBA_NOERROR);
6203 		}
6204 		return;
6205 	}
6206 
6207 	case RQCS_XACT_ERR1:
6208 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
6209 		break;
6210 
6211 	case RQCS_XACT_ERR2:
6212 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction to target routine %d", XS_LUN(xs));
6213 		break;
6214 
6215 	case RQCS_XACT_ERR3:
6216 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
6217 		break;
6218 
6219 	case RQCS_BAD_ENTRY:
6220 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6221 		break;
6222 
6223 	case RQCS_QUEUE_FULL:
6224 		isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "internal queues full status 0x%x", *XS_STSP(xs));
6225 
6226 		/*
6227 		 * If QFULL or some other status byte is set, then this
6228 		 * isn't an error, per se.
6229 		 *
6230 		 * Unfortunately, some QLogic f/w writers have, in
6231 		 * some cases, ommitted to *set* status to QFULL.
6232 		 *
6233 
6234 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6235 			XS_SETERR(xs, HBA_NOERROR);
6236 			return;
6237 		}
6238 
6239 		 *
6240 		 *
6241 		 */
6242 
6243 		*XS_STSP(xs) = SCSI_QFULL;
6244 		XS_SETERR(xs, HBA_NOERROR);
6245 		return;
6246 
6247 	case RQCS_PHASE_SKIPPED:
6248 		isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
6249 		break;
6250 
6251 	case RQCS_ARQS_FAILED:
6252 		isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
6253 		if (XS_NOERR(xs)) {
6254 			XS_SETERR(xs, HBA_ARQFAIL);
6255 		}
6256 		return;
6257 
6258 	case RQCS_WIDE_FAILED:
6259 		isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
6260 		if (IS_SCSI(isp)) {
6261 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6262 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6263 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6264 			sdp->update = 1;
6265 		}
6266 		if (XS_NOERR(xs)) {
6267 			XS_SETERR(xs, HBA_NOERROR);
6268 		}
6269 		return;
6270 
6271 	case RQCS_SYNCXFER_FAILED:
6272 		isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
6273 		if (IS_SCSI(isp)) {
6274 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6275 			sdp += XS_CHANNEL(xs);
6276 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6277 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6278 			sdp->update = 1;
6279 		}
6280 		break;
6281 
6282 	case RQCS_LVD_BUSERR:
6283 		isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
6284 		break;
6285 
6286 	case RQCS_PORT_UNAVAILABLE:
6287 		/*
6288 		 * No such port on the loop. Moral equivalent of SELTIMEO
6289 		 */
6290 	case RQCS_PORT_LOGGED_OUT:
6291 	{
6292 		const char *reason;
6293 		uint8_t sts = sp->req_completion_status & 0xff;
6294 
6295 		/*
6296 		 * It was there (maybe)- treat as a selection timeout.
6297 		 */
6298 		if (sts == RQCS_PORT_UNAVAILABLE) {
6299 			reason = "unavailable";
6300 		} else {
6301 			reason = "logout";
6302 		}
6303 
6304 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d",
6305 		    reason, XS_TGT(xs));
6306 
6307 		/*
6308 		 * If we're on a local loop, force a LIP (which is overkill)
6309 		 * to force a re-login of this unit. If we're on fabric,
6310 		 * then we'll have to log in again as a matter of course.
6311 		 */
6312 		if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6313 		    FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6314 			mbreg_t mbs;
6315 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6316 			if (ISP_CAP_2KLOGIN(isp)) {
6317 				mbs.ibits = (1 << 10);
6318 			}
6319 			isp_mboxcmd_qnw(isp, &mbs, 1);
6320 		}
6321 		if (XS_NOERR(xs)) {
6322 			XS_SETERR(xs, HBA_SELTIMEOUT);
6323 		}
6324 		return;
6325 	}
6326 	case RQCS_PORT_CHANGED:
6327 		isp_prt(isp, ISP_LOGWARN,
6328 		    "port changed for target %d", XS_TGT(xs));
6329 		if (XS_NOERR(xs)) {
6330 			XS_SETERR(xs, HBA_SELTIMEOUT);
6331 		}
6332 		return;
6333 
6334 	case RQCS_PORT_BUSY:
6335 		isp_prt(isp, ISP_LOGWARN,
6336 		    "port busy for target %d", XS_TGT(xs));
6337 		if (XS_NOERR(xs)) {
6338 			XS_SETERR(xs, HBA_TGTBSY);
6339 		}
6340 		return;
6341 
6342 	default:
6343 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x",
6344 		    sp->req_completion_status);
6345 		break;
6346 	}
6347 	if (XS_NOERR(xs)) {
6348 		XS_SETERR(xs, HBA_BOTCH);
6349 	}
6350 }
6351 
6352 static void
6353 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
6354 {
6355 	int ru_marked, sv_marked;
6356 	int chan = XS_CHANNEL(xs);
6357 
6358 	switch (sp->req_completion_status) {
6359 	case RQCS_COMPLETE:
6360 		if (XS_NOERR(xs)) {
6361 			XS_SETERR(xs, HBA_NOERROR);
6362 		}
6363 		return;
6364 
6365 	case RQCS_DMA_ERROR:
6366 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
6367 		break;
6368 
6369 	case RQCS_TRANSPORT_ERROR:
6370 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
6371 		break;
6372 
6373 	case RQCS_RESET_OCCURRED:
6374 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
6375 		FCPARAM(isp, chan)->sendmarker = 1;
6376 		if (XS_NOERR(xs)) {
6377 			XS_SETERR(xs, HBA_BUSRESET);
6378 		}
6379 		return;
6380 
6381 	case RQCS_ABORTED:
6382 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6383 		FCPARAM(isp, chan)->sendmarker = 1;
6384 		if (XS_NOERR(xs)) {
6385 			XS_SETERR(xs, HBA_ABORTED);
6386 		}
6387 		return;
6388 
6389 	case RQCS_TIMEOUT:
6390 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
6391 		if (XS_NOERR(xs)) {
6392 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6393 		}
6394 		return;
6395 
6396 	case RQCS_DATA_OVERRUN:
6397 		XS_SET_RESID(xs, sp->req_resid);
6398 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
6399 		if (XS_NOERR(xs)) {
6400 			XS_SETERR(xs, HBA_DATAOVR);
6401 		}
6402 		return;
6403 
6404 	case RQCS_24XX_DRE:	/* data reassembly error */
6405 		isp_prt(isp, ISP_LOGERR,
6406 		    "Chan %d data reassembly error for target %d",
6407 		    chan, XS_TGT(xs));
6408 		if (XS_NOERR(xs)) {
6409 			XS_SETERR(xs, HBA_ABORTED);
6410 		}
6411 		*rp = XS_XFRLEN(xs);
6412 		return;
6413 
6414 	case RQCS_24XX_TABORT:	/* aborted by target */
6415 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS",
6416 		    chan, XS_TGT(xs));
6417 		if (XS_NOERR(xs)) {
6418 			XS_SETERR(xs, HBA_ABORTED);
6419 		}
6420 		return;
6421 
6422 	case RQCS_DATA_UNDERRUN:
6423 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6424 		/*
6425 		 * We can get an underrun w/o things being marked
6426 		 * if we got a non-zero status.
6427 		 */
6428 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6429 		if ((ru_marked == 0 && sv_marked == 0) ||
6430 		    (sp->req_resid > XS_XFRLEN(xs))) {
6431 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6432 			if (XS_NOERR(xs)) {
6433 				XS_SETERR(xs, HBA_BOTCH);
6434 			}
6435 			return;
6436 		}
6437 		XS_SET_RESID(xs, sp->req_resid);
6438 		isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6439 		if (XS_NOERR(xs)) {
6440 			XS_SETERR(xs, HBA_NOERROR);
6441 		}
6442 		return;
6443 
6444 	case RQCS_PORT_UNAVAILABLE:
6445 		/*
6446 		 * No such port on the loop. Moral equivalent of SELTIMEO
6447 		 */
6448 	case RQCS_PORT_LOGGED_OUT:
6449 	{
6450 		const char *reason;
6451 		uint8_t sts = sp->req_completion_status & 0xff;
6452 
6453 		/*
6454 		 * It was there (maybe)- treat as a selection timeout.
6455 		 */
6456 		if (sts == RQCS_PORT_UNAVAILABLE) {
6457 			reason = "unavailable";
6458 		} else {
6459 			reason = "logout";
6460 		}
6461 
6462 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6463 		    chan, reason, XS_TGT(xs));
6464 
6465 		/*
6466 		 * There is no MBOX_INIT_LIP for the 24XX.
6467 		 */
6468 		if (XS_NOERR(xs)) {
6469 			XS_SETERR(xs, HBA_SELTIMEOUT);
6470 		}
6471 		return;
6472 	}
6473 	case RQCS_PORT_CHANGED:
6474 		isp_prt(isp, ISP_LOGWARN,
6475 		    "port changed for target %d chan %d", XS_TGT(xs), chan);
6476 		if (XS_NOERR(xs)) {
6477 			XS_SETERR(xs, HBA_SELTIMEOUT);
6478 		}
6479 		return;
6480 
6481 
6482 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6483 		isp_prt(isp, ISP_LOGWARN,
6484 		    "f/w resource unavailable for target %d chan %d",
6485 		    XS_TGT(xs), chan);
6486 		if (XS_NOERR(xs)) {
6487 			*XS_STSP(xs) = SCSI_BUSY;
6488 			XS_SETERR(xs, HBA_TGTBSY);
6489 		}
6490 		return;
6491 
6492 	case RQCS_24XX_TMO:	/* task management overrun */
6493 		isp_prt(isp, ISP_LOGWARN,
6494 		    "command for target %d overlapped task management for "
6495 		    "chan %d", XS_TGT(xs), chan);
6496 		if (XS_NOERR(xs)) {
6497 			*XS_STSP(xs) = SCSI_BUSY;
6498 			XS_SETERR(xs, HBA_TGTBSY);
6499 		}
6500 		return;
6501 
6502 	default:
6503 		isp_prt(isp, ISP_LOGERR,
6504 		    "Unknown Completion Status 0x%x on chan %d",
6505 		    sp->req_completion_status, chan);
6506 		break;
6507 	}
6508 	if (XS_NOERR(xs)) {
6509 		XS_SETERR(xs, HBA_BOTCH);
6510 	}
6511 }
6512 
6513 static void
6514 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
6515 {
6516 	XS_T *xs;
6517 
6518 	if (fph == 0) {
6519 		return;
6520 	}
6521 	xs = isp_find_xs(isp, fph);
6522 	if (xs == NULL) {
6523 		isp_prt(isp, ISP_LOGWARN,
6524 		    "Command for fast post handle 0x%x not found", fph);
6525 		return;
6526 	}
6527 	isp_destroy_handle(isp, fph);
6528 
6529 	/*
6530 	 * Since we don't have a result queue entry item,
6531 	 * we must believe that SCSI status is zero and
6532 	 * that all data transferred.
6533 	 */
6534 	XS_SET_RESID(xs, 0);
6535 	*XS_STSP(xs) = SCSI_GOOD;
6536 	if (XS_XFRLEN(xs)) {
6537 		ISP_DMAFREE(isp, xs, fph);
6538 	}
6539 	if (isp->isp_nactive) {
6540 		isp->isp_nactive--;
6541 	}
6542 	isp->isp_fphccmplt++;
6543 	isp_done(xs);
6544 }
6545 
6546 static int
6547 isp_mbox_continue(ispsoftc_t *isp)
6548 {
6549 	mbreg_t mbs;
6550 	uint16_t *ptr;
6551 	uint32_t offset;
6552 
6553 	switch (isp->isp_lastmbxcmd) {
6554 	case MBOX_WRITE_RAM_WORD:
6555 	case MBOX_READ_RAM_WORD:
6556 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6557 	case MBOX_READ_RAM_WORD_EXTENDED:
6558 		break;
6559 	default:
6560 		return (1);
6561 	}
6562 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6563 		isp->isp_mbxwrk0 = 0;
6564 		return (-1);
6565 	}
6566 
6567 	/*
6568 	 * Clear the previous interrupt.
6569 	 */
6570 	if (IS_24XX(isp)) {
6571 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6572 	} else {
6573 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6574 		ISP_WRITE(isp, BIU_SEMA, 0);
6575 	}
6576 
6577 	/*
6578 	 * Continue with next word.
6579 	 */
6580 	ISP_MEMZERO(&mbs, sizeof (mbs));
6581 	ptr = isp->isp_mbxworkp;
6582 	switch (isp->isp_lastmbxcmd) {
6583 	case MBOX_WRITE_RAM_WORD:
6584 		mbs.param[1] = isp->isp_mbxwrk1++;
6585 		mbs.param[2] = *ptr++;
6586 		break;
6587 	case MBOX_READ_RAM_WORD:
6588 		*ptr++ = isp->isp_mboxtmp[2];
6589 		mbs.param[1] = isp->isp_mbxwrk1++;
6590 		break;
6591 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6592 		offset = isp->isp_mbxwrk1;
6593 		offset |= isp->isp_mbxwrk8 << 16;
6594 
6595 		mbs.param[2] = *ptr++;
6596 		mbs.param[1] = offset;
6597 		mbs.param[8] = offset >> 16;
6598 		isp->isp_mbxwrk1 = ++offset;
6599 		isp->isp_mbxwrk8 = offset >> 16;
6600 		break;
6601 	case MBOX_READ_RAM_WORD_EXTENDED:
6602 		offset = isp->isp_mbxwrk1;
6603 		offset |= isp->isp_mbxwrk8 << 16;
6604 
6605 		*ptr++ = isp->isp_mboxtmp[2];
6606 		mbs.param[1] = offset;
6607 		mbs.param[8] = offset >> 16;
6608 		isp->isp_mbxwrk1 = ++offset;
6609 		isp->isp_mbxwrk8 = offset >> 16;
6610 		break;
6611 	}
6612 	isp->isp_mbxworkp = ptr;
6613 	isp->isp_mbxwrk0--;
6614 	mbs.param[0] = isp->isp_lastmbxcmd;
6615 	mbs.logval = MBLOGALL;
6616 	isp_mboxcmd_qnw(isp, &mbs, 0);
6617 	return (0);
6618 }
6619 
6620 #define	HIWRD(x)			((x) >> 16)
6621 #define	LOWRD(x)			((x)  & 0xffff)
6622 #define	ISPOPMAP(a, b)			(((a) << 16) | (b))
6623 static const uint32_t mbpscsi[] = {
6624 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6625 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6626 	ISPOPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6627 	ISPOPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6628 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6629 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6630 	ISPOPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6631 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6632 	ISPOPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6633 	ISPOPMAP(0x00, 0x00),	/* 0x09: */
6634 	ISPOPMAP(0x00, 0x00),	/* 0x0a: */
6635 	ISPOPMAP(0x00, 0x00),	/* 0x0b: */
6636 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6637 	ISPOPMAP(0x00, 0x00),	/* 0x0d: */
6638 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6639 	ISPOPMAP(0x00, 0x00),	/* 0x0f: */
6640 	ISPOPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6641 	ISPOPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6642 	ISPOPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6643 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6644 	ISPOPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6645 	ISPOPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6646 	ISPOPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6647 	ISPOPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6648 	ISPOPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6649 	ISPOPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6650 	ISPOPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6651 	ISPOPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6652 	ISPOPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6653 	ISPOPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6654 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6655 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6656 	ISPOPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6657 	ISPOPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6658 	ISPOPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6659 	ISPOPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6660 	ISPOPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6661 	ISPOPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6662 	ISPOPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6663 	ISPOPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6664 	ISPOPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6665 	ISPOPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6666 	ISPOPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6667 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6668 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6669 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6670 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6671 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6672 	ISPOPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6673 	ISPOPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6674 	ISPOPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6675 	ISPOPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6676 	ISPOPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6677 	ISPOPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6678 	ISPOPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6679 	ISPOPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6680 	ISPOPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6681 	ISPOPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6682 	ISPOPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6683 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6684 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6685 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6686 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6687 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6688 	ISPOPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6689 	ISPOPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6690 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6691 	ISPOPMAP(0x00, 0x00),	/* 0x43: */
6692 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6693 	ISPOPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6694 	ISPOPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6695 	ISPOPMAP(0x00, 0x00),	/* 0x47: */
6696 	ISPOPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6697 	ISPOPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6698 	ISPOPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6699 	ISPOPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6700 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6701 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6702 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6703 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6704 	ISPOPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6705 	ISPOPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6706 	ISPOPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6707 	ISPOPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6708 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6709 	ISPOPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6710 	ISPOPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6711 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6712 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6713 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6714 	ISPOPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6715 	ISPOPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6716 	ISPOPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6717 	ISPOPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6718 };
6719 
6720 static const char *scsi_mbcmd_names[] = {
6721 	"NO-OP",
6722 	"LOAD RAM",
6723 	"EXEC FIRMWARE",
6724 	"DUMP RAM",
6725 	"WRITE RAM WORD",
6726 	"READ RAM WORD",
6727 	"MAILBOX REG TEST",
6728 	"VERIFY CHECKSUM",
6729 	"ABOUT FIRMWARE",
6730 	NULL,
6731 	NULL,
6732 	NULL,
6733 	NULL,
6734 	NULL,
6735 	"CHECK FIRMWARE",
6736 	NULL,
6737 	"INIT REQUEST QUEUE",
6738 	"INIT RESULT QUEUE",
6739 	"EXECUTE IOCB",
6740 	"WAKE UP",
6741 	"STOP FIRMWARE",
6742 	"ABORT",
6743 	"ABORT DEVICE",
6744 	"ABORT TARGET",
6745 	"BUS RESET",
6746 	"STOP QUEUE",
6747 	"START QUEUE",
6748 	"SINGLE STEP QUEUE",
6749 	"ABORT QUEUE",
6750 	"GET DEV QUEUE STATUS",
6751 	NULL,
6752 	"GET FIRMWARE STATUS",
6753 	"GET INIT SCSI ID",
6754 	"GET SELECT TIMEOUT",
6755 	"GET RETRY COUNT",
6756 	"GET TAG AGE LIMIT",
6757 	"GET CLOCK RATE",
6758 	"GET ACT NEG STATE",
6759 	"GET ASYNC DATA SETUP TIME",
6760 	"GET PCI PARAMS",
6761 	"GET TARGET PARAMS",
6762 	"GET DEV QUEUE PARAMS",
6763 	"GET RESET DELAY PARAMS",
6764 	NULL,
6765 	NULL,
6766 	NULL,
6767 	NULL,
6768 	NULL,
6769 	"SET INIT SCSI ID",
6770 	"SET SELECT TIMEOUT",
6771 	"SET RETRY COUNT",
6772 	"SET TAG AGE LIMIT",
6773 	"SET CLOCK RATE",
6774 	"SET ACT NEG STATE",
6775 	"SET ASYNC DATA SETUP TIME",
6776 	"SET PCI CONTROL PARAMS",
6777 	"SET TARGET PARAMS",
6778 	"SET DEV QUEUE PARAMS",
6779 	"SET RESET DELAY PARAMS",
6780 	NULL,
6781 	NULL,
6782 	NULL,
6783 	NULL,
6784 	NULL,
6785 	"RETURN BIOS BLOCK ADDR",
6786 	"WRITE FOUR RAM WORDS",
6787 	"EXEC BIOS IOCB",
6788 	NULL,
6789 	NULL,
6790 	"SET SYSTEM PARAMETER",
6791 	"GET SYSTEM PARAMETER",
6792 	NULL,
6793 	"GET SCAM CONFIGURATION",
6794 	"SET SCAM CONFIGURATION",
6795 	"SET FIRMWARE FEATURES",
6796 	"GET FIRMWARE FEATURES",
6797 	NULL,
6798 	NULL,
6799 	NULL,
6800 	NULL,
6801 	"LOAD RAM A64",
6802 	"DUMP RAM A64",
6803 	"INITIALIZE REQUEST QUEUE A64",
6804 	"INITIALIZE RESPONSE QUEUE A64",
6805 	"EXECUTE IOCB A64",
6806 	"ENABLE TARGET MODE",
6807 	"GET TARGET MODE STATE",
6808 	NULL,
6809 	NULL,
6810 	NULL,
6811 	"SET DATA OVERRUN RECOVERY MODE",
6812 	"GET DATA OVERRUN RECOVERY MODE",
6813 	"SET HOST DATA",
6814 	"GET NOST DATA",
6815 };
6816 
6817 static const uint32_t mbpfc[] = {
6818 	ISPOPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6819 	ISPOPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6820 	ISPOPMAP(0x0f, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6821 	ISPOPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6822 	ISPOPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6823 	ISPOPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6824 	ISPOPMAP(0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6825 	ISPOPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6826 	ISPOPMAP(0x01, 0x4f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6827 	ISPOPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6828 	ISPOPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6829 	ISPOPMAP(0x1ff, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6830 	ISPOPMAP(0x00, 0x00),	/* 0x0c: */
6831 	ISPOPMAP(0x10f, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6832 	ISPOPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6833 	ISPOPMAP(0x10f, 0x05),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6834 	ISPOPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6835 	ISPOPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6836 	ISPOPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6837 	ISPOPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6838 	ISPOPMAP(0x01, 0xff),	/* 0x14: MBOX_STOP_FIRMWARE */
6839 	ISPOPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6840 	ISPOPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6841 	ISPOPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6842 	ISPOPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6843 	ISPOPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6844 	ISPOPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6845 	ISPOPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6846 	ISPOPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6847 	ISPOPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6848 	ISPOPMAP(0x00, 0x00),	/* 0x1e: */
6849 	ISPOPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6850 	ISPOPMAP(0x01, 0x4f),	/* 0x20: MBOX_GET_LOOP_ID */
6851 	ISPOPMAP(0x00, 0x00),	/* 0x21: */
6852 	ISPOPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6853 	ISPOPMAP(0x00, 0x00),	/* 0x23: */
6854 	ISPOPMAP(0x00, 0x00),	/* 0x24: */
6855 	ISPOPMAP(0x00, 0x00),	/* 0x25: */
6856 	ISPOPMAP(0x00, 0x00),	/* 0x26: */
6857 	ISPOPMAP(0x00, 0x00),	/* 0x27: */
6858 	ISPOPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6859 	ISPOPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6860 	ISPOPMAP(0x00, 0x00),	/* 0x2a: */
6861 	ISPOPMAP(0x00, 0x00),	/* 0x2b: */
6862 	ISPOPMAP(0x00, 0x00),	/* 0x2c: */
6863 	ISPOPMAP(0x00, 0x00),	/* 0x2d: */
6864 	ISPOPMAP(0x00, 0x00),	/* 0x2e: */
6865 	ISPOPMAP(0x00, 0x00),	/* 0x2f: */
6866 	ISPOPMAP(0x00, 0x00),	/* 0x30: */
6867 	ISPOPMAP(0x00, 0x00),	/* 0x31: */
6868 	ISPOPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6869 	ISPOPMAP(0x00, 0x00),	/* 0x33: */
6870 	ISPOPMAP(0x00, 0x00),	/* 0x34: */
6871 	ISPOPMAP(0x00, 0x00),	/* 0x35: */
6872 	ISPOPMAP(0x00, 0x00),	/* 0x36: */
6873 	ISPOPMAP(0x00, 0x00),	/* 0x37: */
6874 	ISPOPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6875 	ISPOPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6876 	ISPOPMAP(0x00, 0x00),	/* 0x3a: */
6877 	ISPOPMAP(0x00, 0x00),	/* 0x3b: */
6878 	ISPOPMAP(0x00, 0x00),	/* 0x3c: */
6879 	ISPOPMAP(0x00, 0x00),	/* 0x3d: */
6880 	ISPOPMAP(0x00, 0x00),	/* 0x3e: */
6881 	ISPOPMAP(0x00, 0x00),	/* 0x3f: */
6882 	ISPOPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6883 	ISPOPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6884 	ISPOPMAP(0x03, 0x07),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6885 	ISPOPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6886 	ISPOPMAP(0x00, 0x00),	/* 0x44: */
6887 	ISPOPMAP(0x00, 0x00),	/* 0x45: */
6888 	ISPOPMAP(0x00, 0x00),	/* 0x46: */
6889 	ISPOPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6890 	ISPOPMAP(0xcd, 0x01),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6891 	ISPOPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
6892 	ISPOPMAP(0x2cd, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6893 	ISPOPMAP(0x00, 0x00),	/* 0x4b: */
6894 	ISPOPMAP(0x00, 0x00),	/* 0x4c: */
6895 	ISPOPMAP(0x00, 0x00),	/* 0x4d: */
6896 	ISPOPMAP(0x00, 0x00),	/* 0x4e: */
6897 	ISPOPMAP(0x00, 0x00),	/* 0x4f: */
6898 	ISPOPMAP(0x00, 0x00),	/* 0x50: */
6899 	ISPOPMAP(0x00, 0x00),	/* 0x51: */
6900 	ISPOPMAP(0x00, 0x00),	/* 0x52: */
6901 	ISPOPMAP(0x00, 0x00),	/* 0x53: */
6902 	ISPOPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6903 	ISPOPMAP(0x00, 0x00),	/* 0x55: */
6904 	ISPOPMAP(0x00, 0x00),	/* 0x56: */
6905 	ISPOPMAP(0x00, 0x00),	/* 0x57: */
6906 	ISPOPMAP(0x00, 0x00),	/* 0x58: */
6907 	ISPOPMAP(0x00, 0x00),	/* 0x59: */
6908 	ISPOPMAP(0x00, 0x00),	/* 0x5a: */
6909 	ISPOPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6910 	ISPOPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6911 	ISPOPMAP(0x07, 0x03),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6912 	ISPOPMAP(0x00, 0x00),	/* 0x5e: */
6913 	ISPOPMAP(0x00, 0x00),	/* 0x5f: */
6914 	ISPOPMAP(0xcd, 0x01),	/* 0x60: MBOX_INIT_FIRMWARE */
6915 	ISPOPMAP(0x00, 0x00),	/* 0x61: */
6916 	ISPOPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6917 	ISPOPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6918 	ISPOPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6919 	ISPOPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6920 	ISPOPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6921 	ISPOPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6922 	ISPOPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6923 	ISPOPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6924 	ISPOPMAP(0x03, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6925 	ISPOPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6926 	ISPOPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6927 	ISPOPMAP(0x00, 0x00),	/* 0x6d: */
6928 	ISPOPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6929 	ISPOPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6930 	ISPOPMAP(0x03, 0x01),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6931 	ISPOPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6932 	ISPOPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6933 	ISPOPMAP(0x00, 0x00),	/* 0x73: */
6934 	ISPOPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6935 	ISPOPMAP(0xcf, 0x03),	/* 0x75: GET PORT/NODE NAME LIST */
6936 	ISPOPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6937 	ISPOPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6938 	ISPOPMAP(0x00, 0x00),	/* 0x78: */
6939 	ISPOPMAP(0x00, 0x00),	/* 0x79: */
6940 	ISPOPMAP(0x00, 0x00),	/* 0x7a: */
6941 	ISPOPMAP(0x00, 0x00),	/* 0x7b: */
6942 	ISPOPMAP(0x4f, 0x03),	/* 0x7c: Get ID List */
6943 	ISPOPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6944 	ISPOPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6945 };
6946 /*
6947  * Footnotes
6948  *
6949  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
6950  *	do not access at this time in the core driver. The caller is
6951  *	responsible for setting this register first (Gross!). The assumption
6952  *	is that we won't overflow.
6953  */
6954 
6955 static const char *fc_mbcmd_names[] = {
6956 	"NO-OP",
6957 	"LOAD RAM",
6958 	"EXEC FIRMWARE",
6959 	"DUMP RAM",
6960 	"WRITE RAM WORD",
6961 	"READ RAM WORD",
6962 	"MAILBOX REG TEST",
6963 	"VERIFY CHECKSUM",
6964 	"ABOUT FIRMWARE",
6965 	"LOAD RAM",
6966 	"DUMP RAM",
6967 	"WRITE RAM WORD EXTENDED",
6968 	NULL,
6969 	"READ RAM WORD EXTENDED",
6970 	"CHECK FIRMWARE",
6971 	NULL,
6972 	"INIT REQUEST QUEUE",
6973 	"INIT RESULT QUEUE",
6974 	"EXECUTE IOCB",
6975 	"WAKE UP",
6976 	"STOP FIRMWARE",
6977 	"ABORT",
6978 	"ABORT DEVICE",
6979 	"ABORT TARGET",
6980 	"BUS RESET",
6981 	"STOP QUEUE",
6982 	"START QUEUE",
6983 	"SINGLE STEP QUEUE",
6984 	"ABORT QUEUE",
6985 	"GET DEV QUEUE STATUS",
6986 	NULL,
6987 	"GET FIRMWARE STATUS",
6988 	"GET LOOP ID",
6989 	NULL,
6990 	"GET RETRY COUNT",
6991 	NULL,
6992 	NULL,
6993 	NULL,
6994 	NULL,
6995 	NULL,
6996 	"GET FIRMWARE OPTIONS",
6997 	"GET PORT QUEUE PARAMS",
6998 	NULL,
6999 	NULL,
7000 	NULL,
7001 	NULL,
7002 	NULL,
7003 	NULL,
7004 	NULL,
7005 	NULL,
7006 	"SET RETRY COUNT",
7007 	NULL,
7008 	NULL,
7009 	NULL,
7010 	NULL,
7011 	NULL,
7012 	"SET FIRMWARE OPTIONS",
7013 	"SET PORT QUEUE PARAMS",
7014 	NULL,
7015 	NULL,
7016 	NULL,
7017 	NULL,
7018 	NULL,
7019 	NULL,
7020 	"LOOP PORT BYPASS",
7021 	"LOOP PORT ENABLE",
7022 	"GET RESOURCE COUNT",
7023 	"REQUEST NON PARTICIPATING MODE",
7024 	NULL,
7025 	NULL,
7026 	NULL,
7027 	"GET PORT DATABASE ENHANCED",
7028 	"INIT FIRMWARE MULTI ID",
7029 	"GET VP DATABASE",
7030 	"GET VP DATABASE ENTRY",
7031 	NULL,
7032 	NULL,
7033 	NULL,
7034 	NULL,
7035 	NULL,
7036 	NULL,
7037 	NULL,
7038 	NULL,
7039 	NULL,
7040 	"EXECUTE IOCB A64",
7041 	NULL,
7042 	NULL,
7043 	NULL,
7044 	NULL,
7045 	NULL,
7046 	NULL,
7047 	"DRIVER HEARTBEAT",
7048 	NULL,
7049 	"GET/SET DATA RATE",
7050 	NULL,
7051 	NULL,
7052 	"INIT FIRMWARE",
7053 	NULL,
7054 	"INIT LIP",
7055 	"GET FC-AL POSITION MAP",
7056 	"GET PORT DATABASE",
7057 	"CLEAR ACA",
7058 	"TARGET RESET",
7059 	"CLEAR TASK SET",
7060 	"ABORT TASK SET",
7061 	"GET FW STATE",
7062 	"GET PORT NAME",
7063 	"GET LINK STATUS",
7064 	"INIT LIP RESET",
7065 	NULL,
7066 	"SEND SNS",
7067 	"FABRIC LOGIN",
7068 	"SEND CHANGE REQUEST",
7069 	"FABRIC LOGOUT",
7070 	"INIT LIP LOGIN",
7071 	NULL,
7072 	"LOGIN LOOP PORT",
7073 	"GET PORT/NODE NAME LIST",
7074 	"SET VENDOR ID",
7075 	"INITIALIZE IP MAILBOX",
7076 	NULL,
7077 	NULL,
7078 	NULL,
7079 	NULL,
7080 	"Get ID List",
7081 	"SEND LFA",
7082 	"Lun RESET"
7083 };
7084 
7085 static void
7086 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7087 {
7088 	unsigned int ibits, obits, box, opcode;
7089 	const uint32_t *mcp;
7090 
7091 	if (IS_FC(isp)) {
7092 		mcp = mbpfc;
7093 	} else {
7094 		mcp = mbpscsi;
7095 	}
7096 	opcode = mbp->param[0];
7097 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7098 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7099 	ibits |= mbp->ibits;
7100 	obits |= mbp->obits;
7101 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7102 		if (ibits & (1 << box)) {
7103 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7104 		}
7105 		if (nodelay == 0) {
7106 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7107 		}
7108 	}
7109 	if (nodelay == 0) {
7110 		isp->isp_lastmbxcmd = opcode;
7111 		isp->isp_obits = obits;
7112 		isp->isp_mboxbsy = 1;
7113 	}
7114 	if (IS_24XX(isp)) {
7115 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7116 	} else {
7117 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7118 	}
7119 	/*
7120 	 * Oddly enough, if we're not delaying for an answer,
7121 	 * delay a bit to give the f/w a chance to pick up the
7122 	 * command.
7123 	 */
7124 	if (nodelay) {
7125 		ISP_DELAY(1000);
7126 	}
7127 }
7128 
7129 static void
7130 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7131 {
7132 	const char *cname, *xname;
7133 	char tname[16], mname[16];
7134 	unsigned int lim, ibits, obits, box, opcode;
7135 	const uint32_t *mcp;
7136 
7137 	if (IS_FC(isp)) {
7138 		mcp = mbpfc;
7139 		lim = (sizeof (mbpfc) / sizeof (mbpfc[0]));
7140 	} else {
7141 		mcp = mbpscsi;
7142 		lim = (sizeof (mbpscsi) / sizeof (mbpscsi[0]));
7143 	}
7144 
7145 	if ((opcode = mbp->param[0]) >= lim) {
7146 		mbp->param[0] = MBOX_INVALID_COMMAND;
7147 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7148 		return;
7149 	}
7150 
7151 	ibits = HIWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7152 	obits = LOWRD(mcp[opcode]) & NMBOX_BMASK(isp);
7153 
7154 	/*
7155 	 * Pick up any additional bits that the caller might have set.
7156 	 */
7157 	ibits |= mbp->ibits;
7158 	obits |= mbp->obits;
7159 
7160 	if (ibits == 0 && obits == 0) {
7161 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7162 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7163 		return;
7164 	}
7165 
7166 	/*
7167 	 * Get exclusive usage of mailbox registers.
7168 	 */
7169 	if (MBOX_ACQUIRE(isp)) {
7170 		mbp->param[0] = MBOX_REGS_BUSY;
7171 		goto out;
7172 	}
7173 
7174 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7175 		if (ibits & (1 << box)) {
7176 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7177 			    mbp->param[box]);
7178 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7179 		}
7180 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7181 	}
7182 
7183 	isp->isp_lastmbxcmd = opcode;
7184 
7185 	/*
7186 	 * We assume that we can't overwrite a previous command.
7187 	 */
7188 	isp->isp_obits = obits;
7189 	isp->isp_mboxbsy = 1;
7190 
7191 	/*
7192 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7193 	 */
7194 	if (IS_24XX(isp)) {
7195 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7196 	} else {
7197 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7198 	}
7199 
7200 	/*
7201 	 * While we haven't finished the command, spin our wheels here.
7202 	 */
7203 	MBOX_WAIT_COMPLETE(isp, mbp);
7204 
7205 	/*
7206 	 * Did the command time out?
7207 	 */
7208 	if (mbp->param[0] == MBOX_TIMEOUT) {
7209 		isp->isp_mboxbsy = 0;
7210 		MBOX_RELEASE(isp);
7211 		goto out;
7212 	}
7213 
7214 	/*
7215 	 * Copy back output registers.
7216 	 */
7217 	for (box = 0; box < MAX_MAILBOX(isp); box++) {
7218 		if (obits & (1 << box)) {
7219 			mbp->param[box] = isp->isp_mboxtmp[box];
7220 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7221 			    mbp->param[box]);
7222 		}
7223 	}
7224 
7225 	isp->isp_mboxbsy = 0;
7226 	MBOX_RELEASE(isp);
7227  out:
7228 	if (mbp->logval == 0 || opcode == MBOX_EXEC_FIRMWARE) {
7229 		return;
7230 	}
7231 	cname = (IS_FC(isp))? fc_mbcmd_names[opcode] : scsi_mbcmd_names[opcode];
7232 	if (cname == NULL) {
7233 		cname = tname;
7234 		ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7235 	}
7236 
7237 	/*
7238 	 * Just to be chatty here...
7239 	 */
7240 	xname = NULL;
7241 	switch (mbp->param[0]) {
7242 	case MBOX_COMMAND_COMPLETE:
7243 		break;
7244 	case MBOX_INVALID_COMMAND:
7245 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_COMPLETE)) {
7246 			xname = "INVALID COMMAND";
7247 		}
7248 		break;
7249 	case MBOX_HOST_INTERFACE_ERROR:
7250 		if (mbp->logval & MBLOGMASK(MBOX_HOST_INTERFACE_ERROR)) {
7251 			xname = "HOST INTERFACE ERROR";
7252 		}
7253 		break;
7254 	case MBOX_TEST_FAILED:
7255 		if (mbp->logval & MBLOGMASK(MBOX_TEST_FAILED)) {
7256 			xname = "TEST FAILED";
7257 		}
7258 		break;
7259 	case MBOX_COMMAND_ERROR:
7260 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_ERROR)) {
7261 			xname = "COMMAND ERROR";
7262 		}
7263 		break;
7264 	case MBOX_COMMAND_PARAM_ERROR:
7265 		if (mbp->logval & MBLOGMASK(MBOX_COMMAND_PARAM_ERROR)) {
7266 			xname = "COMMAND PARAMETER ERROR";
7267 		}
7268 		break;
7269 	case MBOX_LOOP_ID_USED:
7270 		if (mbp->logval & MBLOGMASK(MBOX_LOOP_ID_USED)) {
7271 			xname = "LOOP ID ALREADY IN USE";
7272 		}
7273 		break;
7274 	case MBOX_PORT_ID_USED:
7275 		if (mbp->logval & MBLOGMASK(MBOX_PORT_ID_USED)) {
7276 			xname = "PORT ID ALREADY IN USE";
7277 		}
7278 		break;
7279 	case MBOX_ALL_IDS_USED:
7280 		if (mbp->logval & MBLOGMASK(MBOX_ALL_IDS_USED)) {
7281 			xname = "ALL LOOP IDS IN USE";
7282 		}
7283 		break;
7284 	case MBOX_REGS_BUSY:
7285 		xname = "REGISTERS BUSY";
7286 		break;
7287 	case MBOX_TIMEOUT:
7288 		xname = "TIMEOUT";
7289 		break;
7290 	default:
7291 		ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7292 		xname = mname;
7293 		break;
7294 	}
7295 	if (xname) {
7296 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s)",
7297 		    cname, xname);
7298 	}
7299 }
7300 
7301 static void
7302 isp_fw_state(ispsoftc_t *isp, int chan)
7303 {
7304 	if (IS_FC(isp)) {
7305 		mbreg_t mbs;
7306 		fcparam *fcp = FCPARAM(isp, chan);
7307 
7308 		MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7309 		isp_mboxcmd(isp, &mbs);
7310 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7311 			fcp->isp_fwstate = mbs.param[1];
7312 		}
7313 	}
7314 }
7315 
7316 static void
7317 isp_spi_update(ispsoftc_t *isp, int chan)
7318 {
7319 	int tgt;
7320 	mbreg_t mbs;
7321 	sdparam *sdp;
7322 
7323 	if (IS_FC(isp)) {
7324 		/*
7325 		 * There are no 'per-bus' settings for Fibre Channel.
7326 		 */
7327 		return;
7328 	}
7329 	sdp = SDPARAM(isp, chan);
7330 	sdp->update = 0;
7331 
7332 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7333 		uint16_t flags, period, offset;
7334 		int get;
7335 
7336 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
7337 			sdp->isp_devparam[tgt].dev_update = 0;
7338 			sdp->isp_devparam[tgt].dev_refresh = 0;
7339 			isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
7340 			continue;
7341 		}
7342 		/*
7343 		 * If the goal is to update the status of the device,
7344 		 * take what's in goal_flags and try and set the device
7345 		 * toward that. Otherwise, if we're just refreshing the
7346 		 * current device state, get the current parameters.
7347 		 */
7348 
7349 		MBSINIT(&mbs, 0, MBLOGALL, 0);
7350 
7351 		/*
7352 		 * Refresh overrides set
7353 		 */
7354 		if (sdp->isp_devparam[tgt].dev_refresh) {
7355 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7356 			get = 1;
7357 		} else if (sdp->isp_devparam[tgt].dev_update) {
7358 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7359 
7360 			/*
7361 			 * Make sure goal_flags has "Renegotiate on Error"
7362 			 * on and "Freeze Queue on Error" off.
7363 			 */
7364 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7365 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7366 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7367 
7368 			/*
7369 			 * Insist that PARITY must be enabled
7370 			 * if SYNC or WIDE is enabled.
7371 			 */
7372 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7373 				mbs.param[2] |= DPARM_PARITY;
7374 			}
7375 
7376 			if (mbs.param[2] & DPARM_SYNC) {
7377 				mbs.param[3] =
7378 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
7379 				    (sdp->isp_devparam[tgt].goal_period);
7380 			}
7381 			/*
7382 			 * A command completion later that has
7383 			 * RQSTF_NEGOTIATION set can cause
7384 			 * the dev_refresh/announce cycle also.
7385 			 *
7386 			 * Note: It is really important to update our current
7387 			 * flags with at least the state of TAG capabilities-
7388 			 * otherwise we might try and send a tagged command
7389 			 * when we have it all turned off. So change it here
7390 			 * to say that current already matches goal.
7391 			 */
7392 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7393 			sdp->isp_devparam[tgt].actv_flags |=
7394 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7395 			isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7396 			    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
7397 			get = 0;
7398 		} else {
7399 			continue;
7400 		}
7401 		mbs.param[1] = (chan << 15) | (tgt << 8);
7402 		isp_mboxcmd(isp, &mbs);
7403 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7404 			continue;
7405 		}
7406 		if (get == 0) {
7407 			sdp->sendmarker = 1;
7408 			sdp->isp_devparam[tgt].dev_update = 0;
7409 			sdp->isp_devparam[tgt].dev_refresh = 1;
7410 		} else {
7411 			sdp->isp_devparam[tgt].dev_refresh = 0;
7412 			flags = mbs.param[2];
7413 			period = mbs.param[3] & 0xff;
7414 			offset = mbs.param[3] >> 8;
7415 			sdp->isp_devparam[tgt].actv_flags = flags;
7416 			sdp->isp_devparam[tgt].actv_period = period;
7417 			sdp->isp_devparam[tgt].actv_offset = offset;
7418 			isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7419 		}
7420 	}
7421 
7422 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7423 		if (sdp->isp_devparam[tgt].dev_update ||
7424 		    sdp->isp_devparam[tgt].dev_refresh) {
7425 			sdp->update = 1;
7426 			break;
7427 		}
7428 	}
7429 }
7430 
7431 static void
7432 isp_setdfltsdparm(ispsoftc_t *isp)
7433 {
7434 	int tgt;
7435 	sdparam *sdp, *sdp1;
7436 
7437 	sdp = SDPARAM(isp, 0);
7438 	sdp->role = GET_DEFAULT_ROLE(isp, 0);
7439 	if (IS_DUALBUS(isp)) {
7440 		sdp1 = sdp + 1;
7441 		sdp1->role = GET_DEFAULT_ROLE(isp, 1);
7442 	} else {
7443 		sdp1 = NULL;
7444 	}
7445 
7446 	/*
7447 	 * Establish some default parameters.
7448 	 */
7449 	sdp->isp_cmd_dma_burst_enable = 0;
7450 	sdp->isp_data_dma_burst_enabl = 1;
7451 	sdp->isp_fifo_threshold = 0;
7452 	sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7453 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7454 		sdp->isp_async_data_setup = 9;
7455 	} else {
7456 		sdp->isp_async_data_setup = 6;
7457 	}
7458 	sdp->isp_selection_timeout = 250;
7459 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7460 	sdp->isp_tag_aging = 8;
7461 	sdp->isp_bus_reset_delay = 5;
7462 	/*
7463 	 * Don't retry selection, busy or queue full automatically- reflect
7464 	 * these back to us.
7465 	 */
7466 	sdp->isp_retry_count = 0;
7467 	sdp->isp_retry_delay = 0;
7468 
7469 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7470 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7471 		sdp->isp_devparam[tgt].dev_enable = 1;
7472 	}
7473 
7474 	/*
7475 	 * The trick here is to establish a default for the default (honk!)
7476 	 * state (goal_flags). Then try and get the current status from
7477 	 * the card to fill in the current state. We don't, in fact, set
7478 	 * the default to the SAFE default state- that's not the goal state.
7479 	 */
7480 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7481 		uint8_t off, per;
7482 		sdp->isp_devparam[tgt].actv_offset = 0;
7483 		sdp->isp_devparam[tgt].actv_period = 0;
7484 		sdp->isp_devparam[tgt].actv_flags = 0;
7485 
7486 		sdp->isp_devparam[tgt].goal_flags =
7487 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7488 
7489 		/*
7490 		 * We default to Wide/Fast for versions less than a 1040
7491 		 * (unless it's SBus).
7492 		 */
7493 		if (IS_ULTRA3(isp)) {
7494 			off = ISP_80M_SYNCPARMS >> 8;
7495 			per = ISP_80M_SYNCPARMS & 0xff;
7496 		} else if (IS_ULTRA2(isp)) {
7497 			off = ISP_40M_SYNCPARMS >> 8;
7498 			per = ISP_40M_SYNCPARMS & 0xff;
7499 		} else if (IS_1240(isp)) {
7500 			off = ISP_20M_SYNCPARMS >> 8;
7501 			per = ISP_20M_SYNCPARMS & 0xff;
7502 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7503 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7504 		    (isp->isp_bustype == ISP_BT_PCI &&
7505 		    isp->isp_type < ISP_HA_SCSI_1040) ||
7506 		    (isp->isp_clock && isp->isp_clock < 60) ||
7507 		    (sdp->isp_ultramode == 0)) {
7508 			off = ISP_10M_SYNCPARMS >> 8;
7509 			per = ISP_10M_SYNCPARMS & 0xff;
7510 		} else {
7511 			off = ISP_20M_SYNCPARMS_1040 >> 8;
7512 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7513 		}
7514 		sdp->isp_devparam[tgt].goal_offset =
7515 		    sdp->isp_devparam[tgt].nvrm_offset = off;
7516 		sdp->isp_devparam[tgt].goal_period =
7517 		    sdp->isp_devparam[tgt].nvrm_period = per;
7518 
7519 	}
7520 
7521 	/*
7522 	 * If we're a dual bus card, just copy the data over
7523 	 */
7524 	if (sdp1) {
7525 		*sdp1 = *sdp;
7526 		sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7527 	}
7528 
7529 	/*
7530 	 * If we've not been told to avoid reading NVRAM, try and read it.
7531 	 * If we're successful reading it, we can then return because NVRAM
7532 	 * will tell us what the desired settings are. Otherwise, we establish
7533 	 * some reasonable 'fake' nvram and goal defaults.
7534 	 */
7535 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7536 		mbreg_t mbs;
7537 
7538 		if (isp_read_nvram(isp, 0) == 0) {
7539 			if (IS_DUALBUS(isp)) {
7540 				if (isp_read_nvram(isp, 1) == 0) {
7541 					return;
7542 				}
7543 			}
7544 		}
7545 		MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7546 		isp_mboxcmd(isp, &mbs);
7547 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7548 			sdp->isp_req_ack_active_neg = 1;
7549 			sdp->isp_data_line_active_neg = 1;
7550 			if (sdp1) {
7551 				sdp1->isp_req_ack_active_neg = 1;
7552 				sdp1->isp_data_line_active_neg = 1;
7553 			}
7554 		} else {
7555 			sdp->isp_req_ack_active_neg =
7556 			    (mbs.param[1] >> 4) & 0x1;
7557 			sdp->isp_data_line_active_neg =
7558 			    (mbs.param[1] >> 5) & 0x1;
7559 			if (sdp1) {
7560 				sdp1->isp_req_ack_active_neg =
7561 				    (mbs.param[2] >> 4) & 0x1;
7562 				sdp1->isp_data_line_active_neg =
7563 				    (mbs.param[2] >> 5) & 0x1;
7564 			}
7565 		}
7566 	}
7567 
7568 }
7569 
7570 static void
7571 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7572 {
7573 	fcparam *fcp = FCPARAM(isp, chan);
7574 
7575 	/*
7576 	 * Establish some default parameters.
7577 	 */
7578 	fcp->role = GET_DEFAULT_ROLE(isp, chan);
7579 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7580 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7581 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7582 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7583 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7584 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7585 	fcp->isp_fwoptions = 0;
7586 	fcp->isp_lasthdl = NIL_HANDLE;
7587 
7588 	if (IS_24XX(isp)) {
7589 		fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7590 		fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7591 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7592 			fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7593 		}
7594 		fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7595 	} else {
7596 		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7597 		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7598 		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7599 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7600 			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7601 		}
7602 		/*
7603 		 * Make sure this is turned off now until we get
7604 		 * extended options from NVRAM
7605 		 */
7606 		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7607 	}
7608 
7609 
7610 	/*
7611 	 * Now try and read NVRAM unless told to not do so.
7612 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7613 	 */
7614 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7615 		int i, j = 0;
7616 		/*
7617 		 * Give a couple of tries at reading NVRAM.
7618 		 */
7619 		for (i = 0; i < 2; i++) {
7620 			j = isp_read_nvram(isp, chan);
7621 			if (j == 0) {
7622 				break;
7623 			}
7624 		}
7625 		if (j) {
7626 			isp->isp_confopts |= ISP_CFG_NONVRAM;
7627 		}
7628 	}
7629 
7630 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7631 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7632 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7633 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7634 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7635 	    isp_class3_roles[fcp->role]);
7636 }
7637 
7638 /*
7639  * Re-initialize the ISP and complete all orphaned commands
7640  * with a 'botched' notice. The reset/init routines should
7641  * not disturb an already active list of commands.
7642  */
7643 
7644 void
7645 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7646 {
7647 	int i;
7648 
7649 	isp_reset(isp, do_load_defaults);
7650 
7651 	if (isp->isp_state != ISP_RESETSTATE) {
7652 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7653 		ISP_DISABLE_INTS(isp);
7654 		goto cleanup;
7655 	}
7656 
7657 	isp_init(isp);
7658 
7659 	if (isp->isp_state == ISP_INITSTATE) {
7660 		isp->isp_state = ISP_RUNSTATE;
7661 	}
7662 
7663 	if (isp->isp_state != ISP_RUNSTATE) {
7664 #ifndef	ISP_TARGET_MODE
7665 		isp_prt(isp, ISP_LOGWARN, "%s: not at runstate", __func__);
7666 #endif
7667 		ISP_DISABLE_INTS(isp);
7668 		if (IS_FC(isp)) {
7669 			/*
7670 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7671 			 */
7672 			if (!IS_24XX(isp)) {
7673 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7674 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7675 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7676 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7677 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7678 			}
7679 		}
7680  	}
7681 
7682  cleanup:
7683 
7684 	isp->isp_nactive = 0;
7685 
7686 	isp_clear_commands(isp);
7687 	if (IS_FC(isp)) {
7688 		for (i = 0; i < isp->isp_nchan; i++) {
7689 			ISP_MARK_PORTDB(isp, i, -1);
7690 		}
7691 	}
7692 }
7693 
7694 /*
7695  * NVRAM Routines
7696  */
7697 static int
7698 isp_read_nvram(ispsoftc_t *isp, int bus)
7699 {
7700 	int i, amt, retval;
7701 	uint8_t csum, minversion;
7702 	union {
7703 		uint8_t _x[ISP2400_NVRAM_SIZE];
7704 		uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7705 	} _n;
7706 #define	nvram_data	_n._x
7707 #define	nvram_words	_n._s
7708 
7709 	if (IS_24XX(isp)) {
7710 		return (isp_read_nvram_2400(isp, nvram_data));
7711 	} else if (IS_FC(isp)) {
7712 		amt = ISP2100_NVRAM_SIZE;
7713 		minversion = 1;
7714 	} else if (IS_ULTRA2(isp)) {
7715 		amt = ISP1080_NVRAM_SIZE;
7716 		minversion = 0;
7717 	} else {
7718 		amt = ISP_NVRAM_SIZE;
7719 		minversion = 2;
7720 	}
7721 
7722 	for (i = 0; i < amt>>1; i++) {
7723 		isp_rdnvram_word(isp, i, &nvram_words[i]);
7724 	}
7725 
7726 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7727 	    nvram_data[2] != 'P') {
7728 		if (isp->isp_bustype != ISP_BT_SBUS) {
7729 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7730 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
7731 		}
7732 		retval = -1;
7733 		goto out;
7734 	}
7735 
7736 	for (csum = 0, i = 0; i < amt; i++) {
7737 		csum += nvram_data[i];
7738 	}
7739 	if (csum != 0) {
7740 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7741 		retval = -1;
7742 		goto out;
7743 	}
7744 
7745 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7746 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7747 		    ISP_NVRAM_VERSION(nvram_data));
7748 		retval = -1;
7749 		goto out;
7750 	}
7751 
7752 	if (IS_ULTRA3(isp)) {
7753 		isp_parse_nvram_12160(isp, bus, nvram_data);
7754 	} else if (IS_1080(isp)) {
7755 		isp_parse_nvram_1080(isp, bus, nvram_data);
7756 	} else if (IS_1280(isp) || IS_1240(isp)) {
7757 		isp_parse_nvram_1080(isp, bus, nvram_data);
7758 	} else if (IS_SCSI(isp)) {
7759 		isp_parse_nvram_1020(isp, nvram_data);
7760 	} else {
7761 		isp_parse_nvram_2100(isp, nvram_data);
7762 	}
7763 	retval = 0;
7764 out:
7765 	return (retval);
7766 #undef	nvram_data
7767 #undef	nvram_words
7768 }
7769 
7770 static int
7771 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7772 {
7773 	int retval = 0;
7774 	uint32_t addr, csum, lwrds, *dptr;
7775 
7776 	if (isp->isp_port) {
7777 		addr = ISP2400_NVRAM_PORT1_ADDR;
7778 	} else {
7779 		addr = ISP2400_NVRAM_PORT0_ADDR;
7780 	}
7781 
7782 	dptr = (uint32_t *) nvram_data;
7783 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7784 		isp_rd_2400_nvram(isp, addr++, dptr++);
7785 	}
7786 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7787 	    nvram_data[2] != 'P') {
7788 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7789 		    nvram_data[0], nvram_data[1], nvram_data[2]);
7790 		retval = -1;
7791 		goto out;
7792 	}
7793 	dptr = (uint32_t *) nvram_data;
7794 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7795 		uint32_t tmp;
7796 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7797 		csum += tmp;
7798 	}
7799 	if (csum != 0) {
7800 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7801 		retval = -1;
7802 		goto out;
7803 	}
7804 	isp_parse_nvram_2400(isp, nvram_data);
7805 out:
7806 	return (retval);
7807 }
7808 
7809 static void
7810 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7811 {
7812 	int i, cbits;
7813 	uint16_t bit, rqst, junk;
7814 
7815 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7816 	ISP_DELAY(10);
7817 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7818 	ISP_DELAY(10);
7819 
7820 	if (IS_FC(isp)) {
7821 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7822 		if (IS_2312(isp) && isp->isp_port) {
7823 			wo += 128;
7824 		}
7825 		rqst = (ISP_NVRAM_READ << 8) | wo;
7826 		cbits = 10;
7827 	} else if (IS_ULTRA2(isp)) {
7828 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7829 		rqst = (ISP_NVRAM_READ << 8) | wo;
7830 		cbits = 10;
7831 	} else {
7832 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7833 		rqst = (ISP_NVRAM_READ << 6) | wo;
7834 		cbits = 8;
7835 	}
7836 
7837 	/*
7838 	 * Clock the word select request out...
7839 	 */
7840 	for (i = cbits; i >= 0; i--) {
7841 		if ((rqst >> i) & 1) {
7842 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7843 		} else {
7844 			bit = BIU_NVRAM_SELECT;
7845 		}
7846 		ISP_WRITE(isp, BIU_NVRAM, bit);
7847 		ISP_DELAY(10);
7848 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7849 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7850 		ISP_DELAY(10);
7851 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7852 		ISP_WRITE(isp, BIU_NVRAM, bit);
7853 		ISP_DELAY(10);
7854 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7855 	}
7856 	/*
7857 	 * Now read the result back in (bits come back in MSB format).
7858 	 */
7859 	*rp = 0;
7860 	for (i = 0; i < 16; i++) {
7861 		uint16_t rv;
7862 		*rp <<= 1;
7863 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7864 		ISP_DELAY(10);
7865 		rv = ISP_READ(isp, BIU_NVRAM);
7866 		if (rv & BIU_NVRAM_DATAIN) {
7867 			*rp |= 1;
7868 		}
7869 		ISP_DELAY(10);
7870 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7871 		ISP_DELAY(10);
7872 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7873 	}
7874 	ISP_WRITE(isp, BIU_NVRAM, 0);
7875 	ISP_DELAY(10);
7876 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7877 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7878 }
7879 
7880 static void
7881 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7882 {
7883 	int loops = 0;
7884 	uint32_t base = 0x7ffe0000;
7885 	uint32_t tmp = 0;
7886 
7887 	if (IS_25XX(isp)) {
7888 		base = 0x7ff00000 | 0x48000;
7889 	}
7890 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7891 	for (loops = 0; loops < 5000; loops++) {
7892 		ISP_DELAY(10);
7893 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7894 		if ((tmp & (1U << 31)) != 0) {
7895 			break;
7896 		}
7897 	}
7898 	if (tmp & (1U << 31)) {
7899 		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7900 		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7901 	} else {
7902 		*rp = 0xffffffff;
7903 	}
7904 }
7905 
7906 static void
7907 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7908 {
7909 	sdparam *sdp = SDPARAM(isp, 0);
7910 	int tgt;
7911 
7912 	sdp->isp_fifo_threshold =
7913 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7914 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7915 
7916 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7917 		sdp->isp_initiator_id =
7918 			ISP_NVRAM_INITIATOR_ID(nvram_data);
7919 
7920 	sdp->isp_bus_reset_delay =
7921 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7922 
7923 	sdp->isp_retry_count =
7924 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7925 
7926 	sdp->isp_retry_delay =
7927 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7928 
7929 	sdp->isp_async_data_setup =
7930 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7931 
7932 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7933 		if (sdp->isp_async_data_setup < 9) {
7934 			sdp->isp_async_data_setup = 9;
7935 		}
7936 	} else {
7937 		if (sdp->isp_async_data_setup != 6) {
7938 			sdp->isp_async_data_setup = 6;
7939 		}
7940 	}
7941 
7942 	sdp->isp_req_ack_active_neg =
7943 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
7944 
7945 	sdp->isp_data_line_active_neg =
7946 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
7947 
7948 	sdp->isp_data_dma_burst_enabl =
7949 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
7950 
7951 	sdp->isp_cmd_dma_burst_enable =
7952 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
7953 
7954 	sdp->isp_tag_aging =
7955 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
7956 
7957 	sdp->isp_selection_timeout =
7958 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
7959 
7960 	sdp->isp_max_queue_depth =
7961 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
7962 
7963 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
7964 
7965 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7966 		sdp->isp_devparam[tgt].dev_enable =
7967 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
7968 		sdp->isp_devparam[tgt].exc_throttle =
7969 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
7970 		sdp->isp_devparam[tgt].nvrm_offset =
7971 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
7972 		sdp->isp_devparam[tgt].nvrm_period =
7973 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
7974 		/*
7975 		 * We probably shouldn't lie about this, but it
7976 		 * it makes it much safer if we limit NVRAM values
7977 		 * to sanity.
7978 		 */
7979 		if (isp->isp_type < ISP_HA_SCSI_1040) {
7980 			/*
7981 			 * If we're not ultra, we can't possibly
7982 			 * be a shorter period than this.
7983 			 */
7984 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
7985 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
7986 			}
7987 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
7988 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
7989 			}
7990 		} else {
7991 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
7992 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
7993 			}
7994 		}
7995 		sdp->isp_devparam[tgt].nvrm_flags = 0;
7996 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
7997 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
7998 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
7999 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
8000 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8001 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
8002 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8003 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
8004 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8005 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
8006 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8007 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
8008 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8009 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
8010 		sdp->isp_devparam[tgt].goal_offset =
8011 		    sdp->isp_devparam[tgt].nvrm_offset;
8012 		sdp->isp_devparam[tgt].goal_period =
8013 		    sdp->isp_devparam[tgt].nvrm_period;
8014 		sdp->isp_devparam[tgt].goal_flags =
8015 		    sdp->isp_devparam[tgt].nvrm_flags;
8016 	}
8017 }
8018 
8019 static void
8020 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8021 {
8022 	sdparam *sdp = SDPARAM(isp, bus);
8023 	int tgt;
8024 
8025 	sdp->isp_fifo_threshold =
8026 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8027 
8028 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8029 		sdp->isp_initiator_id =
8030 		    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8031 
8032 	sdp->isp_bus_reset_delay =
8033 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8034 
8035 	sdp->isp_retry_count =
8036 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8037 
8038 	sdp->isp_retry_delay =
8039 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8040 
8041 	sdp->isp_async_data_setup =
8042 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8043 
8044 	sdp->isp_req_ack_active_neg =
8045 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8046 
8047 	sdp->isp_data_line_active_neg =
8048 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8049 
8050 	sdp->isp_data_dma_burst_enabl =
8051 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8052 
8053 	sdp->isp_cmd_dma_burst_enable =
8054 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8055 
8056 	sdp->isp_selection_timeout =
8057 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8058 
8059 	sdp->isp_max_queue_depth =
8060 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8061 
8062 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8063 		sdp->isp_devparam[tgt].dev_enable =
8064 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8065 		sdp->isp_devparam[tgt].exc_throttle =
8066 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8067 		sdp->isp_devparam[tgt].nvrm_offset =
8068 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8069 		sdp->isp_devparam[tgt].nvrm_period =
8070 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8071 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8072 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8073 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8074 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8075 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8076 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8077 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8078 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8079 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8080 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8081 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8082 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8083 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8084 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8085 		sdp->isp_devparam[tgt].actv_flags = 0;
8086 		sdp->isp_devparam[tgt].goal_offset =
8087 		    sdp->isp_devparam[tgt].nvrm_offset;
8088 		sdp->isp_devparam[tgt].goal_period =
8089 		    sdp->isp_devparam[tgt].nvrm_period;
8090 		sdp->isp_devparam[tgt].goal_flags =
8091 		    sdp->isp_devparam[tgt].nvrm_flags;
8092 	}
8093 }
8094 
8095 static void
8096 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8097 {
8098 	sdparam *sdp = SDPARAM(isp, bus);
8099 	int tgt;
8100 
8101 	sdp->isp_fifo_threshold =
8102 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8103 
8104 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8105 		sdp->isp_initiator_id =
8106 		    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8107 
8108 	sdp->isp_bus_reset_delay =
8109 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8110 
8111 	sdp->isp_retry_count =
8112 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8113 
8114 	sdp->isp_retry_delay =
8115 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8116 
8117 	sdp->isp_async_data_setup =
8118 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8119 
8120 	sdp->isp_req_ack_active_neg =
8121 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8122 
8123 	sdp->isp_data_line_active_neg =
8124 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8125 
8126 	sdp->isp_data_dma_burst_enabl =
8127 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8128 
8129 	sdp->isp_cmd_dma_burst_enable =
8130 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8131 
8132 	sdp->isp_selection_timeout =
8133 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8134 
8135 	sdp->isp_max_queue_depth =
8136 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8137 
8138 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8139 		sdp->isp_devparam[tgt].dev_enable =
8140 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8141 		sdp->isp_devparam[tgt].exc_throttle =
8142 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8143 		sdp->isp_devparam[tgt].nvrm_offset =
8144 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8145 		sdp->isp_devparam[tgt].nvrm_period =
8146 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8147 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8148 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8149 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8150 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8151 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8152 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8153 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8154 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8155 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8156 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8157 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8158 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8159 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8160 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8161 		sdp->isp_devparam[tgt].actv_flags = 0;
8162 		sdp->isp_devparam[tgt].goal_offset =
8163 		    sdp->isp_devparam[tgt].nvrm_offset;
8164 		sdp->isp_devparam[tgt].goal_period =
8165 		    sdp->isp_devparam[tgt].nvrm_period;
8166 		sdp->isp_devparam[tgt].goal_flags =
8167 		    sdp->isp_devparam[tgt].nvrm_flags;
8168 	}
8169 }
8170 
8171 static void
8172 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8173 {
8174 	fcparam *fcp = FCPARAM(isp, 0);
8175 	uint64_t wwn;
8176 
8177 	/*
8178 	 * There is NVRAM storage for both Port and Node entities-
8179 	 * but the Node entity appears to be unused on all the cards
8180 	 * I can find. However, we should account for this being set
8181 	 * at some point in the future.
8182 	 *
8183 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8184 	 * bits 48..60. In the case of the 2202, it appears that they do
8185 	 * use bit 48 to distinguish between the two instances on the card.
8186 	 * The 2204, which I've never seen, *probably* extends this method.
8187 	 */
8188 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8189 	if (wwn) {
8190 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8191 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8192 		if ((wwn >> 60) == 0) {
8193 			wwn |= (((uint64_t) 2)<< 60);
8194 		}
8195 	}
8196 	fcp->isp_wwpn_nvram = wwn;
8197 	if (IS_2200(isp) || IS_23XX(isp)) {
8198 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8199 		if (wwn) {
8200 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8201 			    (uint32_t) (wwn >> 32),
8202 			    (uint32_t) (wwn));
8203 			if ((wwn >> 60) == 0) {
8204 				wwn |= (((uint64_t) 2)<< 60);
8205 			}
8206 		} else {
8207 			wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8208 		}
8209 	} else {
8210 		wwn &= ~((uint64_t) 0xfff << 48);
8211 	}
8212 	fcp->isp_wwnn_nvram = wwn;
8213 
8214 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8215 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8216 		DEFAULT_FRAMESIZE(isp) =
8217 		    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8218 	}
8219 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8220 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8221 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8222 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8223 	}
8224 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8225 		DEFAULT_EXEC_THROTTLE(isp) =
8226 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8227 	}
8228 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8229 	isp_prt(isp, ISP_LOGDEBUG0,
8230 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8231 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8232 	    (uint32_t) fcp->isp_wwnn_nvram,
8233 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8234 	    (uint32_t) fcp->isp_wwpn_nvram,
8235 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8236 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8237 	isp_prt(isp, ISP_LOGDEBUG0,
8238 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8239 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8240 	    ISP2100_NVRAM_OPTIONS(nvram_data),
8241 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
8242 	    ISP2100_NVRAM_TOV(nvram_data));
8243 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8244 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8245 	isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
8246 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8247 }
8248 
8249 static void
8250 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8251 {
8252 	fcparam *fcp = FCPARAM(isp, 0);
8253 	uint64_t wwn;
8254 
8255 	isp_prt(isp, ISP_LOGDEBUG0,
8256 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8257 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8258 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8259 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8260 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8261 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8262 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8263 	isp_prt(isp, ISP_LOGDEBUG0,
8264 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8265 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8266 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
8267 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8268 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8269 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8270 
8271 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8272 	fcp->isp_wwpn_nvram = wwn;
8273 
8274 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8275 	if (wwn) {
8276 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8277 			wwn = 0;
8278 		}
8279 	}
8280 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8281 		wwn = fcp->isp_wwpn_nvram;
8282 		wwn &= ~((uint64_t) 0xfff << 48);
8283 	}
8284 	fcp->isp_wwnn_nvram = wwn;
8285 
8286 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8287 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8288 	}
8289 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8290 		DEFAULT_FRAMESIZE(isp) =
8291 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8292 	}
8293 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8294 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8295 	}
8296 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8297 		DEFAULT_EXEC_THROTTLE(isp) =
8298 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8299 	}
8300 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8301 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8302 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8303 }
8304