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