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