xref: /freebsd/sys/dev/isp/isp.c (revision 7899f917b1c0ea178f1d2be0cfb452086d079d23)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  *  Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5  *  Copyright (c) 1997-2009 by Matthew Jacob
6  *  All rights reserved.
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *
18  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  *  SUCH DAMAGE.
29  *
30  */
31 
32 /*
33  * Machine and OS Independent (well, as best as possible)
34  * code for the Qlogic ISP SCSI and FC-SCSI adapters.
35  */
36 
37 /*
38  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
39  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
40  * ideas dredged from the Solaris driver.
41  */
42 
43 /*
44  * Include header file appropriate for platform we're building on.
45  */
46 #ifdef	__NetBSD__
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD$");
49 #include <dev/ic/isp_netbsd.h>
50 #endif
51 #ifdef	__FreeBSD__
52 #include <sys/param.h>
53 #include <sys/cdefs.h>
54 #include <sys/firmware.h>
55 #include <dev/isp/isp_freebsd.h>
56 #endif
57 #ifdef	__OpenBSD__
58 #include <dev/ic/isp_openbsd.h>
59 #endif
60 #ifdef	__linux__
61 #include "isp_linux.h"
62 #endif
63 #ifdef	__svr4__
64 #include "isp_solaris.h"
65 #endif
66 
67 /*
68  * Local static data
69  */
70 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
71 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
72 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
73 static const char sacq[] = "unable to acquire scratch area";
74 
75 static const uint8_t alpa_map[] = {
76 	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
77 	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
78 	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
79 	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
80 	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
81 	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
82 	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
83 	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
84 	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
85 	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
86 	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
87 	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
88 	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
89 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
90 	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
91 	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
92 };
93 
94 /*
95  * Local function prototypes.
96  */
97 static int isp_handle_control(ispsoftc_t *, isphdr_t *);
98 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *);
99 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *);
100 static void isp_clear_portdb(ispsoftc_t *, int);
101 static void isp_mark_portdb(ispsoftc_t *, int);
102 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
103 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
104 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
105 static void isp_dump_chip_portdb(ispsoftc_t *, int);
106 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
107 static int isp_fclink_test(ispsoftc_t *, int, int);
108 static int isp_pdb_sync(ispsoftc_t *, int);
109 static int isp_scan_loop(ispsoftc_t *, int);
110 static int isp_gid_pt(ispsoftc_t *, int);
111 static int isp_scan_fabric(ispsoftc_t *, int);
112 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
113 static int isp_register_fc4_type(ispsoftc_t *, int);
114 static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
115 static int isp_register_port_name_24xx(ispsoftc_t *, int);
116 static int isp_register_node_name_24xx(ispsoftc_t *, int);
117 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
118 static int isp_fw_state(ispsoftc_t *, int);
119 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
120 
121 static void isp_get_flash_addrs(ispsoftc_t *);
122 static void isp_setdfltfcparm(ispsoftc_t *, int);
123 static int isp_read_flash_dword(ispsoftc_t *, uint32_t, uint32_t *);
124 static int isp_read_flash_data(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
125 static void isp_rd_2xxx_flash(ispsoftc_t *, uint32_t, uint32_t *);
126 static int isp_read_flthdr_2xxx(ispsoftc_t *);
127 static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *);
128 static int isp_read_flt_2xxx(ispsoftc_t *);
129 static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *);
130 static int isp_read_nvram(ispsoftc_t *);
131 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
132 
133 static void isp_print_image(ispsoftc_t *, char *, struct isp_image_status *);
134 static bool isp_check_aux_image_status_signature(struct isp_image_status *);
135 static bool isp_check_image_status_signature(struct isp_image_status *);
136 static unsigned long isp_image_status_checksum(struct isp_image_status *);
137 static void isp_component_status(struct active_regions *, struct isp_image_status *);
138 static int isp_compare_image_generation(ispsoftc_t *, struct isp_image_status *, struct isp_image_status *);
139 static void isp_get_aux_images(ispsoftc_t *, struct active_regions *);
140 static void isp_get_active_image(ispsoftc_t *, struct active_regions *);
141 static bool isp_risc_firmware_invalid(ispsoftc_t *, uint32_t *);
142 static int isp_load_ram(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
143 static int isp_load_risc_flash(ispsoftc_t *, uint32_t *, uint32_t);
144 static int isp_load_risc(ispsoftc_t *, uint32_t *);
145 
146 static void
147 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
148 {
149 	fcparam *fcp = FCPARAM(isp, chan);
150 
151 	if (fcp->isp_fwstate == state)
152 		return;
153 	isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG,
154 	    "Chan %d Firmware state <%s->%s>", chan,
155 	    isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state));
156 	fcp->isp_fwstate = state;
157 }
158 
159 static void
160 isp_get_flash_addrs(ispsoftc_t *isp)
161 {
162 	fcparam *fcp = FCPARAM(isp, 0);
163 	int r = 0;
164 
165 	if (IS_28XX(isp)) {
166 		fcp->flash_data_addr = ISP28XX_BASE_ADDR;
167 		fcp->flt_region_flt = ISP28XX_FLT_ADDR;
168 	} else if (IS_26XX(isp)) {	/* 26xx and 27xx are identical */
169 		fcp->flash_data_addr = ISP27XX_BASE_ADDR;
170 		fcp->flt_region_flt = ISP27XX_FLT_ADDR;
171 	} else if (IS_25XX(isp)) {
172 		fcp->flash_data_addr = ISP25XX_BASE_ADDR;
173 		fcp->flt_region_flt = ISP25XX_FLT_ADDR;
174 	} else {
175 		fcp->flash_data_addr = ISP24XX_BASE_ADDR;
176 		fcp->flt_region_flt = ISP24XX_FLT_ADDR;
177 	}
178 	fcp->flt_length = 0;
179 	r = isp_read_flthdr_2xxx(isp);
180 	if (r == 0) {
181 		isp_read_flt_2xxx(isp);
182 	} else { /* fallback to hardcoded NVRAM address */
183 		if (IS_28XX(isp)) {
184 			fcp->flt_region_nvram = 0x300000;
185 		} else if (IS_26XX(isp)) {
186 			fcp->flash_data_addr = 0x7fe7c000;
187 			fcp->flt_region_nvram = 0;
188 		} else if (IS_25XX(isp)) {
189 			fcp->flt_region_nvram = 0x48000;
190 		} else {
191 			fcp->flash_data_addr = 0x7ffe0000;
192 			fcp->flt_region_nvram = 0;
193 		}
194 		fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
195 	}
196 }
197 
198 /*
199  * Reset Hardware.
200  *
201  * Hit the chip over the head, download new f/w if available and set it running.
202  *
203  * Locking done elsewhere.
204  */
205 
206 void
207 isp_reset(ispsoftc_t *isp, int do_load_defaults)
208 {
209 	mbreg_t mbs;
210 	char *buf;
211 	uint16_t fwt;
212 	uint32_t code_org, val;
213 	int loaded_fw, loops, i, dodnld = 1;
214 	const char *btype = "????";
215 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
216 
217 	isp->isp_state = ISP_NILSTATE;
218 	ISP_DISABLE_INTS(isp);
219 
220 	/*
221 	 * Put the board into PAUSE mode (so we can read the SXP registers
222 	 * or write FPM/FBM registers).
223 	 */
224 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
225 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
226 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
227 
228 	switch (isp->isp_type) {
229 	case ISP_HA_FC_2400:
230 		btype = "2422";
231 		break;
232 	case ISP_HA_FC_2500:
233 		btype = "2532";
234 		break;
235 	case ISP_HA_FC_2600:
236 		btype = "2600";
237 		break;
238 	case ISP_HA_FC_2700:
239 		btype = "2700";
240 		break;
241 	case ISP_HA_FC_2800:
242 		btype = "2800";
243 		break;
244 	default:
245 		break;
246 	}
247 
248 	/*
249 	 * Stop DMA and wait for it to stop.
250 	 */
251 	ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
252 	for (loops = 0; loops < 100000; loops++) {
253 		ISP_DELAY(10);
254 		val = ISP_READ(isp, BIU2400_CSR);
255 		if ((val & BIU2400_DMA_ACTIVE) == 0) {
256 			break;
257 		}
258 	}
259 	if (val & BIU2400_DMA_ACTIVE)
260 		isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
261 
262 	/*
263 	 * Hold it in SOFT_RESET and STOP state for 100us.
264 	 */
265 	ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
266 	ISP_DELAY(100);
267 	for (loops = 0; loops < 10000; loops++) {
268 		ISP_DELAY(5);
269 		val = ISP_READ(isp, OUTMAILBOX0);
270 		if (val != 0x4)
271 			break;
272 	}
273 	switch (val) {
274 	case 0x0:
275 		break;
276 	case 0x4:
277 		isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
278 		return;
279 	case 0xf:
280 		isp_prt(isp, ISP_LOGERR, "Board configuration error.");
281 		return;
282 	default:
283 		isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
284 		return;
285 	}
286 
287 	/*
288 	 * Reset RISC Processor
289 	 */
290 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
291 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
292 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
293 
294 	/*
295 	 * Post-RISC Reset stuff.
296 	 */
297 	for (loops = 0; loops < 10000; loops++) {
298 		ISP_DELAY(5);
299 		val = ISP_READ(isp, OUTMAILBOX0);
300 		if (val != 0x4)
301 			break;
302 	}
303 	switch (val) {
304 	case 0x0:
305 		break;
306 	case 0x4:
307 		isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
308 		return;
309 	case 0xf:
310 		isp_prt(isp, ISP_LOGERR, "Board configuration error.");
311 		return;
312 	default:
313 		isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
314 		return;
315 	}
316 
317 	isp->isp_reqidx = isp->isp_reqodx = 0;
318 	isp->isp_resodx = 0;
319 	isp->isp_atioodx = 0;
320 	ISP_WRITE(isp, BIU2400_REQINP, 0);
321 	ISP_WRITE(isp, BIU2400_REQOUTP, 0);
322 	ISP_WRITE(isp, BIU2400_RSPINP, 0);
323 	ISP_WRITE(isp, BIU2400_RSPOUTP, 0);
324 	if (!IS_26XX(isp)) {
325 		ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
326 		ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
327 	}
328 	ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
329 	ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
330 
331 	/*
332 	 * Up until this point we've done everything by just reading or
333 	 * setting registers. From this point on we rely on at least *some*
334 	 * kind of firmware running in the card.
335 	 */
336 
337 	/*
338 	 * Do some sanity checking by running a NOP command.
339 	 * If it succeeds, the ROM firmware is now running.
340 	 */
341 	MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0);
342 	isp_mboxcmd(isp, &mbs);
343 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
344 		isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
345 		return;
346 	}
347 
348 	/*
349 	 * Do some operational tests
350 	 */
351 	{
352 		static const uint16_t patterns[MAX_MAILBOX] = {
353 			0x0000, 0xdead, 0xbeef, 0xffff,
354 			0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7,
355 			0x3421, 0xabcd, 0xdcba, 0xfeef,
356 			0xbead, 0xdebe, 0x2222, 0x3333,
357 			0x5555, 0x6666, 0x7777, 0xaaaa,
358 			0xffff, 0xdddd, 0x9999, 0x1fbc,
359 			0x6666, 0x6677, 0x1122, 0x33ff,
360 			0x0000, 0x0001, 0x1000, 0x1010,
361 		};
362 		int nmbox = ISP_NMBOX(isp);
363 		MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
364 		for (i = 1; i < nmbox; i++) {
365 			mbs.param[i] = patterns[i];
366 		}
367 		isp_mboxcmd(isp, &mbs);
368 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
369 			return;
370 		}
371 		for (i = 1; i < nmbox; i++) {
372 			if (mbs.param[i] != patterns[i]) {
373 				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]);
374 				return;
375 			}
376 		}
377 	}
378 
379 	/*
380 	 * Early setup DMA for the request and response queues.
381 	 * We do this now so we can use the request queue
382 	 * for dma to load firmware from.
383 	 */
384 
385 	if (ISP_MBOXDMASETUP(isp) != 0) {
386 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
387 		return;
388 	}
389 
390 	/*
391 	 * FW load priority
392 	 * For 27xx and newer:
393 	 * Load ispfw(4) firmware unless requested not to do so.
394 	 * Request (active) flash firmware information. Compare
395 	 * version numbers of ispfw(4) and flash firmware. Load
396 	 * the highest version into RAM of the adapter.
397 	 * If loading ispfw(4) is disabled or loading it failed
398 	 * (eg. no firmware available) we just load firmware from
399 	 * flash. If this fails for whatever reason we fallback
400 	 * to let the adapter MBOX_LOAD_FLASH_FIRMWARE by itself
401 	 * followed by MBOX_EXEC_FIRMWARE and hope the best to
402 	 * get it up and running.
403 	 *
404 	 * For 26xx and older:
405 	 * Load ispfw(4) firmware unless requested not to do so
406 	 * and load it into RAM of the adapter. If loading
407 	 * ispfw(4) is disabled or loading it failed (eg. no
408 	 * firmware available) we just let the adapter
409 	 * MBOX_EXEC_FIRMWARE to start the flash firmware.
410 	 * For the 26xx a preceding MBOX_LOAD_FLASH_FIRMWARE
411 	 * is required.
412 	 */
413 
414 	fcparam *fcp = FCPARAM(isp, 0);
415 
416 	/* read FLT to get flash region addresses */
417 	isp_get_flash_addrs(isp);
418 
419 	/* set informational sysctl(8) to sane value */
420 	snprintf(fcp->fw_version_ispfw, sizeof(fcp->fw_version_ispfw),
421 	    "not loaded");
422 	snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
423 	    "not loaded");
424 	snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
425 	    "not loaded");
426 
427 
428 	/* Try to load ispfw(4) first */
429 	if (!(isp->isp_confopts & ISP_CFG_NORELOAD)) {
430 		char fwname[32];
431 		snprintf(fwname, sizeof(fwname), "isp_%04x", isp->isp_did);
432 		isp->isp_osinfo.ispfw = firmware_get(fwname);
433 		if (isp->isp_osinfo.ispfw != NULL) {
434 			isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.ispfw->data;
435 			const uint32_t *ispfwptr = isp->isp_mdvec->dv_ispfw;
436 			for (i = 0; i < 4; i++)
437 				fcp->fw_ispfwrev[i] = ispfwptr[4 + i];
438 			isp_prt(isp, ISP_LOGCONFIG,
439 			    "Loaded ispfw(4) firmware %s", fwname);
440 			snprintf(fcp->fw_version_ispfw,
441 			    sizeof(fcp->fw_version_ispfw),
442 			    "%u.%u.%u", fcp->fw_ispfwrev[0],
443 			    fcp->fw_ispfwrev[1], fcp->fw_ispfwrev[2]);
444 			isp_prt(isp, ISP_LOGCONFIG,
445 			    "Firmware revision (ispfw) %u.%u.%u (%x).",
446 			    fcp->fw_ispfwrev[0], fcp->fw_ispfwrev[1],
447 			    fcp->fw_ispfwrev[2], fcp->fw_ispfwrev[3]);
448 		} else {
449 			isp_prt(isp, ISP_LOGDEBUG0,
450 			    "Unable to load ispfw(4) firmware %s", fwname);
451 		}
452 	}
453 
454 	loaded_fw = 0;
455 	dodnld = 0;
456 
457 	if (IS_27XX(isp)) {
458 		switch (isp_load_risc(isp, 0)) {
459 		case ISP_ABORTED:
460 			/*
461 			 * download ispfw(4) as it's newer than flash, or
462 			 * the user requested it.
463 			 */
464 			dodnld = 1;
465 			break;
466 		case ISP_SUCCESS:
467 			/* We've loaded flash firmware */
468 			loaded_fw = 1;
469 			break;
470 		default:
471 			/*
472 			 * Fall through to use ispfw(4) if available or
473 			 * just fall back to use MBOX_LOAD_FLASH_FIRMWARE
474 			 */
475 			if (isp->isp_osinfo.ispfw != NULL)
476 				dodnld = 1;
477 			break;
478 		}
479 	} else {
480 		/* Fall through to load ispfw(4) or simply MBOX_EXEC_FIRMWARE */
481 		if (isp->isp_osinfo.ispfw != NULL)
482 			dodnld = 1;
483 	}
484 
485 	code_org = ISP_CODE_ORG_2400;
486 	if (dodnld) {
487 		const uint32_t *ptr = isp->isp_mdvec->dv_ispfw;
488 		uint32_t la, wi, wl;
489 
490 		/* Keep loading until we run out of f/w. */
491 		code_org = ptr[2];	/* 1st load address is our start addr */
492 		for (;;) {
493 			isp_prt(isp, ISP_LOGDEBUG2,
494 			    "Load 0x%x words of code at load address 0x%x",
495 			    ptr[3], ptr[2]);
496 
497 			wi = 0;
498 			la = ptr[2];
499 			wl = ptr[3];
500 			while (wi < ptr[3]) {
501 				uint32_t *cp;
502 				uint32_t nw;
503 
504 				nw = min(wl, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
505 				cp = isp->isp_rquest;
506 				for (i = 0; i < nw; i++)
507 					ISP_IOXPUT_32(isp, ptr[wi + i], &cp[i]);
508 				if (isp_load_ram(isp, cp, la, nw) != 0) {
509 					isp_prt(isp, ISP_LOGERR,
510 					    "Failed to load firmware fragment.");
511 					return;
512 				}
513 				la += nw;
514 				wi += nw;
515 				wl -= nw;
516 			}
517 
518 			if (ptr[1] == 0) {
519 				break;
520 			}
521 			ptr += ptr[3];
522 		}
523 		loaded_fw = 1;
524 		/* Drop reference to ispfw(4) firmware */
525 		if (isp->isp_osinfo.ispfw != NULL)
526 			firmware_put(isp->isp_osinfo.ispfw, FIRMWARE_UNLOAD);
527 	} else {
528 		isp_prt(isp, ISP_LOGCONFIG,
529 		    "Skipping ispfw(4) firmware download");
530 	}
531 
532 	/* If we loaded firmware, verify its checksum. */
533 	if (loaded_fw) {
534 		MBSINIT(&mbs, MBOX_VERIFY_CHECKSUM, MBLOGNONE, 0);
535 		mbs.param[1] = code_org >> 16;
536 		mbs.param[2] = code_org;
537 		isp_mboxcmd(isp, &mbs);
538 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
539 			isp_prt(isp, ISP_LOGERR, "%s: 0x%x", dcrc,
540 			    (mbs.param[2] << 16 | mbs.param[1]));
541 			return;
542 		}
543 	} else if (IS_26XX(isp)) {
544 		isp_prt(isp, ISP_LOGCONFIG,
545 		    "Instruct RISC to load firmware from flash by itself");
546 		MBSINIT(&mbs, MBOX_LOAD_FLASH_FIRMWARE, MBLOGALL, 5000000);
547 		isp_mboxcmd(isp, &mbs);
548 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
549 			isp_prt(isp, ISP_LOGERR, "Flash F/W load failed");
550 			return;
551 		}
552 	}
553 
554 	/*
555 	 * Now start it rolling.
556 	 *
557 	 * If we didn't actually download f/w,
558 	 * we still need to (re)start it.
559 	 */
560 	MBSINIT(&mbs, MBOX_EXEC_FIRMWARE, MBLOGALL, 5000000);
561 	mbs.param[1] = code_org >> 16;
562 	mbs.param[2] = code_org;
563 	if (!IS_26XX(isp))
564 		mbs.param[3] = loaded_fw ? 0 : 1;
565 	mbs.param[4] = 0;
566 	if (IS_27XX(isp))
567 		mbs.param[4] |= 0x08;	/* NVME_ENABLE_FLAG */
568 	mbs.param[11] = 0;
569 	isp_mboxcmd(isp, &mbs);
570 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
571 		return;
572 	fcp->fw_ability_mask = (mbs.param[3] << 16) | mbs.param[2];
573 	isp_prt(isp, ISP_LOGDEBUG0, "Firmware ability mask: 0x%x",
574 	    fcp->fw_ability_mask);
575 	if (IS_26XX(isp)) {
576 		fcp->max_supported_speed = mbs.param[2] & (0x1 | 0x2);
577 		isp_prt(isp, ISP_LOGINFO, "Maximum supported speed: %s",
578 		    fcp->max_supported_speed == 0 ? "16Gbit/s" :
579 		    fcp->max_supported_speed == 1 ? "32Gbit/s" :
580 		    fcp->max_supported_speed == 2 ? "64Gbit/s" : "unknown");
581 	}
582 	if (IS_28XX(isp) && (mbs.param[5] & 0x400)) {
583 		isp_prt(isp, ISP_LOGINFO,
584 		    "HW supports EDIF (Encryption of data in flight)");
585 	}
586 
587 	/*
588 	 * Ask the chip for the current firmware version.
589 	 * This should prove that the new firmware is working.
590 	 */
591 	MBSINIT(&mbs, MBOX_ABOUT_FIRMWARE, MBLOGALL, 5000000);
592 	isp_mboxcmd(isp, &mbs);
593 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
594 		return;
595 	}
596 
597 	isp->isp_fwrev[0] = mbs.param[1];
598 	isp->isp_fwrev[1] = mbs.param[2];
599 	isp->isp_fwrev[2] = mbs.param[3];
600 	isp->isp_fwattr = mbs.param[6];
601 	isp->isp_fwattr_h = mbs.param[15];
602 	if (isp->isp_fwattr & ISP_FW_ATTR_EXTNDED) {
603 		isp->isp_fwattr_ext[0] = mbs.param[16];
604 		isp->isp_fwattr_ext[1] = mbs.param[17];
605 	}
606 
607 	isp_prt(isp, ISP_LOGCONFIG, "Board Type %s, Chip Revision 0x%x, %s F/W Revision %d.%d.%d",
608 	    btype, isp->isp_revision, dodnld ? "loaded" : "resident",
609 	    isp->isp_fwrev[0], isp->isp_fwrev[1], isp->isp_fwrev[2]);
610 	snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
611 	    "%u.%u.%u", isp->isp_fwrev[0], isp->isp_fwrev[1],
612 	    isp->isp_fwrev[2]);
613 	if (!dodnld && !IS_26XX(isp))
614 		snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
615 		    "%s", fcp->fw_version_run);
616 
617 	fwt = isp->isp_fwattr;
618 	buf = FCPARAM(isp, 0)->isp_scanscratch;
619 	ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Attributes Lower:");
620 	if (fwt & ISP_FW_ATTR_CLASS2) {
621 		fwt ^= ISP_FW_ATTR_CLASS2;
622 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s Class2", buf);
623 	}
624 	if (fwt & ISP_FW_ATTR_IP) {
625 		fwt ^= ISP_FW_ATTR_IP;
626 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s IP", buf);
627 	}
628 	if (fwt & ISP_FW_ATTR_MULTIID) {
629 		fwt ^= ISP_FW_ATTR_MULTIID;
630 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MultiID", buf);
631 	}
632 	if (fwt & ISP_FW_ATTR_SB2) {
633 		fwt ^= ISP_FW_ATTR_SB2;
634 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SB2", buf);
635 	}
636 	if (fwt & ISP_FW_ATTR_T10CRC) {
637 		fwt ^= ISP_FW_ATTR_T10CRC;
638 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s T10CRC", buf);
639 	}
640 	if (fwt & ISP_FW_ATTR_VI) {
641 		fwt ^= ISP_FW_ATTR_VI;
642 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VI", buf);
643 	}
644 	if (fwt & ISP_FW_ATTR_MQ) {
645 		fwt ^= ISP_FW_ATTR_MQ;
646 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MQ", buf);
647 	}
648 	if (fwt & ISP_FW_ATTR_MSIX) {
649 		fwt ^= ISP_FW_ATTR_MSIX;
650 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s MSIX", buf);
651 	}
652 	if (fwt & ISP_FW_ATTR_FCOE) {
653 		fwt ^= ISP_FW_ATTR_FCOE;
654 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s FCOE", buf);
655 	}
656 	if (fwt & ISP_FW_ATTR_VP0) {
657 		fwt ^= ISP_FW_ATTR_VP0;
658 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VP0_Decoupling", buf);
659 	}
660 	if (fwt & ISP_FW_ATTR_EXPFW) {
661 		fwt ^= ISP_FW_ATTR_EXPFW;
662 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s (Experimental)", buf);
663 	}
664 	if (fwt & ISP_FW_ATTR_HOTFW) {
665 		fwt ^= ISP_FW_ATTR_HOTFW;
666 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s HotFW", buf);
667 	}
668 	fwt &= ~ISP_FW_ATTR_EXTNDED;
669 	if (fwt) {
670 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
671 		    "%s (unknown 0x%04x)", buf, fwt);
672 	}
673 	isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
674 
675 	fwt = isp->isp_fwattr_h;
676 	buf = FCPARAM(isp, 0)->isp_scanscratch;
677 	ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Attributes Upper:");
678 	if (fwt & ISP_FW_ATTR_H_EXTVP) {
679 		fwt ^= ISP_FW_ATTR_H_EXTVP;
680 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ExtVP", buf);
681 	}
682 	if (fwt & ISP_FW_ATTR_H_VN2VN) {
683 		fwt ^= ISP_FW_ATTR_H_VN2VN;
684 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s VN2VN", buf);
685 	}
686 	if (fwt & ISP_FW_ATTR_H_EXMOFF) {
687 		fwt ^= ISP_FW_ATTR_H_EXMOFF;
688 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EXMOFF", buf);
689 	}
690 	if (fwt & ISP_FW_ATTR_H_NPMOFF) {
691 		fwt ^= ISP_FW_ATTR_H_NPMOFF;
692 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NPMOFF", buf);
693 	}
694 	if (fwt & ISP_FW_ATTR_H_DIFCHOP) {
695 		fwt ^= ISP_FW_ATTR_H_DIFCHOP;
696 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s DIFCHOP", buf);
697 	}
698 	if (fwt & ISP_FW_ATTR_H_SRIOV) {
699 		fwt ^= ISP_FW_ATTR_H_SRIOV;
700 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SRIOV", buf);
701 	}
702 	if (fwt & ISP_FW_ATTR_H_NVME) {
703 		fwt ^= ISP_FW_ATTR_H_NVME;
704 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe", buf);
705 	}
706 	if (fwt & ISP_FW_ATTR_H_NVME_UP) {
707 		fwt ^= ISP_FW_ATTR_H_NVME_UP;
708 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(updated)", buf);
709 	}
710 	if (fwt & (ISP_FW_ATTR_H_NVME_FB)) {
711 		fwt ^= (ISP_FW_ATTR_H_NVME_FB);
712 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe(first burst)", buf);
713 	}
714 	if (fwt) {
715 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
716 		    "%s (unknown 0x%04x)", buf, fwt);
717 	}
718 	isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
719 
720 	fwt = isp->isp_fwattr_ext[0];
721 	buf = FCPARAM(isp, 0)->isp_scanscratch;
722 	ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Ext. Attributes Lower:");
723 	if (fwt & ISP_FW_ATTR_E0_ASICTMP) {
724 		fwt ^= ISP_FW_ATTR_E0_ASICTMP;
725 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ASICTMP", buf);
726 	}
727 	if (fwt & ISP_FW_ATTR_E0_ATIOMQ) {
728 		fwt ^= ISP_FW_ATTR_E0_ATIOMQ;
729 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s ATIOMQ", buf);
730 	}
731 	if (fwt & ISP_FW_ATTR_E0_EDIF) {
732 		fwt ^= ISP_FW_ATTR_E0_EDIF;
733 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s EDIF", buf);
734 	}
735 	if (fwt & ISP_FW_ATTR_E0_SCM) {
736 		fwt ^= ISP_FW_ATTR_E0_SCM;
737 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s SCM", buf);
738 	}
739 	if (fwt & ISP_FW_ATTR_E0_NVME2) {
740 		fwt ^= ISP_FW_ATTR_E0_NVME2;
741 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf), "%s NVMe-2", buf);
742 	}
743 	if (fwt) {
744 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
745 		    "%s (unknown 0x%04x)", buf, fwt);
746 	}
747 	isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
748 
749 	fwt = isp->isp_fwattr_ext[1];
750 	buf = FCPARAM(isp, 0)->isp_scanscratch;
751 	ISP_SNPRINTF(buf, ISP_FC_SCRLEN, "FW Ext. Attributes Upper:");
752 	if (fwt) {
753 		ISP_SNPRINTF(buf, ISP_FC_SCRLEN - strlen(buf),
754 		    "%s (unknown 0x%04x)", buf, fwt);
755 	}
756 	isp_prt(isp, ISP_LOGCONFIG, "%s", buf);
757 
758 	/*
759 	 * For the maximum number of commands take free exchange control block
760 	 * buffer count reported by firmware, limiting it to the maximum of our
761 	 * hardcoded handle format (16K now) minus some management reserve.
762 	 */
763 	MBSINIT(&mbs, MBOX_GET_RESOURCE_COUNT, MBLOGALL, 0);
764 	isp_mboxcmd(isp, &mbs);
765 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
766 		return;
767 	isp->isp_maxcmds = MIN(mbs.param[3], ISP_HANDLE_MAX - ISP_HANDLE_RESERVE);
768 	isp_prt(isp, ISP_LOGCONFIG, "%d max I/O command limit set", isp->isp_maxcmds);
769 
770 	/*
771 	 * If we don't have Multi-ID f/w loaded, we need to restrict channels to one.
772 	 * Only make this check for non-SCSI cards (I'm not sure firmware attributes
773 	 * work for them).
774 	 */
775 	if (isp->isp_nchan > 1) {
776 		if (!ISP_CAP_MULTI_ID(isp)) {
777 			isp_prt(isp, ISP_LOGWARN, "non-MULTIID f/w loaded, "
778 			    "only can enable 1 of %d channels", isp->isp_nchan);
779 			isp->isp_nchan = 1;
780 		} else if (!ISP_CAP_VP0(isp)) {
781 			isp_prt(isp, ISP_LOGWARN, "We can not use MULTIID "
782 			    "feature properly without VP0_Decoupling");
783 			isp->isp_nchan = 1;
784 		}
785 	}
786 
787 	/*
788 	 * Final DMA setup after we got isp_maxcmds.
789 	 */
790 	if (ISP_MBOXDMASETUP(isp) != 0) {
791 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
792 		return;
793 	}
794 
795 	/*
796 	 * Setup interrupts.
797 	 */
798 	if (ISP_IRQSETUP(isp) != 0) {
799 		isp_prt(isp, ISP_LOGERR, "Cannot setup IRQ");
800 		return;
801 	}
802 	ISP_ENABLE_INTS(isp);
803 
804 	for (i = 0; i < isp->isp_nchan; i++)
805 		isp_change_fw_state(isp, i, FW_CONFIG_WAIT);
806 
807 	isp->isp_state = ISP_RESETSTATE;
808 
809 	/*
810 	 * We get some default values established. As a side
811 	 * effect, NVRAM is read here (unless overridden by
812 	 * a configuration flag).
813 	 */
814 	if (do_load_defaults) {
815 		for (i = 0; i < isp->isp_nchan; i++)
816 			isp_setdfltfcparm(isp, i);
817 	}
818 }
819 
820 /*
821  * Clean firmware shutdown.
822  */
823 static int
824 isp_stop(ispsoftc_t *isp)
825 {
826 	mbreg_t mbs;
827 
828 	isp->isp_state = ISP_NILSTATE;
829 	MBSINIT(&mbs, MBOX_STOP_FIRMWARE, MBLOGALL, 500000);
830 	mbs.param[1] = 0;
831 	mbs.param[2] = 0;
832 	mbs.param[3] = 0;
833 	mbs.param[4] = 0;
834 	mbs.param[5] = 0;
835 	mbs.param[6] = 0;
836 	mbs.param[7] = 0;
837 	mbs.param[8] = 0;
838 	isp_mboxcmd(isp, &mbs);
839 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : mbs.param[0]);
840 }
841 
842 /*
843  * Hardware shutdown.
844  */
845 void
846 isp_shutdown(ispsoftc_t *isp)
847 {
848 
849 	if (isp->isp_state >= ISP_RESETSTATE)
850 		isp_stop(isp);
851 	ISP_DISABLE_INTS(isp);
852 	ISP_WRITE(isp, BIU2400_ICR, 0);
853 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
854 }
855 
856 /*
857  * Initialize Parameters of Hardware to a known state.
858  *
859  * Locks are held before coming here.
860  */
861 void
862 isp_init(ispsoftc_t *isp)
863 {
864 	fcparam *fcp;
865 	isp_icb_2400_t local, *icbp = &local;
866 	mbreg_t mbs;
867 	int chan;
868 	int ownloopid = 0;
869 
870 	/*
871 	 * Check to see whether all channels have *some* kind of role
872 	 */
873 	for (chan = 0; chan < isp->isp_nchan; chan++) {
874 		fcp = FCPARAM(isp, chan);
875 		if (fcp->role != ISP_ROLE_NONE) {
876 			break;
877 		}
878 	}
879 	if (chan == isp->isp_nchan) {
880 		isp_prt(isp, ISP_LOG_WARN1, "all %d channels with role 'none'", chan);
881 		return;
882 	}
883 
884 	isp->isp_state = ISP_INITSTATE;
885 
886 	/*
887 	 * Start with channel 0.
888 	 */
889 	fcp = FCPARAM(isp, 0);
890 
891 	/*
892 	 * Turn on LIP F8 async event (1)
893 	 */
894 	MBSINIT(&mbs, MBOX_SET_FIRMWARE_OPTIONS, MBLOGALL, 0);
895 	mbs.param[1] = 1;
896 	isp_mboxcmd(isp, &mbs);
897 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
898 		return;
899 	}
900 
901 	ISP_MEMZERO(icbp, sizeof (*icbp));
902 	icbp->icb_fwoptions1 = fcp->isp_fwoptions;
903 	icbp->icb_fwoptions2 = fcp->isp_xfwoptions;
904 	icbp->icb_fwoptions3 = fcp->isp_zfwoptions;
905 	if (isp->isp_nchan > 1 && ISP_CAP_VP0(isp)) {
906 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
907 		icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
908 	} else {
909 		if (fcp->role & ISP_ROLE_TARGET)
910 			icbp->icb_fwoptions1 |= ICB2400_OPT1_TGT_ENABLE;
911 		else
912 			icbp->icb_fwoptions1 &= ~ICB2400_OPT1_TGT_ENABLE;
913 		if (fcp->role & ISP_ROLE_INITIATOR)
914 			icbp->icb_fwoptions1 &= ~ICB2400_OPT1_INI_DISABLE;
915 		else
916 			icbp->icb_fwoptions1 |= ICB2400_OPT1_INI_DISABLE;
917 	}
918 
919 	icbp->icb_version = ICB_VERSION1;
920 	icbp->icb_maxfrmlen = DEFAULT_FRAMESIZE(isp);
921 	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN || icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
922 		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
923 		if (IS_28XX(isp))
924 			icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN_28XX;
925 
926 		isp_prt(isp, ISP_LOGERR,
927 		    "bad frame length (%d) from NVRAM - using %d",
928 		    DEFAULT_FRAMESIZE(isp), icbp->icb_maxfrmlen);
929 	}
930 
931 	if (!IS_26XX(isp))
932 		icbp->icb_execthrottle = 0xffff;
933 
934 #ifdef	ISP_TARGET_MODE
935 	/*
936 	 * Set target exchange count. Take half if we are supporting both roles.
937 	 */
938 	if (icbp->icb_fwoptions1 & ICB2400_OPT1_TGT_ENABLE) {
939 		if ((icbp->icb_fwoptions1 & ICB2400_OPT1_INI_DISABLE) == 0)
940 			icbp->icb_xchgcnt = MIN(isp->isp_maxcmds / 2, ATPDPSIZE);
941 		else
942 			icbp->icb_xchgcnt = isp->isp_maxcmds;
943 	}
944 #endif
945 
946 	ownloopid = (isp->isp_confopts & ISP_CFG_OWNLOOPID) != 0;
947 	icbp->icb_hardaddr = fcp->isp_loopid;
948 	if (icbp->icb_hardaddr >= LOCAL_LOOP_LIM) {
949 		icbp->icb_hardaddr = 0;
950 		ownloopid = 0;
951 	}
952 
953 	if (ownloopid)
954 		icbp->icb_fwoptions1 |= ICB2400_OPT1_HARD_ADDRESS;
955 
956 	if (isp->isp_confopts & ISP_CFG_NOFCTAPE) {
957 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_FCTAPE;
958 	}
959 	if (isp->isp_confopts & ISP_CFG_FCTAPE) {
960 		icbp->icb_fwoptions2 |= ICB2400_OPT2_FCTAPE;
961 	}
962 
963 	for (chan = 0; chan < isp->isp_nchan; chan++) {
964 		if (icbp->icb_fwoptions2 & ICB2400_OPT2_FCTAPE)
965 			FCPARAM(isp, chan)->fctape_enabled = 1;
966 		else
967 			FCPARAM(isp, chan)->fctape_enabled = 0;
968 	}
969 
970 	switch (isp->isp_confopts & ISP_CFG_PORT_PREF) {
971 	case ISP_CFG_LPORT_ONLY:
972 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
973 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_ONLY;
974 		break;
975 	case ISP_CFG_NPORT_ONLY:
976 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
977 		icbp->icb_fwoptions2 |= ICB2400_OPT2_PTP_ONLY;
978 		break;
979 	case ISP_CFG_NPORT:
980 		/* ISP_CFG_PTP_2_LOOP not available in 24XX/25XX */
981 	case ISP_CFG_LPORT:
982 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
983 		icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
984 		break;
985 	default:
986 		/* Let NVRAM settings define it if they are sane */
987 		switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TOPO_MASK) {
988 		case ICB2400_OPT2_LOOP_ONLY:
989 		case ICB2400_OPT2_PTP_ONLY:
990 		case ICB2400_OPT2_LOOP_2_PTP:
991 			break;
992 		default:
993 			icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TOPO_MASK;
994 			icbp->icb_fwoptions2 |= ICB2400_OPT2_LOOP_2_PTP;
995 		}
996 		break;
997 	}
998 
999 	switch (icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK) {
1000 	case ICB2400_OPT2_ZIO:
1001 	case ICB2400_OPT2_ZIO1:
1002 		icbp->icb_idelaytimer = 0;
1003 		break;
1004 	case 0:
1005 		break;
1006 	default:
1007 		isp_prt(isp, ISP_LOGWARN, "bad value %x in fwopt2 timer field", icbp->icb_fwoptions2 & ICB2400_OPT2_TIMER_MASK);
1008 		icbp->icb_fwoptions2 &= ~ICB2400_OPT2_TIMER_MASK;
1009 		break;
1010 	}
1011 
1012 	if (IS_26XX(isp)) {
1013 		/* Use handshake to reduce global lock congestion. */
1014 		icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHR;
1015 		icbp->icb_fwoptions2 |= ICB2400_OPT2_ENA_IHA;
1016 	}
1017 
1018 	if ((icbp->icb_fwoptions3 & ICB2400_OPT3_RSPSZ_MASK) == 0) {
1019 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RSPSZ_24;
1020 	}
1021 	if (isp->isp_confopts & ISP_CFG_1GB) {
1022 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1023 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_1GB;
1024 	} else if (isp->isp_confopts & ISP_CFG_2GB) {
1025 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1026 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_2GB;
1027 	} else if (isp->isp_confopts & ISP_CFG_4GB) {
1028 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1029 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_4GB;
1030 	} else if (isp->isp_confopts & ISP_CFG_8GB) {
1031 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1032 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_8GB;
1033 	} else if (isp->isp_confopts & ISP_CFG_16GB) {
1034 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1035 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_16GB;
1036 	} else if (isp->isp_confopts & ISP_CFG_32GB) {
1037 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1038 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_32GB;
1039 	} else if (isp->isp_confopts & ISP_CFG_64GB) {
1040 		icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1041 		icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_64GB;
1042 	} else {
1043 		switch (icbp->icb_fwoptions3 & ICB2400_OPT3_RATE_MASK) {
1044 		case ICB2400_OPT3_RATE_4GB:
1045 		case ICB2400_OPT3_RATE_8GB:
1046 		case ICB2400_OPT3_RATE_16GB:
1047 		case ICB2400_OPT3_RATE_32GB:
1048 		case ICB2400_OPT3_RATE_64GB:
1049 		case ICB2400_OPT3_RATE_AUTO:
1050 			break;
1051 		case ICB2400_OPT3_RATE_2GB:
1052 			if (isp->isp_type <= ISP_HA_FC_2500)
1053 				break;
1054 			/*FALLTHROUGH*/
1055 		case ICB2400_OPT3_RATE_1GB:
1056 			if (isp->isp_type <= ISP_HA_FC_2400)
1057 				break;
1058 			/*FALLTHROUGH*/
1059 		default:
1060 			icbp->icb_fwoptions3 &= ~ICB2400_OPT3_RATE_MASK;
1061 			icbp->icb_fwoptions3 |= ICB2400_OPT3_RATE_AUTO;
1062 			break;
1063 		}
1064 	}
1065 	if (ownloopid == 0) {
1066 		icbp->icb_fwoptions3 |= ICB2400_OPT3_SOFTID;
1067 	}
1068 	icbp->icb_logintime = ICB_LOGIN_TOV;
1069 
1070 	if (fcp->isp_wwnn && fcp->isp_wwpn) {
1071 		icbp->icb_fwoptions1 |= ICB2400_OPT1_BOTH_WWNS;
1072 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1073 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_wwnn);
1074 		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)),
1075 		    ((uint32_t) (fcp->isp_wwpn >> 32)), ((uint32_t) (fcp->isp_wwpn)));
1076 	} else if (fcp->isp_wwpn) {
1077 		icbp->icb_fwoptions1 &= ~ICB2400_OPT1_BOTH_WWNS;
1078 		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_wwpn);
1079 		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)));
1080 	} else {
1081 		isp_prt(isp, ISP_LOGERR, "No valid WWNs to use");
1082 		return;
1083 	}
1084 	icbp->icb_rspnsin = isp->isp_resodx;
1085 	icbp->icb_rqstout = isp->isp_reqidx;
1086 	icbp->icb_retry_count = fcp->isp_retry_count;
1087 
1088 	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN(isp);
1089 	if (icbp->icb_rqstqlen < 8) {
1090 		isp_prt(isp, ISP_LOGERR, "bad request queue length %d", icbp->icb_rqstqlen);
1091 		return;
1092 	}
1093 	icbp->icb_rsltqlen = RESULT_QUEUE_LEN(isp);
1094 	if (icbp->icb_rsltqlen < 8) {
1095 		isp_prt(isp, ISP_LOGERR, "bad result queue length %d",
1096 		    icbp->icb_rsltqlen);
1097 		return;
1098 	}
1099 	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_rquest_dma);
1100 	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_rquest_dma);
1101 	icbp->icb_rqstaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_rquest_dma);
1102 	icbp->icb_rqstaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_rquest_dma);
1103 
1104 	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_result_dma);
1105 	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_result_dma);
1106 	icbp->icb_respaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_result_dma);
1107 	icbp->icb_respaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_result_dma);
1108 
1109 #ifdef	ISP_TARGET_MODE
1110 	/* unconditionally set up the ATIO queue if we support target mode */
1111 	icbp->icb_atio_in = isp->isp_atioodx;
1112 	icbp->icb_atioqlen = ATIO_QUEUE_LEN(isp);
1113 	if (icbp->icb_atioqlen < 8) {
1114 		isp_prt(isp, ISP_LOGERR, "bad ATIO queue length %d", icbp->icb_atioqlen);
1115 		return;
1116 	}
1117 	icbp->icb_atioqaddr[RQRSP_ADDR0015] = DMA_WD0(isp->isp_atioq_dma);
1118 	icbp->icb_atioqaddr[RQRSP_ADDR1631] = DMA_WD1(isp->isp_atioq_dma);
1119 	icbp->icb_atioqaddr[RQRSP_ADDR3247] = DMA_WD2(isp->isp_atioq_dma);
1120 	icbp->icb_atioqaddr[RQRSP_ADDR4863] = DMA_WD3(isp->isp_atioq_dma);
1121 	isp_prt(isp, ISP_LOGDEBUG0, "isp_init: atioq %04x%04x%04x%04x", DMA_WD3(isp->isp_atioq_dma), DMA_WD2(isp->isp_atioq_dma),
1122 	    DMA_WD1(isp->isp_atioq_dma), DMA_WD0(isp->isp_atioq_dma));
1123 #endif
1124 
1125 	if (ISP_CAP_MSIX(isp) && isp->isp_nirq >= 2) {
1126 		icbp->icb_msixresp = 1;
1127 		if (IS_26XX(isp) && isp->isp_nirq >= 3)
1128 			icbp->icb_msixatio = 2;
1129 	}
1130 
1131 	isp_prt(isp, ISP_LOGDEBUG0, "isp_init: fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x", icbp->icb_fwoptions1, icbp->icb_fwoptions2, icbp->icb_fwoptions3);
1132 
1133 	isp_prt(isp, ISP_LOGDEBUG0, "isp_init: rqst %04x%04x%04x%04x rsp %04x%04x%04x%04x", DMA_WD3(isp->isp_rquest_dma), DMA_WD2(isp->isp_rquest_dma),
1134 	    DMA_WD1(isp->isp_rquest_dma), DMA_WD0(isp->isp_rquest_dma), DMA_WD3(isp->isp_result_dma), DMA_WD2(isp->isp_result_dma),
1135 	    DMA_WD1(isp->isp_result_dma), DMA_WD0(isp->isp_result_dma));
1136 
1137 	if (FC_SCRATCH_ACQUIRE(isp, 0)) {
1138 		isp_prt(isp, ISP_LOGERR, sacq);
1139 		return;
1140 	}
1141 	ISP_MEMZERO(fcp->isp_scratch, ISP_FC_SCRLEN);
1142 	isp_put_icb_2400(isp, icbp, fcp->isp_scratch);
1143 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
1144 		isp_print_bytes(isp, "isp_init",
1145 		    sizeof (*icbp), fcp->isp_scratch);
1146 	}
1147 
1148 	/*
1149 	 * Now fill in information about any additional channels
1150 	 */
1151 	if (isp->isp_nchan > 1) {
1152 		isp_icb_2400_vpinfo_t vpinfo, *vdst;
1153 		vp_port_info_t pi, *pdst;
1154 		size_t amt = 0;
1155 		uint8_t *off;
1156 
1157 		vpinfo.vp_global_options = ICB2400_VPGOPT_GEN_RIDA;
1158 		if (ISP_CAP_VP0(isp)) {
1159 			vpinfo.vp_global_options |= ICB2400_VPGOPT_VP0_DECOUPLE;
1160 			vpinfo.vp_count = isp->isp_nchan;
1161 			chan = 0;
1162 		} else {
1163 			vpinfo.vp_count = isp->isp_nchan - 1;
1164 			chan = 1;
1165 		}
1166 		off = fcp->isp_scratch;
1167 		off += ICB2400_VPINFO_OFF;
1168 		vdst = (isp_icb_2400_vpinfo_t *) off;
1169 		isp_put_icb_2400_vpinfo(isp, &vpinfo, vdst);
1170 		amt = ICB2400_VPINFO_OFF + sizeof (isp_icb_2400_vpinfo_t);
1171 		for (; chan < isp->isp_nchan; chan++) {
1172 			fcparam *fcp2;
1173 
1174 			ISP_MEMZERO(&pi, sizeof (pi));
1175 			fcp2 = FCPARAM(isp, chan);
1176 			if (fcp2->role != ISP_ROLE_NONE) {
1177 				pi.vp_port_options = ICB2400_VPOPT_ENABLED |
1178 				    ICB2400_VPOPT_ENA_SNSLOGIN;
1179 				if (fcp2->role & ISP_ROLE_INITIATOR)
1180 					pi.vp_port_options |= ICB2400_VPOPT_INI_ENABLE;
1181 				if ((fcp2->role & ISP_ROLE_TARGET) == 0)
1182 					pi.vp_port_options |= ICB2400_VPOPT_TGT_DISABLE;
1183 				if (fcp2->isp_loopid < LOCAL_LOOP_LIM) {
1184 					pi.vp_port_loopid = fcp2->isp_loopid;
1185 					if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1186 						pi.vp_port_options |= ICB2400_VPOPT_HARD_ADDRESS;
1187 				}
1188 
1189 			}
1190 			MAKE_NODE_NAME_FROM_WWN(pi.vp_port_portname, fcp2->isp_wwpn);
1191 			MAKE_NODE_NAME_FROM_WWN(pi.vp_port_nodename, fcp2->isp_wwnn);
1192 			off = fcp->isp_scratch;
1193 			if (ISP_CAP_VP0(isp))
1194 				off += ICB2400_VPINFO_PORT_OFF(chan);
1195 			else
1196 				off += ICB2400_VPINFO_PORT_OFF(chan - 1);
1197 			pdst = (vp_port_info_t *) off;
1198 			isp_put_vp_port_info(isp, &pi, pdst);
1199 			amt += ICB2400_VPOPT_WRITE_SIZE;
1200 		}
1201 		if (isp->isp_dblev & ISP_LOGDEBUG1) {
1202 			isp_print_bytes(isp, "isp_init",
1203 			    amt - ICB2400_VPINFO_OFF,
1204 			    (char *)fcp->isp_scratch + ICB2400_VPINFO_OFF);
1205 		}
1206 	}
1207 
1208 	/*
1209 	 * Init the firmware
1210 	 */
1211 	MBSINIT(&mbs, 0, MBLOGALL, 30000000);
1212 	if (isp->isp_nchan > 1) {
1213 		mbs.param[0] = MBOX_INIT_FIRMWARE_MULTI_ID;
1214 	} else {
1215 		mbs.param[0] = MBOX_INIT_FIRMWARE;
1216 	}
1217 	mbs.param[1] = 0;
1218 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1219 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1220 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1221 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1222 	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));
1223 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (*icbp), 0);
1224 	isp_mboxcmd(isp, &mbs);
1225 	FC_SCRATCH_RELEASE(isp, 0);
1226 
1227 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1228 		return;
1229 	}
1230 
1231 	/*
1232 	 * Whatever happens, we're now committed to being here.
1233 	 */
1234 	isp->isp_state = ISP_RUNSTATE;
1235 }
1236 
1237 static int
1238 isp_fc_enable_vp(ispsoftc_t *isp, int chan)
1239 {
1240 	fcparam *fcp = FCPARAM(isp, chan);
1241 	vp_modify_t vp;
1242 	int retval;
1243 
1244 	/* Build a VP MODIFY command in memory */
1245 	ISP_MEMZERO(&vp, sizeof(vp));
1246 	vp.vp_mod_hdr.rqs_entry_type = RQSTYPE_VP_MODIFY;
1247 	vp.vp_mod_hdr.rqs_entry_count = 1;
1248 	vp.vp_mod_cnt = 1;
1249 	vp.vp_mod_idx0 = chan;
1250 	vp.vp_mod_cmd = VP_MODIFY_ENA;
1251 	vp.vp_mod_ports[0].options = ICB2400_VPOPT_ENABLED |
1252 	    ICB2400_VPOPT_ENA_SNSLOGIN;
1253 	if (fcp->role & ISP_ROLE_INITIATOR)
1254 		vp.vp_mod_ports[0].options |= ICB2400_VPOPT_INI_ENABLE;
1255 	if ((fcp->role & ISP_ROLE_TARGET) == 0)
1256 		vp.vp_mod_ports[0].options |= ICB2400_VPOPT_TGT_DISABLE;
1257 	if (fcp->isp_loopid < LOCAL_LOOP_LIM) {
1258 		vp.vp_mod_ports[0].loopid = fcp->isp_loopid;
1259 		if (isp->isp_confopts & ISP_CFG_OWNLOOPID)
1260 			vp.vp_mod_ports[0].options |= ICB2400_VPOPT_HARD_ADDRESS;
1261 	}
1262 	MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwpn, fcp->isp_wwpn);
1263 	MAKE_NODE_NAME_FROM_WWN(vp.vp_mod_ports[0].wwnn, fcp->isp_wwnn);
1264 
1265 	retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1266 	if (retval != 0) {
1267 		isp_prt(isp, ISP_LOGERR, "%s: VP_MODIFY of chan %d error %d",
1268 		    __func__, chan, retval);
1269 		return (retval);
1270 	}
1271 
1272 	if (vp.vp_mod_hdr.rqs_flags != 0 || vp.vp_mod_status != VP_STS_OK) {
1273 		isp_prt(isp, ISP_LOGERR,
1274 		    "%s: VP_MODIFY of Chan %d failed with flags %x status %d",
1275 		    __func__, chan, vp.vp_mod_hdr.rqs_flags, vp.vp_mod_status);
1276 		return (EIO);
1277 	}
1278 	return (0);
1279 }
1280 
1281 static int
1282 isp_fc_disable_vp(ispsoftc_t *isp, int chan)
1283 {
1284 	vp_ctrl_info_t vp;
1285 	int retval;
1286 
1287 	/* Build a VP CTRL command in memory */
1288 	ISP_MEMZERO(&vp, sizeof(vp));
1289 	vp.vp_ctrl_hdr.rqs_entry_type = RQSTYPE_VP_CTRL;
1290 	vp.vp_ctrl_hdr.rqs_entry_count = 1;
1291 	if (ISP_CAP_VP0(isp)) {
1292 		vp.vp_ctrl_status = 1;
1293 	} else {
1294 		vp.vp_ctrl_status = 0;
1295 		chan--;	/* VP0 can not be controlled in this case. */
1296 	}
1297 	vp.vp_ctrl_command = VP_CTRL_CMD_DISABLE_VP_LOGO_ALL;
1298 	vp.vp_ctrl_vp_count = 1;
1299 	vp.vp_ctrl_idmap[chan / 16] |= (1 << chan % 16);
1300 
1301 	retval = isp_exec_entry_queue(isp, &vp, &vp, 5);
1302 	if (retval != 0) {
1303 		isp_prt(isp, ISP_LOGERR, "%s: VP_CTRL of chan %d error %d",
1304 		    __func__, chan, retval);
1305 		return (retval);
1306 	}
1307 
1308 	if (vp.vp_ctrl_hdr.rqs_flags != 0 || vp.vp_ctrl_status != 0) {
1309 		isp_prt(isp, ISP_LOGERR,
1310 		    "%s: VP_CTRL of Chan %d failed with flags %x status %d %d",
1311 		    __func__, chan, vp.vp_ctrl_hdr.rqs_flags,
1312 		    vp.vp_ctrl_status, vp.vp_ctrl_index_fail);
1313 		return (EIO);
1314 	}
1315 	return (0);
1316 }
1317 
1318 static int
1319 isp_fc_change_role(ispsoftc_t *isp, int chan, int new_role)
1320 {
1321 	fcparam *fcp = FCPARAM(isp, chan);
1322 	int i, was, res = 0;
1323 
1324 	if (chan >= isp->isp_nchan) {
1325 		isp_prt(isp, ISP_LOGWARN, "%s: bad channel %d", __func__, chan);
1326 		return (ENXIO);
1327 	}
1328 	if (fcp->role == new_role)
1329 		return (0);
1330 	for (was = 0, i = 0; i < isp->isp_nchan; i++) {
1331 		if (FCPARAM(isp, i)->role != ISP_ROLE_NONE)
1332 			was++;
1333 	}
1334 	if (was == 0 || (was == 1 && fcp->role != ISP_ROLE_NONE)) {
1335 		fcp->role = new_role;
1336 		return (isp_reinit(isp, 0));
1337 	}
1338 	if (fcp->role != ISP_ROLE_NONE) {
1339 		res = isp_fc_disable_vp(isp, chan);
1340 		isp_clear_portdb(isp, chan);
1341 	}
1342 	fcp->role = new_role;
1343 	if (fcp->role != ISP_ROLE_NONE)
1344 		res = isp_fc_enable_vp(isp, chan);
1345 	return (res);
1346 }
1347 
1348 static void
1349 isp_clear_portdb(ispsoftc_t *isp, int chan)
1350 {
1351 	fcparam *fcp = FCPARAM(isp, chan);
1352 	fcportdb_t *lp;
1353 	int i;
1354 
1355 	for (i = 0; i < MAX_FC_TARG; i++) {
1356 		lp = &fcp->portdb[i];
1357 		switch (lp->state) {
1358 		case FC_PORTDB_STATE_DEAD:
1359 		case FC_PORTDB_STATE_CHANGED:
1360 		case FC_PORTDB_STATE_VALID:
1361 			lp->state = FC_PORTDB_STATE_NIL;
1362 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1363 			break;
1364 		case FC_PORTDB_STATE_NIL:
1365 		case FC_PORTDB_STATE_NEW:
1366 			lp->state = FC_PORTDB_STATE_NIL;
1367 			break;
1368 		case FC_PORTDB_STATE_ZOMBIE:
1369 			break;
1370 		default:
1371 			panic("Don't know how to clear state %d\n", lp->state);
1372 		}
1373 	}
1374 }
1375 
1376 static void
1377 isp_mark_portdb(ispsoftc_t *isp, int chan)
1378 {
1379 	fcparam *fcp = FCPARAM(isp, chan);
1380 	fcportdb_t *lp;
1381 	int i;
1382 
1383 	for (i = 0; i < MAX_FC_TARG; i++) {
1384 		lp = &fcp->portdb[i];
1385 		if (lp->state == FC_PORTDB_STATE_NIL)
1386 			continue;
1387 		if (lp->portid >= DOMAIN_CONTROLLER_BASE &&
1388 		    lp->portid <= DOMAIN_CONTROLLER_END)
1389 			continue;
1390 		fcp->portdb[i].probational = 1;
1391 	}
1392 }
1393 
1394 /*
1395  * Perform an IOCB PLOGI or LOGO via EXECUTE IOCB A64 for 24XX cards
1396  * or via FABRIC LOGIN/FABRIC LOGOUT for other cards.
1397  */
1398 static int
1399 isp_plogx(ispsoftc_t *isp, int chan, uint16_t handle, uint32_t portid, int flags)
1400 {
1401 	isp_plogx_t pl;
1402 	uint32_t sst, parm1;
1403 	int retval, lev;
1404 	const char *msg;
1405 	char buf[64];
1406 
1407 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d PLOGX %s PortID 0x%06x nphdl 0x%x",
1408 	    chan, (flags & PLOGX_FLG_CMD_MASK) == PLOGX_FLG_CMD_PLOGI ?
1409 	    "Login":"Logout", portid, handle);
1410 
1411 	ISP_MEMZERO(&pl, sizeof(pl));
1412 	pl.plogx_header.rqs_entry_count = 1;
1413 	pl.plogx_header.rqs_entry_type = RQSTYPE_LOGIN;
1414 	pl.plogx_nphdl = handle;
1415 	pl.plogx_vphdl = chan;
1416 	pl.plogx_portlo = portid;
1417 	pl.plogx_rspsz_porthi = (portid >> 16) & 0xff;
1418 	pl.plogx_flags = flags;
1419 
1420 	retval = isp_exec_entry_queue(isp, &pl, &pl, 3 * ICB_LOGIN_TOV);
1421 	if (retval != 0) {
1422 		isp_prt(isp, ISP_LOGERR, "%s: PLOGX of chan %d error %d",
1423 		    __func__, chan, retval);
1424 		return (retval);
1425 	}
1426 
1427 	if (pl.plogx_status == PLOGX_STATUS_OK) {
1428 		return (0);
1429 	} else if (pl.plogx_status != PLOGX_STATUS_IOCBERR) {
1430 		isp_prt(isp, ISP_LOGWARN,
1431 		    "status 0x%x on port login IOCB channel %d",
1432 		    pl.plogx_status, chan);
1433 		return (-1);
1434 	}
1435 
1436 	sst = pl.plogx_ioparm[0].lo16 | (pl.plogx_ioparm[0].hi16 << 16);
1437 	parm1 = pl.plogx_ioparm[1].lo16 | (pl.plogx_ioparm[1].hi16 << 16);
1438 
1439 	retval = -1;
1440 	lev = ISP_LOGERR;
1441 	msg = NULL;
1442 
1443 	switch (sst) {
1444 	case PLOGX_IOCBERR_NOLINK:
1445 		msg = "no link";
1446 		break;
1447 	case PLOGX_IOCBERR_NOIOCB:
1448 		msg = "no IOCB buffer";
1449 		break;
1450 	case PLOGX_IOCBERR_NOXGHG:
1451 		msg = "no Exchange Control Block";
1452 		break;
1453 	case PLOGX_IOCBERR_FAILED:
1454 		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
1455 		msg = buf;
1456 		break;
1457 	case PLOGX_IOCBERR_NOFABRIC:
1458 		msg = "no fabric";
1459 		break;
1460 	case PLOGX_IOCBERR_NOTREADY:
1461 		msg = "firmware not ready";
1462 		break;
1463 	case PLOGX_IOCBERR_NOLOGIN:
1464 		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
1465 		msg = buf;
1466 		retval = MBOX_NOT_LOGGED_IN;
1467 		break;
1468 	case PLOGX_IOCBERR_REJECT:
1469 		ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
1470 		msg = buf;
1471 		break;
1472 	case PLOGX_IOCBERR_NOPCB:
1473 		msg = "no PCB allocated";
1474 		break;
1475 	case PLOGX_IOCBERR_EINVAL:
1476 		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
1477 		msg = buf;
1478 		break;
1479 	case PLOGX_IOCBERR_PORTUSED:
1480 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1481 		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
1482 		msg = buf;
1483 		retval = MBOX_PORT_ID_USED | (parm1 << 16);
1484 		break;
1485 	case PLOGX_IOCBERR_HNDLUSED:
1486 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
1487 		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
1488 		msg = buf;
1489 		retval = MBOX_LOOP_ID_USED;
1490 		break;
1491 	case PLOGX_IOCBERR_NOHANDLE:
1492 		msg = "no handle allocated";
1493 		break;
1494 	case PLOGX_IOCBERR_NOFLOGI:
1495 		msg = "no FLOGI_ACC";
1496 		break;
1497 	default:
1498 		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", pl.plogx_status, flags);
1499 		msg = buf;
1500 		break;
1501 	}
1502 	if (msg) {
1503 		isp_prt(isp, lev, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s",
1504 		    chan, portid, handle, msg);
1505 	}
1506 	return (retval);
1507 }
1508 
1509 static int
1510 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb)
1511 {
1512 	mbreg_t mbs;
1513 	union {
1514 		isp_pdb_24xx_t bill;
1515 	} un;
1516 
1517 	MBSINIT(&mbs, MBOX_GET_PORT_DB,
1518 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000);
1519 	mbs.ibits = (1 << 9)|(1 << 10);
1520 	mbs.param[1] = id;
1521 	mbs.param[2] = DMA_WD1(isp->isp_iocb_dma);
1522 	mbs.param[3] = DMA_WD0(isp->isp_iocb_dma);
1523 	mbs.param[6] = DMA_WD3(isp->isp_iocb_dma);
1524 	mbs.param[7] = DMA_WD2(isp->isp_iocb_dma);
1525 	mbs.param[9] = chan;
1526 	MEMORYBARRIER(isp, SYNC_IFORDEV, 0, sizeof(un), chan);
1527 
1528 	isp_mboxcmd(isp, &mbs);
1529 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE)
1530 		return (mbs.param[0] | (mbs.param[1] << 16));
1531 
1532 	MEMORYBARRIER(isp, SYNC_IFORCPU, 0, sizeof(un), chan);
1533 	isp_get_pdb_24xx(isp, isp->isp_iocb, &un.bill);
1534 	pdb->handle = un.bill.pdb_handle;
1535 	pdb->prli_word0 = un.bill.pdb_prli_svc0;
1536 	pdb->prli_word3 = un.bill.pdb_prli_svc3;
1537 	pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
1538 	ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
1539 	ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
1540 	isp_prt(isp, ISP_LOGDEBUG0,
1541 	    "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x laststate %x",
1542 	    chan, id, pdb->portid, un.bill.pdb_flags,
1543 	    un.bill.pdb_curstate, un.bill.pdb_laststate);
1544 
1545 	/*
1546 	 * XXX KDM this is broken for NVMe.  Need to determine whether this
1547 	 * is an NVMe target, and if so, check the NVMe status bits. We are
1548 	 * probably missing more bits for proper NVMe support, though.
1549 	 */
1550 	if (((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) <
1551 	      PDB2400_STATE_PLOGI_DONE)
1552 	 || ((un.bill.pdb_curstate & PDB2400_STATE_FCP_MASK) >
1553 	      PDB2400_STATE_LOGGED_IN)) {
1554 		mbs.param[0] = MBOX_NOT_LOGGED_IN;
1555 		return (mbs.param[0]);
1556 	}
1557 	return (0);
1558 }
1559 
1560 static int
1561 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num, int loop)
1562 {
1563 	fcparam *fcp = FCPARAM(isp, chan);
1564 	mbreg_t mbs;
1565 	isp_pnhle_24xx_t el4, *elp4;
1566 	int i, j;
1567 	uint32_t p;
1568 
1569 	MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000);
1570 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
1571 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
1572 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
1573 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
1574 	mbs.param[8] = ISP_FC_SCRLEN;
1575 	mbs.param[9] = chan;
1576 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
1577 		isp_prt(isp, ISP_LOGERR, sacq);
1578 		return (-1);
1579 	}
1580 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
1581 	isp_mboxcmd(isp, &mbs);
1582 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1583 		FC_SCRATCH_RELEASE(isp, chan);
1584 		return (mbs.param[0] | (mbs.param[1] << 16));
1585 	}
1586 	MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan);
1587 	elp4 = fcp->isp_scratch;
1588 	for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
1589 		isp_get_pnhle_24xx(isp, &elp4[i], &el4);
1590 		p = el4.pnhle_port_id_lo | (el4.pnhle_port_id_hi << 16);
1591 		if (loop && (p >> 8) != (fcp->isp_portid >> 8))
1592 			continue;
1593 		handles[j++] = el4.pnhle_handle;
1594 	}
1595 	*num = j;
1596 	FC_SCRATCH_RELEASE(isp, chan);
1597 	return (0);
1598 }
1599 
1600 static void
1601 isp_dump_chip_portdb(ispsoftc_t *isp, int chan)
1602 {
1603 	isp_pdb_t pdb;
1604 	uint16_t nphdl;
1605 
1606 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
1607 	for (nphdl = 0; nphdl != NPH_MAX_2K; nphdl++) {
1608 		if (isp_getpdb(isp, chan, nphdl, &pdb)) {
1609 			continue;
1610 		}
1611 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
1612 		    "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
1613 		    chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
1614 		    pdb.portname[2], pdb.portname[3], pdb.portname[4],
1615 		    pdb.portname[5], pdb.portname[6], pdb.portname[7]);
1616 	}
1617 }
1618 
1619 static uint64_t
1620 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
1621 {
1622 	uint64_t wwn = INI_NONE;
1623 	mbreg_t mbs;
1624 
1625 	MBSINIT(&mbs, MBOX_GET_PORT_NAME,
1626 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000);
1627 	mbs.param[1] = nphdl;
1628 	if (nodename)
1629 		mbs.param[10] = 1;
1630 	mbs.param[9] = chan;
1631 	isp_mboxcmd(isp, &mbs);
1632 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1633 		return (wwn);
1634 	}
1635 	wwn = (((uint64_t)(mbs.param[2] >> 8))	<< 56) |
1636 	      (((uint64_t)(mbs.param[2] & 0xff))<< 48) |
1637 	      (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
1638 	      (((uint64_t)(mbs.param[3] & 0xff))<< 32) |
1639 	      (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
1640 	      (((uint64_t)(mbs.param[6] & 0xff))<< 16) |
1641 	      (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
1642 	      (((uint64_t)(mbs.param[7] & 0xff)));
1643 	return (wwn);
1644 }
1645 
1646 /*
1647  * Make sure we have good FC link.
1648  */
1649 
1650 static int
1651 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
1652 {
1653 	mbreg_t mbs;
1654 	int i, r, topo;
1655 	fcparam *fcp;
1656 	isp_pdb_t pdb;
1657 	NANOTIME_T hra, hrb;
1658 
1659 	fcp = FCPARAM(isp, chan);
1660 
1661 	if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1662 		return (-1);
1663 	if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
1664 		return (0);
1665 
1666 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
1667 
1668 	/*
1669 	 * Wait up to N microseconds for F/W to go to a ready state.
1670 	 */
1671 	GET_NANOTIME(&hra);
1672 	while (1) {
1673 		isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
1674 		if (fcp->isp_fwstate == FW_READY) {
1675 			break;
1676 		}
1677 		if (fcp->isp_loopstate < LOOP_HAVE_LINK)
1678 			goto abort;
1679 		GET_NANOTIME(&hrb);
1680 		if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay))
1681 			break;
1682 		ISP_SLEEP(isp, 1000);
1683 	}
1684 	if (fcp->isp_fwstate != FW_READY) {
1685 		isp_prt(isp, ISP_LOG_SANCFG,
1686 		    "Chan %d Firmware is not ready (%s)",
1687 		    chan, isp_fc_fw_statename(fcp->isp_fwstate));
1688 		return (-1);
1689 	}
1690 
1691 	/*
1692 	 * Get our Loop ID and Port ID.
1693 	 */
1694 	MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
1695 	mbs.param[9] = chan;
1696 	isp_mboxcmd(isp, &mbs);
1697 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1698 		return (-1);
1699 	}
1700 
1701 	topo = (int) mbs.param[6];
1702 	if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1703 		topo = TOPO_PTP_STUB;
1704 	fcp->isp_topo = topo;
1705 	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
1706 
1707 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
1708 		fcp->isp_loopid = mbs.param[1] & 0xff;
1709 	} else if (fcp->isp_topo != TOPO_F_PORT) {
1710 		uint8_t alpa = fcp->isp_portid;
1711 
1712 		for (i = 0; alpa_map[i]; i++) {
1713 			if (alpa_map[i] == alpa)
1714 				break;
1715 		}
1716 		if (alpa_map[i])
1717 			fcp->isp_loopid = i;
1718 	}
1719 
1720 #if 0
1721 	fcp->isp_loopstate = LOOP_HAVE_ADDR;
1722 #endif
1723 	fcp->isp_loopstate = LOOP_TESTING_LINK;
1724 
1725 	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
1726 		r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
1727 		if (r != 0 || pdb.portid == 0) {
1728 			isp_prt(isp, ISP_LOGWARN,
1729 			    "fabric topology, but cannot get info about fabric controller (0x%x)", r);
1730 			fcp->isp_topo = TOPO_PTP_STUB;
1731 			goto not_on_fabric;
1732 		}
1733 
1734 		fcp->isp_fabric_params = mbs.param[7];
1735 		fcp->isp_sns_hdl = NPH_SNS_ID;
1736 		r = isp_register_fc4_type(isp, chan);
1737 		if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1738 			goto abort;
1739 		if (r != 0)
1740 			goto not_on_fabric;
1741 		r = isp_register_fc4_features_24xx(isp, chan);
1742 		if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1743 			goto abort;
1744 		if (r != 0)
1745 			goto not_on_fabric;
1746 		r = isp_register_port_name_24xx(isp, chan);
1747 		if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1748 			goto abort;
1749 		if (r != 0)
1750 			goto not_on_fabric;
1751 		isp_register_node_name_24xx(isp, chan);
1752 		if (fcp->isp_loopstate < LOOP_TESTING_LINK)
1753 			goto abort;
1754 	}
1755 
1756 not_on_fabric:
1757 	/* Get link speed. */
1758 	fcp->isp_gbspeed = 1;
1759 	MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
1760 	mbs.param[1] = MBGSD_GET_RATE;
1761 	/* mbs.param[2] undefined if we're just getting rate */
1762 	isp_mboxcmd(isp, &mbs);
1763 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1764 		if (mbs.param[1] == MBGSD_10GB)
1765 			fcp->isp_gbspeed = 10;
1766 		else if (mbs.param[1] == MBGSD_64GB)
1767 			fcp->isp_gbspeed = 64;
1768 		else if (mbs.param[1] == MBGSD_32GB)
1769 			fcp->isp_gbspeed = 32;
1770 		else if (mbs.param[1] == MBGSD_16GB)
1771 			fcp->isp_gbspeed = 16;
1772 		else if (mbs.param[1] == MBGSD_8GB)
1773 			fcp->isp_gbspeed = 8;
1774 		else if (mbs.param[1] == MBGSD_4GB)
1775 			fcp->isp_gbspeed = 4;
1776 		else if (mbs.param[1] == MBGSD_2GB)
1777 			fcp->isp_gbspeed = 2;
1778 		else if (mbs.param[1] == MBGSD_1GB)
1779 			fcp->isp_gbspeed = 1;
1780 	}
1781 
1782 	if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
1783 abort:
1784 		isp_prt(isp, ISP_LOG_SANCFG,
1785 		    "Chan %d FC link test aborted", chan);
1786 		return (1);
1787 	}
1788 	fcp->isp_loopstate = LOOP_LTEST_DONE;
1789 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1790 	    "Chan %d WWPN %016jx WWNN %016jx",
1791 	    chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
1792 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
1793 	    "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
1794 	    chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
1795 	    fcp->isp_loopid);
1796 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
1797 	return (0);
1798 }
1799 
1800 /*
1801  * Complete the synchronization of our Port Database.
1802  *
1803  * At this point, we've scanned the local loop (if any) and the fabric
1804  * and performed fabric logins on all new devices.
1805  *
1806  * Our task here is to go through our port database removing any entities
1807  * that are still marked probational (issuing PLOGO for ones which we had
1808  * PLOGI'd into) or are dead, and notifying upper layers about new/changed
1809  * devices.
1810  */
1811 static int
1812 isp_pdb_sync(ispsoftc_t *isp, int chan)
1813 {
1814 	fcparam *fcp = FCPARAM(isp, chan);
1815 	fcportdb_t *lp;
1816 	uint16_t dbidx;
1817 
1818 	if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
1819 		return (-1);
1820 	if (fcp->isp_loopstate >= LOOP_READY)
1821 		return (0);
1822 
1823 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
1824 
1825 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
1826 
1827 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
1828 		lp = &fcp->portdb[dbidx];
1829 
1830 		if (lp->state == FC_PORTDB_STATE_NIL)
1831 			continue;
1832 		if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
1833 			lp->state = FC_PORTDB_STATE_DEAD;
1834 		switch (lp->state) {
1835 		case FC_PORTDB_STATE_DEAD:
1836 			lp->state = FC_PORTDB_STATE_NIL;
1837 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
1838 			if ((lp->portid & 0xffff00) != 0) {
1839 				(void) isp_plogx(isp, chan, lp->handle,
1840 				    lp->portid,
1841 				    PLOGX_FLG_CMD_LOGO |
1842 				    PLOGX_FLG_IMPLICIT |
1843 				    PLOGX_FLG_FREE_NPHDL);
1844 			}
1845 			/*
1846 			 * Note that we might come out of this with our state
1847 			 * set to FC_PORTDB_STATE_ZOMBIE.
1848 			 */
1849 			break;
1850 		case FC_PORTDB_STATE_NEW:
1851 			lp->state = FC_PORTDB_STATE_VALID;
1852 			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
1853 			break;
1854 		case FC_PORTDB_STATE_CHANGED:
1855 			lp->state = FC_PORTDB_STATE_VALID;
1856 			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
1857 			lp->portid = lp->new_portid;
1858 			lp->prli_word0 = lp->new_prli_word0;
1859 			lp->prli_word3 = lp->new_prli_word3;
1860 			break;
1861 		case FC_PORTDB_STATE_VALID:
1862 			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
1863 			break;
1864 		case FC_PORTDB_STATE_ZOMBIE:
1865 			break;
1866 		default:
1867 			isp_prt(isp, ISP_LOGWARN,
1868 			    "isp_pdb_sync: state %d for idx %d",
1869 			    lp->state, dbidx);
1870 			isp_dump_portdb(isp, chan);
1871 		}
1872 	}
1873 
1874 	if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
1875 		isp_prt(isp, ISP_LOG_SANCFG,
1876 		    "Chan %d FC PDB sync aborted", chan);
1877 		return (1);
1878 	}
1879 
1880 	fcp->isp_loopstate = LOOP_READY;
1881 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
1882 	return (0);
1883 }
1884 
1885 static void
1886 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
1887 {
1888 	fcportdb_t *lp;
1889 	uint64_t wwnn, wwpn;
1890 
1891 	MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
1892 	MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
1893 
1894 	/* Search port database for the same WWPN. */
1895 	if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
1896 		if (!lp->probational) {
1897 			isp_prt(isp, ISP_LOGERR,
1898 			    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
1899 			    chan, lp->portid, lp->handle,
1900 			    FC_PORTDB_TGT(isp, chan, lp), lp->state);
1901 			isp_dump_portdb(isp, chan);
1902 			return;
1903 		}
1904 		lp->probational = 0;
1905 		lp->node_wwn = wwnn;
1906 
1907 		/* Old device, nothing new. */
1908 		if (lp->portid == pdb->portid &&
1909 		    lp->handle == pdb->handle &&
1910 		    lp->prli_word3 == pdb->prli_word3 &&
1911 		    ((pdb->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR) ==
1912 		     (lp->prli_word0 & PRLI_WD0_EST_IMAGE_PAIR))) {
1913 			if (lp->state != FC_PORTDB_STATE_NEW)
1914 				lp->state = FC_PORTDB_STATE_VALID;
1915 			isp_prt(isp, ISP_LOG_SANCFG,
1916 			    "Chan %d Port 0x%06x@0x%04x is valid",
1917 			    chan, pdb->portid, pdb->handle);
1918 			return;
1919 		}
1920 
1921 		/* Something has changed. */
1922 		lp->state = FC_PORTDB_STATE_CHANGED;
1923 		lp->handle = pdb->handle;
1924 		lp->new_portid = pdb->portid;
1925 		lp->new_prli_word0 = pdb->prli_word0;
1926 		lp->new_prli_word3 = pdb->prli_word3;
1927 		isp_prt(isp, ISP_LOG_SANCFG,
1928 		    "Chan %d Port 0x%06x@0x%04x is changed",
1929 		    chan, pdb->portid, pdb->handle);
1930 		return;
1931 	}
1932 
1933 	/* It seems like a new port. Find an empty slot for it. */
1934 	if (!isp_find_pdb_empty(isp, chan, &lp)) {
1935 		isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
1936 		return;
1937 	}
1938 
1939 	ISP_MEMZERO(lp, sizeof (fcportdb_t));
1940 	lp->probational = 0;
1941 	lp->state = FC_PORTDB_STATE_NEW;
1942 	lp->portid = lp->new_portid = pdb->portid;
1943 	lp->prli_word0 = lp->new_prli_word0 = pdb->prli_word0;
1944 	lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
1945 	lp->handle = pdb->handle;
1946 	lp->port_wwn = wwpn;
1947 	lp->node_wwn = wwnn;
1948 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
1949 	    chan, pdb->portid, pdb->handle);
1950 }
1951 
1952 /*
1953  * Scan local loop for devices.
1954  */
1955 static int
1956 isp_scan_loop(ispsoftc_t *isp, int chan)
1957 {
1958 	fcparam *fcp = FCPARAM(isp, chan);
1959 	int idx, lim, r;
1960 	isp_pdb_t pdb;
1961 	uint16_t *handles;
1962 	uint16_t handle;
1963 
1964 	if (fcp->isp_loopstate < LOOP_LTEST_DONE)
1965 		return (-1);
1966 	if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
1967 		return (0);
1968 
1969 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
1970 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
1971 	if (TOPO_IS_FABRIC(fcp->isp_topo)) {
1972 		isp_prt(isp, ISP_LOG_SANCFG,
1973 		    "Chan %d FC loop scan done (no loop)", chan);
1974 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
1975 		return (0);
1976 	}
1977 
1978 	handles = (uint16_t *)fcp->isp_scanscratch;
1979 	lim = ISP_FC_SCRLEN / 2;
1980 	r = isp_gethandles(isp, chan, handles, &lim, 1);
1981 	if (r != 0) {
1982 		isp_prt(isp, ISP_LOG_SANCFG,
1983 		    "Chan %d Getting list of handles failed with %x", chan, r);
1984 		isp_prt(isp, ISP_LOG_SANCFG,
1985 		    "Chan %d FC loop scan done (bad)", chan);
1986 		return (-1);
1987 	}
1988 
1989 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
1990 	    chan, lim);
1991 
1992 	/*
1993 	 * Run through the list and get the port database info for each one.
1994 	 */
1995 	isp_mark_portdb(isp, chan);
1996 	for (idx = 0; idx < lim; idx++) {
1997 		handle = handles[idx];
1998 
1999 		/*
2000 		 * Don't scan "special" ids.
2001 		 */
2002 		if (handle >= NPH_RESERVED)
2003 			continue;
2004 
2005 		/*
2006 		 * Get the port database entity for this index.
2007 		 */
2008 		r = isp_getpdb(isp, chan, handle, &pdb);
2009 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
2010 abort:
2011 			isp_prt(isp, ISP_LOG_SANCFG,
2012 			    "Chan %d FC loop scan aborted", chan);
2013 			return (1);
2014 		}
2015 		if (r != 0) {
2016 			isp_prt(isp, ISP_LOGDEBUG1,
2017 			    "Chan %d FC Scan Loop handle %d returned %x",
2018 			    chan, handle, r);
2019 			continue;
2020 		}
2021 
2022 		isp_pdb_add_update(isp, chan, &pdb);
2023 	}
2024 	if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
2025 		goto abort;
2026 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
2027 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
2028 	return (0);
2029 }
2030 
2031 static int
2032 isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt)
2033 {
2034 	fcparam *fcp = FCPARAM(isp, chan);
2035 	isp_ct_pt_t pt;
2036 	int retval;
2037 
2038 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2039 		isp_print_bytes(isp, "CT request", cmd_bcnt, fcp->isp_scratch);
2040 
2041 	/*
2042 	 * Build a Passthrough IOCB in memory.
2043 	 */
2044 	ISP_MEMZERO(&pt, sizeof(pt));
2045 	pt.ctp_header.rqs_entry_count = 1;
2046 	pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
2047 	pt.ctp_nphdl = fcp->isp_sns_hdl;
2048 	pt.ctp_cmd_cnt = 1;
2049 	pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan);
2050 	pt.ctp_time = 10;
2051 	pt.ctp_rsp_cnt = 1;
2052 	pt.ctp_rsp_bcnt = rsp_bcnt;
2053 	pt.ctp_cmd_bcnt = cmd_bcnt;
2054 	pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma);
2055 	pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma);
2056 	pt.ctp_dataseg[0].ds_count = cmd_bcnt;
2057 	pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma);
2058 	pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma);
2059 	pt.ctp_dataseg[1].ds_count = rsp_bcnt;
2060 
2061 	retval = isp_exec_entry_queue(isp, &pt, &pt, 2 * pt.ctp_time);
2062 	if (retval != 0) {
2063 		isp_prt(isp, ISP_LOGERR, "%s: CTP of chan %d error %d",
2064 		    __func__, chan, retval);
2065 		return (retval);
2066 	}
2067 
2068 	if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) {
2069 		isp_prt(isp, ISP_LOGWARN,
2070 		    "Chan %d CT pass-through returned 0x%x",
2071 		    chan, pt.ctp_status);
2072 		return (-1);
2073 	}
2074 
2075 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2076 		isp_print_bytes(isp, "CT response", rsp_bcnt, fcp->isp_scratch);
2077 
2078 	return (0);
2079 }
2080 
2081 /*
2082  * Scan the fabric for devices and add them to our port database.
2083  *
2084  * Use the GID_PT command to get list of all Nx_Port IDs SNS knows.
2085  * Use GFF_ID and GFT_ID to check port type (FCP) and features (target).
2086  *
2087  * We use CT Pass-through IOCB.
2088  */
2089 #define	GIDLEN	ISP_FC_SCRLEN
2090 #define	NGENT	((GIDLEN - 16) >> 2)
2091 
2092 static int
2093 isp_gid_pt(ispsoftc_t *isp, int chan)
2094 {
2095 	fcparam *fcp = FCPARAM(isp, chan);
2096 	ct_hdr_t ct;
2097 	uint8_t *scp = fcp->isp_scratch;
2098 
2099 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GID_PT", chan);
2100 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2101 		isp_prt(isp, ISP_LOGERR, sacq);
2102 		return (-1);
2103 	}
2104 
2105 	/* Build the CT command and execute via pass-through. */
2106 	ISP_MEMZERO(&ct, sizeof (ct));
2107 	ct.ct_revision = CT_REVISION;
2108 	ct.ct_fcs_type = CT_FC_TYPE_FC;
2109 	ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2110 	ct.ct_cmd_resp = SNS_GID_PT;
2111 	ct.ct_bcnt_resid = (GIDLEN - 16) >> 2;
2112 	isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2113 	scp[sizeof(ct)] = 0x7f;		/* Port Type = Nx_Port */
2114 	scp[sizeof(ct)+1] = 0;		/* Domain_ID = any */
2115 	scp[sizeof(ct)+2] = 0;		/* Area_ID = any */
2116 	scp[sizeof(ct)+3] = 0;		/* Flags = no Area_ID */
2117 
2118 	if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t), GIDLEN)) {
2119 		FC_SCRATCH_RELEASE(isp, chan);
2120 		return (-1);
2121 	}
2122 
2123 	isp_get_gid_xx_response(isp, (sns_gid_xx_rsp_t *)scp,
2124 	    (sns_gid_xx_rsp_t *)fcp->isp_scanscratch, NGENT);
2125 	FC_SCRATCH_RELEASE(isp, chan);
2126 	return (0);
2127 }
2128 
2129 static int
2130 isp_gff_id(ispsoftc_t *isp, int chan, uint32_t portid)
2131 {
2132 	fcparam *fcp = FCPARAM(isp, chan);
2133 	ct_hdr_t ct;
2134 	uint32_t *rp;
2135 	uint8_t *scp = fcp->isp_scratch;
2136 	sns_gff_id_rsp_t rsp;
2137 	int i, res = -1;
2138 
2139 	if (!fcp->isp_use_gff_id)	/* User may block GFF_ID use. */
2140 		return (res);
2141 
2142 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFF_ID", chan);
2143 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2144 		isp_prt(isp, ISP_LOGERR, sacq);
2145 		return (res);
2146 	}
2147 
2148 	/* Build the CT command and execute via pass-through. */
2149 	ISP_MEMZERO(&ct, sizeof (ct));
2150 	ct.ct_revision = CT_REVISION;
2151 	ct.ct_fcs_type = CT_FC_TYPE_FC;
2152 	ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2153 	ct.ct_cmd_resp = SNS_GFF_ID;
2154 	ct.ct_bcnt_resid = (SNS_GFF_ID_RESP_SIZE - sizeof(ct)) / 4;
2155 	isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2156 	rp = (uint32_t *) &scp[sizeof(ct)];
2157 	ISP_IOZPUT_32(isp, portid, rp);
2158 
2159 	if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2160 	    SNS_GFF_ID_RESP_SIZE)) {
2161 		FC_SCRATCH_RELEASE(isp, chan);
2162 		return (res);
2163 	}
2164 
2165 	isp_get_gff_id_response(isp, (sns_gff_id_rsp_t *)scp, &rsp);
2166 	if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
2167 		for (i = 0; i < 32; i++) {
2168 			if (rsp.snscb_fc4_features[i] != 0) {
2169 				res = 0;
2170 				break;
2171 			}
2172 		}
2173 		if (((rsp.snscb_fc4_features[FC4_SCSI / 8] >>
2174 		    ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2175 			res = 1;
2176 		/* Workaround for broken Brocade firmware. */
2177 		if (((ISP_SWAP32(isp, rsp.snscb_fc4_features[FC4_SCSI / 8]) >>
2178 		    ((FC4_SCSI % 8) * 4)) & 0x01) != 0)
2179 			res = 1;
2180 	}
2181 	FC_SCRATCH_RELEASE(isp, chan);
2182 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFF_ID result is %d", chan, res);
2183 	return (res);
2184 }
2185 
2186 static int
2187 isp_gft_id(ispsoftc_t *isp, int chan, uint32_t portid)
2188 {
2189 	fcparam *fcp = FCPARAM(isp, chan);
2190 	ct_hdr_t ct;
2191 	uint32_t *rp;
2192 	uint8_t *scp = fcp->isp_scratch;
2193 	sns_gft_id_rsp_t rsp;
2194 	int i, res = -1;
2195 
2196 	if (!fcp->isp_use_gft_id)	/* User may block GFT_ID use. */
2197 		return (res);
2198 
2199 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d requesting GFT_ID", chan);
2200 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2201 		isp_prt(isp, ISP_LOGERR, sacq);
2202 		return (res);
2203 	}
2204 
2205 	/* Build the CT command and execute via pass-through. */
2206 	ISP_MEMZERO(&ct, sizeof (ct));
2207 	ct.ct_revision = CT_REVISION;
2208 	ct.ct_fcs_type = CT_FC_TYPE_FC;
2209 	ct.ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2210 	ct.ct_cmd_resp = SNS_GFT_ID;
2211 	ct.ct_bcnt_resid = (SNS_GFT_ID_RESP_SIZE - sizeof(ct)) / 4;
2212 	isp_put_ct_hdr(isp, &ct, (ct_hdr_t *)scp);
2213 	rp = (uint32_t *) &scp[sizeof(ct)];
2214 	ISP_IOZPUT_32(isp, portid, rp);
2215 
2216 	if (isp_ct_passthru(isp, chan, sizeof(ct) + sizeof(uint32_t),
2217 	    SNS_GFT_ID_RESP_SIZE)) {
2218 		FC_SCRATCH_RELEASE(isp, chan);
2219 		return (res);
2220 	}
2221 
2222 	isp_get_gft_id_response(isp, (sns_gft_id_rsp_t *)scp, &rsp);
2223 	if (rsp.snscb_cthdr.ct_cmd_resp == LS_ACC) {
2224 		for (i = 0; i < 8; i++) {
2225 			if (rsp.snscb_fc4_types[i] != 0) {
2226 				res = 0;
2227 				break;
2228 			}
2229 		}
2230 		if (((rsp.snscb_fc4_types[FC4_SCSI / 32] >>
2231 		    (FC4_SCSI % 32)) & 0x01) != 0)
2232 			res = 1;
2233 	}
2234 	FC_SCRATCH_RELEASE(isp, chan);
2235 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d GFT_ID result is %d", chan, res);
2236 	return (res);
2237 }
2238 
2239 static int
2240 isp_scan_fabric(ispsoftc_t *isp, int chan)
2241 {
2242 	fcparam *fcp = FCPARAM(isp, chan);
2243 	fcportdb_t *lp;
2244 	uint32_t portid;
2245 	isp_pdb_t pdb;
2246 	int portidx, portlim, r;
2247 	sns_gid_xx_rsp_t *rs;
2248 
2249 	if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
2250 		return (-1);
2251 	if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
2252 		return (0);
2253 
2254 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
2255 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
2256 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
2257 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2258 		isp_prt(isp, ISP_LOG_SANCFG,
2259 		    "Chan %d FC fabric scan done (no fabric)", chan);
2260 		return (0);
2261 	}
2262 
2263 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
2264 abort:
2265 		FC_SCRATCH_RELEASE(isp, chan);
2266 		isp_prt(isp, ISP_LOG_SANCFG,
2267 		    "Chan %d FC fabric scan aborted", chan);
2268 		return (1);
2269 	}
2270 
2271 	/*
2272 	 * Make sure we still are logged into the fabric controller.
2273 	 */
2274 	r = isp_getpdb(isp, chan, NPH_FL_ID, &pdb);
2275 	if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
2276 		isp_dump_chip_portdb(isp, chan);
2277 	}
2278 	if (r) {
2279 		fcp->isp_loopstate = LOOP_LTEST_DONE;
2280 fail:
2281 		isp_prt(isp, ISP_LOG_SANCFG,
2282 		    "Chan %d FC fabric scan done (bad)", chan);
2283 		return (-1);
2284 	}
2285 
2286 	/* Get list of port IDs from SNS. */
2287 	r = isp_gid_pt(isp, chan);
2288 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2289 		goto abort;
2290 	if (r > 0) {
2291 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2292 		return (-1);
2293 	} else if (r < 0) {
2294 		fcp->isp_loopstate = LOOP_LTEST_DONE;	/* try again */
2295 		return (-1);
2296 	}
2297 
2298 	rs = (sns_gid_xx_rsp_t *) fcp->isp_scanscratch;
2299 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2300 		goto abort;
2301 	if (rs->snscb_cthdr.ct_cmd_resp != LS_ACC) {
2302 		int level;
2303 		/* FC-4 Type and Port Type not registered are not errors. */
2304 		if (rs->snscb_cthdr.ct_reason == 9 &&
2305 		    (rs->snscb_cthdr.ct_explanation == 0x07 ||
2306 		     rs->snscb_cthdr.ct_explanation == 0x0a)) {
2307 			level = ISP_LOG_SANCFG;
2308 		} else {
2309 			level = ISP_LOGWARN;
2310 		}
2311 		isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_PT"
2312 		    " (Reason=0x%x Expl=0x%x)", chan,
2313 		    rs->snscb_cthdr.ct_reason,
2314 		    rs->snscb_cthdr.ct_explanation);
2315 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
2316 		return (-1);
2317 	}
2318 
2319 	/* Check our buffer was big enough to get the full list. */
2320 	for (portidx = 0; portidx < NGENT-1; portidx++) {
2321 		if (rs->snscb_ports[portidx].control & 0x80)
2322 			break;
2323 	}
2324 	if ((rs->snscb_ports[portidx].control & 0x80) == 0) {
2325 		isp_prt(isp, ISP_LOGWARN,
2326 		    "fabric too big for scratch area: increase ISP_FC_SCRLEN");
2327 	}
2328 	portlim = portidx + 1;
2329 	isp_prt(isp, ISP_LOG_SANCFG,
2330 	    "Chan %d Got %d ports back from name server", chan, portlim);
2331 
2332 	/* Go through the list and remove duplicate port ids. */
2333 	for (portidx = 0; portidx < portlim; portidx++) {
2334 		int npidx;
2335 
2336 		portid =
2337 		    ((rs->snscb_ports[portidx].portid[0]) << 16) |
2338 		    ((rs->snscb_ports[portidx].portid[1]) << 8) |
2339 		    ((rs->snscb_ports[portidx].portid[2]));
2340 
2341 		for (npidx = portidx + 1; npidx < portlim; npidx++) {
2342 			uint32_t new_portid =
2343 			    ((rs->snscb_ports[npidx].portid[0]) << 16) |
2344 			    ((rs->snscb_ports[npidx].portid[1]) << 8) |
2345 			    ((rs->snscb_ports[npidx].portid[2]));
2346 			if (new_portid == portid) {
2347 				break;
2348 			}
2349 		}
2350 
2351 		if (npidx < portlim) {
2352 			rs->snscb_ports[npidx].portid[0] = 0;
2353 			rs->snscb_ports[npidx].portid[1] = 0;
2354 			rs->snscb_ports[npidx].portid[2] = 0;
2355 			isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
2356 		}
2357 	}
2358 
2359 	/*
2360 	 * We now have a list of Port IDs for all FC4 SCSI devices
2361 	 * that the Fabric Name server knows about.
2362 	 *
2363 	 * For each entry on this list go through our port database looking
2364 	 * for probational entries- if we find one, then an old entry is
2365 	 * maybe still this one. We get some information to find out.
2366 	 *
2367 	 * Otherwise, it's a new fabric device, and we log into it
2368 	 * (unconditionally). After searching the entire database
2369 	 * again to make sure that we never ever ever ever have more
2370 	 * than one entry that has the same PortID or the same
2371 	 * WWNN/WWPN duple, we enter the device into our database.
2372 	 */
2373 	isp_mark_portdb(isp, chan);
2374 	for (portidx = 0; portidx < portlim; portidx++) {
2375 		portid = ((rs->snscb_ports[portidx].portid[0]) << 16) |
2376 			 ((rs->snscb_ports[portidx].portid[1]) << 8) |
2377 			 ((rs->snscb_ports[portidx].portid[2]));
2378 		isp_prt(isp, ISP_LOG_SANCFG,
2379 		    "Chan %d Checking fabric port 0x%06x", chan, portid);
2380 		if (portid == 0) {
2381 			isp_prt(isp, ISP_LOG_SANCFG,
2382 			    "Chan %d Port at idx %d is zero",
2383 			    chan, portidx);
2384 			continue;
2385 		}
2386 		if (portid == fcp->isp_portid) {
2387 			isp_prt(isp, ISP_LOG_SANCFG,
2388 			    "Chan %d Port 0x%06x is our", chan, portid);
2389 			continue;
2390 		}
2391 
2392 		/* Now search the entire port database for the same portid. */
2393 		if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
2394 			if (!lp->probational) {
2395 				isp_prt(isp, ISP_LOGERR,
2396 				    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
2397 				    chan, lp->portid, lp->handle,
2398 				    FC_PORTDB_TGT(isp, chan, lp), lp->state);
2399 				isp_dump_portdb(isp, chan);
2400 				goto fail;
2401 			}
2402 
2403 			if (lp->state == FC_PORTDB_STATE_ZOMBIE)
2404 				goto relogin;
2405 
2406 			/*
2407 			 * See if we're still logged into it.
2408 			 *
2409 			 * If we aren't, mark it as a dead device and
2410 			 * leave the new portid in the database entry
2411 			 * for somebody further along to decide what to
2412 			 * do (policy choice).
2413 			 *
2414 			 * If we are, check to see if it's the same
2415 			 * device still (it should be). If for some
2416 			 * reason it isn't, mark it as a changed device
2417 			 * and leave the new portid and role in the
2418 			 * database entry for somebody further along to
2419 			 * decide what to do (policy choice).
2420 			 */
2421 			r = isp_getpdb(isp, chan, lp->handle, &pdb);
2422 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2423 				goto abort;
2424 			if (r != 0) {
2425 				lp->state = FC_PORTDB_STATE_DEAD;
2426 				isp_prt(isp, ISP_LOG_SANCFG,
2427 				    "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
2428 				    chan, portid, lp->handle, r);
2429 				goto relogin;
2430 			}
2431 
2432 			isp_pdb_add_update(isp, chan, &pdb);
2433 			continue;
2434 		}
2435 
2436 relogin:
2437 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2438 			isp_prt(isp, ISP_LOG_SANCFG,
2439 			    "Chan %d Port 0x%06x is not logged in", chan, portid);
2440 			continue;
2441 		}
2442 
2443 		r = isp_gff_id(isp, chan, portid);
2444 		if (r == 0) {
2445 			isp_prt(isp, ISP_LOG_SANCFG,
2446 			    "Chan %d Port 0x%06x is not an FCP target", chan, portid);
2447 			continue;
2448 		}
2449 		if (r < 0)
2450 			r = isp_gft_id(isp, chan, portid);
2451 		if (r == 0) {
2452 			isp_prt(isp, ISP_LOG_SANCFG,
2453 			    "Chan %d Port 0x%06x is not FCP", chan, portid);
2454 			continue;
2455 		}
2456 
2457 		if (isp_login_device(isp, chan, portid, &pdb,
2458 		    &FCPARAM(isp, 0)->isp_lasthdl)) {
2459 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2460 				goto abort;
2461 			continue;
2462 		}
2463 
2464 		isp_pdb_add_update(isp, chan, &pdb);
2465 	}
2466 
2467 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
2468 		goto abort;
2469 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
2470 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
2471 	return (0);
2472 }
2473 
2474 /*
2475  * Find an unused handle and try and use to login to a port.
2476  */
2477 static int
2478 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
2479 {
2480 	int i, r;
2481 	uint16_t handle;
2482 
2483 	handle = isp_next_handle(isp, ohp);
2484 	for (i = 0; i < NPH_MAX_2K; i++) {
2485 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2486 			return (-1);
2487 
2488 		/* Check if this handle is free. */
2489 		r = isp_getpdb(isp, chan, handle, p);
2490 		if (r == 0) {
2491 			if (p->portid != portid) {
2492 				/* This handle is busy, try next one. */
2493 				handle = isp_next_handle(isp, ohp);
2494 				continue;
2495 			}
2496 			break;
2497 		}
2498 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2499 			return (-1);
2500 
2501 		/*
2502 		 * Now try and log into the device
2503 		 */
2504 		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2505 		if (r == 0) {
2506 			break;
2507 		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
2508 			/*
2509 			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
2510 			 * handle. We need to break that association. We used to try and just substitute the handle, but then
2511 			 * failed to get any data via isp_getpdb (below).
2512 			 */
2513 			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL)) {
2514 				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
2515 			}
2516 			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
2517 				return (-1);
2518 			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI);
2519 			if (r != 0)
2520 				i = NPH_MAX_2K;
2521 			break;
2522 		} else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
2523 			/* Try the next handle. */
2524 			handle = isp_next_handle(isp, ohp);
2525 		} else {
2526 			/* Give up. */
2527 			i = NPH_MAX_2K;
2528 			break;
2529 		}
2530 	}
2531 
2532 	if (i == NPH_MAX_2K) {
2533 		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
2534 		return (-1);
2535 	}
2536 
2537 	/*
2538 	 * If we successfully logged into it, get the PDB for it
2539 	 * so we can crosscheck that it is still what we think it
2540 	 * is and that we also have the role it plays
2541 	 */
2542 	r = isp_getpdb(isp, chan, handle, p);
2543 	if (r != 0) {
2544 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
2545 		return (-1);
2546 	}
2547 
2548 	if (p->handle != handle || p->portid != portid) {
2549 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
2550 		    chan, portid, handle, p->portid, p->handle);
2551 		return (-1);
2552 	}
2553 	return (0);
2554 }
2555 
2556 static int
2557 isp_register_fc4_type(ispsoftc_t *isp, int chan)
2558 {
2559 	fcparam *fcp = FCPARAM(isp, chan);
2560 	rft_id_t rp;
2561 	ct_hdr_t *ct = &rp.rftid_hdr;
2562 	uint8_t *scp = fcp->isp_scratch;
2563 
2564 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2565 		isp_prt(isp, ISP_LOGERR, sacq);
2566 		return (-1);
2567 	}
2568 
2569 	/* Build the CT command and execute via pass-through. */
2570 	ISP_MEMZERO(&rp, sizeof(rp));
2571 	ct->ct_revision = CT_REVISION;
2572 	ct->ct_fcs_type = CT_FC_TYPE_FC;
2573 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2574 	ct->ct_cmd_resp = SNS_RFT_ID;
2575 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
2576 	rp.rftid_portid[0] = fcp->isp_portid >> 16;
2577 	rp.rftid_portid[1] = fcp->isp_portid >> 8;
2578 	rp.rftid_portid[2] = fcp->isp_portid;
2579 	rp.rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
2580 	isp_put_rft_id(isp, &rp, (rft_id_t *)scp);
2581 
2582 	if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2583 		FC_SCRATCH_RELEASE(isp, chan);
2584 		return (-1);
2585 	}
2586 
2587 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2588 	FC_SCRATCH_RELEASE(isp, chan);
2589 	if (ct->ct_cmd_resp == LS_RJT) {
2590 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
2591 		return (-1);
2592 	} else if (ct->ct_cmd_resp == LS_ACC) {
2593 		isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
2594 	} else {
2595 		isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
2596 		return (-1);
2597 	}
2598 	return (0);
2599 }
2600 
2601 static int
2602 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
2603 {
2604 	fcparam *fcp = FCPARAM(isp, chan);
2605 	ct_hdr_t *ct;
2606 	rff_id_t rp;
2607 	uint8_t *scp = fcp->isp_scratch;
2608 
2609 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2610 		isp_prt(isp, ISP_LOGERR, sacq);
2611 		return (-1);
2612 	}
2613 
2614 	/*
2615 	 * Build the CT header and command in memory.
2616 	 */
2617 	ISP_MEMZERO(&rp, sizeof(rp));
2618 	ct = &rp.rffid_hdr;
2619 	ct->ct_revision = CT_REVISION;
2620 	ct->ct_fcs_type = CT_FC_TYPE_FC;
2621 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2622 	ct->ct_cmd_resp = SNS_RFF_ID;
2623 	ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
2624 	rp.rffid_portid[0] = fcp->isp_portid >> 16;
2625 	rp.rffid_portid[1] = fcp->isp_portid >> 8;
2626 	rp.rffid_portid[2] = fcp->isp_portid;
2627 	rp.rffid_fc4features = 0;
2628 	if (fcp->role & ISP_ROLE_TARGET)
2629 		rp.rffid_fc4features |= 1;
2630 	if (fcp->role & ISP_ROLE_INITIATOR)
2631 		rp.rffid_fc4features |= 2;
2632 	rp.rffid_fc4type = FC4_SCSI;
2633 	isp_put_rff_id(isp, &rp, (rff_id_t *)scp);
2634 	if (isp->isp_dblev & ISP_LOGDEBUG1)
2635 		isp_print_bytes(isp, "CT request", sizeof(rft_id_t), scp);
2636 
2637 	if (isp_ct_passthru(isp, chan, sizeof(rft_id_t), sizeof(ct_hdr_t))) {
2638 		FC_SCRATCH_RELEASE(isp, chan);
2639 		return (-1);
2640 	}
2641 
2642 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2643 	FC_SCRATCH_RELEASE(isp, chan);
2644 	if (ct->ct_cmd_resp == LS_RJT) {
2645 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2646 		    "Chan %d Register FC4 Features rejected", chan);
2647 		return (-1);
2648 	} else if (ct->ct_cmd_resp == LS_ACC) {
2649 		isp_prt(isp, ISP_LOG_SANCFG,
2650 		    "Chan %d Register FC4 Features accepted", chan);
2651 	} else {
2652 		isp_prt(isp, ISP_LOGWARN,
2653 		    "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
2654 		return (-1);
2655 	}
2656 	return (0);
2657 }
2658 
2659 static int
2660 isp_register_port_name_24xx(ispsoftc_t *isp, int chan)
2661 {
2662 	fcparam *fcp = FCPARAM(isp, chan);
2663 	ct_hdr_t *ct;
2664 	rspn_id_t rp;
2665 	uint8_t *scp = fcp->isp_scratch;
2666 	int len;
2667 
2668 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2669 		isp_prt(isp, ISP_LOGERR, sacq);
2670 		return (-1);
2671 	}
2672 
2673 	/*
2674 	 * Build the CT header and command in memory.
2675 	 */
2676 	ISP_MEMZERO(&rp, sizeof(rp));
2677 	ct = &rp.rspnid_hdr;
2678 	ct->ct_revision = CT_REVISION;
2679 	ct->ct_fcs_type = CT_FC_TYPE_FC;
2680 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2681 	ct->ct_cmd_resp = SNS_RSPN_ID;
2682 	rp.rspnid_portid[0] = fcp->isp_portid >> 16;
2683 	rp.rspnid_portid[1] = fcp->isp_portid >> 8;
2684 	rp.rspnid_portid[2] = fcp->isp_portid;
2685 	rp.rspnid_length = 0;
2686 	len = offsetof(rspn_id_t, rspnid_name);
2687 	mtx_lock(&prison0.pr_mtx);
2688 	rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2689 	    "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2690 	mtx_unlock(&prison0.pr_mtx);
2691 	rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2692 	    ":%s", device_get_nameunit(isp->isp_dev));
2693 	if (chan != 0) {
2694 		rp.rspnid_length += sprintf(&scp[len + rp.rspnid_length],
2695 		    "/%d", chan);
2696 	}
2697 	len += rp.rspnid_length;
2698 	ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2699 	isp_put_rspn_id(isp, &rp, (rspn_id_t *)scp);
2700 
2701 	if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2702 		FC_SCRATCH_RELEASE(isp, chan);
2703 		return (-1);
2704 	}
2705 
2706 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2707 	FC_SCRATCH_RELEASE(isp, chan);
2708 	if (ct->ct_cmd_resp == LS_RJT) {
2709 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2710 		    "Chan %d Register Symbolic Port Name rejected", chan);
2711 		return (-1);
2712 	} else if (ct->ct_cmd_resp == LS_ACC) {
2713 		isp_prt(isp, ISP_LOG_SANCFG,
2714 		    "Chan %d Register Symbolic Port Name accepted", chan);
2715 	} else {
2716 		isp_prt(isp, ISP_LOGWARN,
2717 		    "Chan %d Register Symbolic Port Name: 0x%x", chan, ct->ct_cmd_resp);
2718 		return (-1);
2719 	}
2720 	return (0);
2721 }
2722 
2723 static int
2724 isp_register_node_name_24xx(ispsoftc_t *isp, int chan)
2725 {
2726 	fcparam *fcp = FCPARAM(isp, chan);
2727 	ct_hdr_t *ct;
2728 	rsnn_nn_t rp;
2729 	uint8_t *scp = fcp->isp_scratch;
2730 	int len;
2731 
2732 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2733 		isp_prt(isp, ISP_LOGERR, sacq);
2734 		return (-1);
2735 	}
2736 
2737 	/*
2738 	 * Build the CT header and command in memory.
2739 	 */
2740 	ISP_MEMZERO(&rp, sizeof(rp));
2741 	ct = &rp.rsnnnn_hdr;
2742 	ct->ct_revision = CT_REVISION;
2743 	ct->ct_fcs_type = CT_FC_TYPE_FC;
2744 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
2745 	ct->ct_cmd_resp = SNS_RSNN_NN;
2746 	MAKE_NODE_NAME_FROM_WWN(rp.rsnnnn_nodename, fcp->isp_wwnn);
2747 	rp.rsnnnn_length = 0;
2748 	len = offsetof(rsnn_nn_t, rsnnnn_name);
2749 	mtx_lock(&prison0.pr_mtx);
2750 	rp.rsnnnn_length += sprintf(&scp[len + rp.rsnnnn_length],
2751 	    "%s", prison0.pr_hostname[0] ? prison0.pr_hostname : "FreeBSD");
2752 	mtx_unlock(&prison0.pr_mtx);
2753 	len += rp.rsnnnn_length;
2754 	ct->ct_bcnt_resid = (len - sizeof(ct_hdr_t)) >> 2;
2755 	isp_put_rsnn_nn(isp, &rp, (rsnn_nn_t *)scp);
2756 
2757 	if (isp_ct_passthru(isp, chan, len, sizeof(ct_hdr_t))) {
2758 		FC_SCRATCH_RELEASE(isp, chan);
2759 		return (-1);
2760 	}
2761 
2762 	isp_get_ct_hdr(isp, (ct_hdr_t *) scp, ct);
2763 	FC_SCRATCH_RELEASE(isp, chan);
2764 	if (ct->ct_cmd_resp == LS_RJT) {
2765 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
2766 		    "Chan %d Register Symbolic Node Name rejected", chan);
2767 		return (-1);
2768 	} else if (ct->ct_cmd_resp == LS_ACC) {
2769 		isp_prt(isp, ISP_LOG_SANCFG,
2770 		    "Chan %d Register Symbolic Node Name accepted", chan);
2771 	} else {
2772 		isp_prt(isp, ISP_LOGWARN,
2773 		    "Chan %d Register Symbolic Node Name: 0x%x", chan, ct->ct_cmd_resp);
2774 		return (-1);
2775 	}
2776 	return (0);
2777 }
2778 
2779 static uint16_t
2780 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
2781 {
2782 	fcparam *fcp;
2783 	int i, chan, wrap;
2784 	uint16_t handle;
2785 
2786 	handle = *ohp;
2787 	wrap = 0;
2788 
2789 next:
2790 	if (handle == NIL_HANDLE) {
2791 		handle = 0;
2792 	} else {
2793 		handle++;
2794 		if (handle > NPH_RESERVED - 1) {
2795 			if (++wrap >= 2) {
2796 				isp_prt(isp, ISP_LOGERR, "Out of port handles!");
2797 				return (NIL_HANDLE);
2798 			}
2799 			handle = 0;
2800 		}
2801 	}
2802 	for (chan = 0; chan < isp->isp_nchan; chan++) {
2803 		fcp = FCPARAM(isp, chan);
2804 		if (fcp->role == ISP_ROLE_NONE)
2805 			continue;
2806 		for (i = 0; i < MAX_FC_TARG; i++) {
2807 			if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
2808 			    fcp->portdb[i].handle == handle)
2809 				goto next;
2810 		}
2811 	}
2812 	*ohp = handle;
2813 	return (handle);
2814 }
2815 
2816 /*
2817  * Start a command. Locking is assumed done in the caller.
2818  */
2819 
2820 int
2821 isp_start(XS_T *xs)
2822 {
2823 	ispsoftc_t *isp;
2824 	fcparam *fcp;
2825 	uint32_t cdblen;
2826 	ispreqt7_t local, *reqp = &local;
2827 	void *qep;
2828 	fcportdb_t *lp;
2829 	int target, dmaresult;
2830 
2831 	XS_INITERR(xs);
2832 	isp = XS_ISP(xs);
2833 
2834 	/*
2835 	 * Check command CDB length, etc.. We really are limited to 16 bytes
2836 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2837 	 * but probably only if we're running fairly new firmware (we'll
2838 	 * let the old f/w choke on an extended command queue entry).
2839 	 */
2840 
2841 	if (XS_CDBLEN(xs) > 16 || XS_CDBLEN(xs) == 0) {
2842 		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2843 		XS_SETERR(xs, HBA_REQINVAL);
2844 		return (CMD_COMPLETE);
2845 	}
2846 
2847 	/*
2848 	 * Translate the target to device handle as appropriate, checking
2849 	 * for correct device state as well.
2850 	 */
2851 	target = XS_TGT(xs);
2852 	fcp = FCPARAM(isp, XS_CHANNEL(xs));
2853 
2854 	if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
2855 		isp_prt(isp, ISP_LOG_WARN1,
2856 		    "%d.%d.%jx I am not an initiator",
2857 		    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2858 		XS_SETERR(xs, HBA_SELTIMEOUT);
2859 		return (CMD_COMPLETE);
2860 	}
2861 
2862 	if (isp->isp_state != ISP_RUNSTATE) {
2863 		isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
2864 		XS_SETERR(xs, HBA_BOTCH);
2865 		return (CMD_COMPLETE);
2866 	}
2867 
2868 	isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
2869 	lp = &fcp->portdb[target];
2870 	if (target < 0 || target >= MAX_FC_TARG ||
2871 	    lp->is_target == 0) {
2872 		XS_SETERR(xs, HBA_SELTIMEOUT);
2873 		return (CMD_COMPLETE);
2874 	}
2875 	if (fcp->isp_loopstate != LOOP_READY) {
2876 		isp_prt(isp, ISP_LOGDEBUG1,
2877 		    "%d.%d.%jx loop is not ready",
2878 		    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2879 		return (CMD_RQLATER);
2880 	}
2881 	if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
2882 		isp_prt(isp, ISP_LOGDEBUG1,
2883 		    "%d.%d.%jx target zombie",
2884 		    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2885 		return (CMD_RQLATER);
2886 	}
2887 	if (lp->state != FC_PORTDB_STATE_VALID) {
2888 		isp_prt(isp, ISP_LOGDEBUG1,
2889 		    "%d.%d.%jx bad db port state 0x%x",
2890 		    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
2891 		XS_SETERR(xs, HBA_SELTIMEOUT);
2892 		return (CMD_COMPLETE);
2893 	}
2894 
2895  start_again:
2896 
2897 	qep = isp_getrqentry(isp);
2898 	if (qep == NULL) {
2899 		isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
2900 		XS_SETERR(xs, HBA_BOTCH);
2901 		return (CMD_EAGAIN);
2902 	}
2903 	XS_SETERR(xs, HBA_NOERROR);
2904 
2905 	/*
2906 	 * Now see if we need to synchronize the ISP with respect to anything.
2907 	 * We do dual duty here (cough) for synchronizing for buses other
2908 	 * than which we got here to send a command to.
2909 	 */
2910 	ISP_MEMZERO(reqp, QENTRY_LEN);
2911 	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
2912 		isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
2913 		m->mrk_header.rqs_entry_count = 1;
2914 		m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
2915 		m->mrk_modifier = SYNC_ALL;
2916 		m->mrk_vphdl = XS_CHANNEL(xs);
2917 		isp_put_marker_24xx(isp, m, qep);
2918 		ISP_SYNC_REQUEST(isp);
2919 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
2920 		goto start_again;
2921 	}
2922 
2923 	/*
2924 	 * NB: we do not support long CDBs (yet)
2925 	 */
2926 	cdblen = XS_CDBLEN(xs);
2927 	if (cdblen > sizeof (reqp->req_cdb)) {
2928 		isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
2929 		XS_SETERR(xs, HBA_REQINVAL);
2930 		return (CMD_COMPLETE);
2931 	}
2932 
2933 	reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
2934 	reqp->req_header.rqs_entry_count = 1;
2935 	reqp->req_nphdl = lp->handle;
2936 	reqp->req_time = XS_TIME(xs);
2937 	be64enc(reqp->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
2938 	if (XS_XFRIN(xs))
2939 		reqp->req_alen_datadir = FCP_CMND_DATA_READ;
2940 	else if (XS_XFROUT(xs))
2941 		reqp->req_alen_datadir = FCP_CMND_DATA_WRITE;
2942 	if (XS_TAG_P(xs))
2943 		reqp->req_task_attribute = XS_TAG_TYPE(xs);
2944 	else
2945 		reqp->req_task_attribute = FCP_CMND_TASK_ATTR_SIMPLE;
2946 	reqp->req_task_attribute |= (XS_PRIORITY(xs) << FCP_CMND_PRIO_SHIFT) &
2947 	     FCP_CMND_PRIO_MASK;
2948 	if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
2949 		if (FCP_NEXT_CRN(isp, &reqp->req_crn, xs)) {
2950 			isp_prt(isp, ISP_LOG_WARN1,
2951 			    "%d.%d.%jx cannot generate next CRN",
2952 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
2953 			XS_SETERR(xs, HBA_BOTCH);
2954 			return (CMD_EAGAIN);
2955 		}
2956 	}
2957 	ISP_MEMCPY(reqp->req_cdb, XS_CDBP(xs), cdblen);
2958 	reqp->req_dl = XS_XFRLEN(xs);
2959 	reqp->req_tidlo = lp->portid;
2960 	reqp->req_tidhi = lp->portid >> 16;
2961 	reqp->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
2962 
2963 	/* Whew. Thankfully the same for type 7 requests */
2964 	reqp->req_handle = isp_allocate_handle(isp, xs, ISP_HANDLE_INITIATOR);
2965 	if (reqp->req_handle == 0) {
2966 		isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
2967 		XS_SETERR(xs, HBA_BOTCH);
2968 		return (CMD_EAGAIN);
2969 	}
2970 
2971 	/*
2972 	 * Set up DMA and/or do any platform dependent swizzling of the request entry
2973 	 * so that the Qlogic F/W understands what is being asked of it.
2974 	 *
2975 	 * The callee is responsible for adding all requests at this point.
2976 	 */
2977 	dmaresult = ISP_DMASETUP(isp, xs, reqp);
2978 	if (dmaresult != 0) {
2979 		isp_destroy_handle(isp, reqp->req_handle);
2980 		/*
2981 		 * dmasetup sets actual error in packet, and
2982 		 * return what we were given to return.
2983 		 */
2984 		return (dmaresult);
2985 	}
2986 	isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
2987 	return (0);
2988 }
2989 
2990 /*
2991  * isp control
2992  * Locks (ints blocked) assumed held.
2993  */
2994 
2995 int
2996 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
2997 {
2998 	fcparam *fcp;
2999 	fcportdb_t *lp;
3000 	XS_T *xs;
3001 	mbreg_t *mbr;
3002 	int chan, tgt;
3003 	uint32_t handle;
3004 	va_list ap;
3005 	uint8_t local[QENTRY_LEN];
3006 
3007 	switch (ctl) {
3008 	case ISPCTL_RESET_BUS:
3009 		/*
3010 		 * Issue a bus reset.
3011 		 */
3012 		isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
3013 		break;
3014 
3015 	case ISPCTL_RESET_DEV:
3016 	{
3017 		isp24xx_tmf_t *tmf;
3018 		isp24xx_statusreq_t *sp;
3019 
3020 		va_start(ap, ctl);
3021 		chan = va_arg(ap, int);
3022 		tgt = va_arg(ap, int);
3023 		va_end(ap);
3024 		fcp = FCPARAM(isp, chan);
3025 
3026 		if (tgt < 0 || tgt >= MAX_FC_TARG) {
3027 			isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
3028 			break;
3029 		}
3030 		lp = &fcp->portdb[tgt];
3031 		if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3032 			isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3033 			break;
3034 		}
3035 
3036 		tmf = (isp24xx_tmf_t *) local;
3037 		ISP_MEMZERO(tmf, QENTRY_LEN);
3038 		tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
3039 		tmf->tmf_header.rqs_entry_count = 1;
3040 		tmf->tmf_nphdl = lp->handle;
3041 		tmf->tmf_delay = 2;
3042 		tmf->tmf_timeout = 4;
3043 		tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
3044 		tmf->tmf_tidlo = lp->portid;
3045 		tmf->tmf_tidhi = lp->portid >> 16;
3046 		tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
3047 		fcp->sendmarker = 1;
3048 		isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3049 
3050 		sp = (isp24xx_statusreq_t *) local;
3051 		if (isp_exec_entry_mbox(isp, tmf, sp, 2 * tmf->tmf_timeout))
3052 			break;
3053 
3054 		if (sp->req_completion_status == 0)
3055 			return (0);
3056 		isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
3057 		break;
3058 	}
3059 	case ISPCTL_ABORT_CMD:
3060 	{
3061 		isp24xx_abrt_t *ab = (isp24xx_abrt_t *)&local;
3062 
3063 		va_start(ap, ctl);
3064 		xs = va_arg(ap, XS_T *);
3065 		va_end(ap);
3066 
3067 		tgt = XS_TGT(xs);
3068 		chan = XS_CHANNEL(xs);
3069 
3070 		handle = isp_find_handle(isp, xs);
3071 		if (handle == 0) {
3072 			isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
3073 			break;
3074 		}
3075 
3076 		fcp = FCPARAM(isp, chan);
3077 		if (tgt < 0 || tgt >= MAX_FC_TARG) {
3078 			isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
3079 			break;
3080 		}
3081 		lp = &fcp->portdb[tgt];
3082 		if (lp->is_target == 0 || lp->state != FC_PORTDB_STATE_VALID) {
3083 			isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
3084 			break;
3085 		}
3086 		isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
3087 		ISP_MEMZERO(ab, QENTRY_LEN);
3088 		ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
3089 		ab->abrt_header.rqs_entry_count = 1;
3090 		ab->abrt_handle = lp->handle;
3091 		ab->abrt_cmd_handle = handle;
3092 		ab->abrt_tidlo = lp->portid;
3093 		ab->abrt_tidhi = lp->portid >> 16;
3094 		ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
3095 
3096 		if (isp_exec_entry_mbox(isp, ab, ab, 5))
3097 			break;
3098 
3099 		if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY)
3100 			return (0);
3101 		isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
3102 		break;
3103 	}
3104 	case ISPCTL_FCLINK_TEST:
3105 	{
3106 		int usdelay;
3107 
3108 		va_start(ap, ctl);
3109 		chan = va_arg(ap, int);
3110 		usdelay = va_arg(ap, int);
3111 		va_end(ap);
3112 		if (usdelay == 0)
3113 			usdelay = 250000;
3114 		return (isp_fclink_test(isp, chan, usdelay));
3115 	}
3116 	case ISPCTL_SCAN_FABRIC:
3117 
3118 		va_start(ap, ctl);
3119 		chan = va_arg(ap, int);
3120 		va_end(ap);
3121 		return (isp_scan_fabric(isp, chan));
3122 
3123 	case ISPCTL_SCAN_LOOP:
3124 
3125 		va_start(ap, ctl);
3126 		chan = va_arg(ap, int);
3127 		va_end(ap);
3128 		return (isp_scan_loop(isp, chan));
3129 
3130 	case ISPCTL_PDB_SYNC:
3131 
3132 		va_start(ap, ctl);
3133 		chan = va_arg(ap, int);
3134 		va_end(ap);
3135 		return (isp_pdb_sync(isp, chan));
3136 
3137 	case ISPCTL_SEND_LIP:
3138 		break;
3139 
3140 	case ISPCTL_GET_PDB:
3141 	{
3142 		isp_pdb_t *pdb;
3143 		va_start(ap, ctl);
3144 		chan = va_arg(ap, int);
3145 		tgt = va_arg(ap, int);
3146 		pdb = va_arg(ap, isp_pdb_t *);
3147 		va_end(ap);
3148 		return (isp_getpdb(isp, chan, tgt, pdb));
3149 	}
3150 	case ISPCTL_GET_NAMES:
3151 	{
3152 		uint64_t *wwnn, *wwnp;
3153 		va_start(ap, ctl);
3154 		chan = va_arg(ap, int);
3155 		tgt = va_arg(ap, int);
3156 		wwnn = va_arg(ap, uint64_t *);
3157 		wwnp = va_arg(ap, uint64_t *);
3158 		va_end(ap);
3159 		if (wwnn == NULL && wwnp == NULL) {
3160 			break;
3161 		}
3162 		if (wwnn) {
3163 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
3164 			if (*wwnn == INI_NONE) {
3165 				break;
3166 			}
3167 		}
3168 		if (wwnp) {
3169 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
3170 			if (*wwnp == INI_NONE) {
3171 				break;
3172 			}
3173 		}
3174 		return (0);
3175 	}
3176 	case ISPCTL_RUN_MBOXCMD:
3177 	{
3178 		va_start(ap, ctl);
3179 		mbr = va_arg(ap, mbreg_t *);
3180 		va_end(ap);
3181 		isp_mboxcmd(isp, mbr);
3182 		return (0);
3183 	}
3184 	case ISPCTL_PLOGX:
3185 	{
3186 		isp_plcmd_t *p;
3187 		int r;
3188 
3189 		va_start(ap, ctl);
3190 		p = va_arg(ap, isp_plcmd_t *);
3191 		va_end(ap);
3192 
3193 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
3194 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
3195 		}
3196 		do {
3197 			isp_next_handle(isp, &p->handle);
3198 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
3199 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3200 				p->handle = r >> 16;
3201 				r = 0;
3202 				break;
3203 			}
3204 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
3205 		return (r);
3206 	}
3207 	case ISPCTL_CHANGE_ROLE:
3208 	{
3209 		int role;
3210 
3211 		va_start(ap, ctl);
3212 		chan = va_arg(ap, int);
3213 		role = va_arg(ap, int);
3214 		va_end(ap);
3215 		return (isp_fc_change_role(isp, chan, role));
3216 	}
3217 	default:
3218 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3219 		break;
3220 
3221 	}
3222 	return (-1);
3223 }
3224 
3225 /*
3226  * Interrupt Service Routine(s).
3227  *
3228  * External (OS) framework has done the appropriate locking,
3229  * and the locking will be held throughout this function.
3230  */
3231 
3232 #ifdef	ISP_TARGET_MODE
3233 void
3234 isp_intr_atioq(ispsoftc_t *isp)
3235 {
3236 	void *addr;
3237 	uint32_t iptr, optr, oop;
3238 
3239 	iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
3240 	optr = isp->isp_atioodx;
3241 	while (optr != iptr) {
3242 		oop = optr;
3243 		MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
3244 		addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
3245 		switch (((isphdr_t *)addr)->rqs_entry_type) {
3246 		case RQSTYPE_NOTIFY:
3247 		case RQSTYPE_ATIO:
3248 		case RQSTYPE_NOTIFY_ACK:	/* Can be set to ATIO queue.*/
3249 		case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue.*/
3250 			(void) isp_target_notify(isp, addr, &oop,
3251 			    ATIO_QUEUE_LEN(isp));
3252 			break;
3253 		case RQSTYPE_RPT_ID_ACQ:	/* Can be set to ATIO queue.*/
3254 		default:
3255 			isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
3256 			break;
3257 		}
3258 		optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
3259 	}
3260 	if (isp->isp_atioodx != optr) {
3261 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
3262 		isp->isp_atioodx = optr;
3263 	}
3264 }
3265 #endif
3266 
3267 void
3268 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
3269 {
3270 	int i, obits;
3271 
3272 	if (!isp->isp_mboxbsy) {
3273 		isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
3274 		return;
3275 	}
3276 	obits = isp->isp_obits;
3277 	isp->isp_mboxtmp[0] = mbox0;
3278 	for (i = 1; i < ISP_NMBOX(isp); i++) {
3279 		if ((obits & (1 << i)) == 0)
3280 			continue;
3281 		isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
3282 	}
3283 	isp->isp_mboxbsy = 0;
3284 }
3285 
3286 void
3287 isp_intr_respq(ispsoftc_t *isp)
3288 {
3289 	XS_T *xs, *cont_xs;
3290 	uint8_t qe[QENTRY_LEN];
3291 	isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe;
3292 	ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
3293 	isphdr_t *hp;
3294 	uint8_t *resp, *snsp, etype;
3295 	uint16_t scsi_status;
3296 	uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen;
3297 #ifdef	ISP_TARGET_MODE
3298 	uint32_t sptr;
3299 #endif
3300 
3301 	/*
3302 	 * We can't be getting this now.
3303 	 */
3304 	if (isp->isp_state != ISP_RUNSTATE) {
3305 		isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
3306 		return;
3307 	}
3308 
3309 	iptr = ISP_READ(isp, BIU2400_RSPINP);
3310 	optr = isp->isp_resodx;
3311 	while (optr != iptr) {
3312 		cptr = optr;
3313 #ifdef	ISP_TARGET_MODE
3314 		sptr = optr;
3315 #endif
3316 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
3317 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3318 
3319 		/*
3320 		 * Synchronize our view of this response queue entry.
3321 		 */
3322 		MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
3323 		if (isp->isp_dblev & ISP_LOGDEBUG1)
3324 			isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
3325 		isp_get_hdr(isp, hp, &sp->req_header);
3326 
3327 		/*
3328 		 * Log IOCBs rejected by the firmware.  We can't really do
3329 		 * much more about them, since it just should not happen.
3330 		 */
3331 		if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) {
3332 			isp_print_qentry(isp, "invalid entry type", cptr, hp);
3333 			continue;
3334 		}
3335 		if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) {
3336 			isp_print_qentry(isp, "invalid entry parameter", cptr, hp);
3337 			continue;
3338 		}
3339 		if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
3340 			isp_print_qentry(isp, "invalid entry count", cptr, hp);
3341 			continue;
3342 		}
3343 		if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
3344 			isp_print_qentry(isp, "invalid entry order", cptr, hp);
3345 			continue;
3346 		}
3347 
3348 		etype = sp->req_header.rqs_entry_type;
3349 
3350 		/* We expected Status Continuation, but got different IOCB. */
3351 		if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
3352 			cont = 0;
3353 			isp_done(cont_xs);
3354 		}
3355 
3356 		if (isp_handle_control(isp, hp)) {
3357 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3358 			continue;
3359 		}
3360 
3361 		switch (etype) {
3362 		case RQSTYPE_RESPONSE:
3363 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp);
3364 			break;
3365 		case RQSTYPE_MARKER:
3366 			isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
3367 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3368 			continue;
3369 		case RQSTYPE_STATUS_CONT:
3370 			isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
3371 			if (cont > 0) {
3372 				slen = min(cont, sizeof(scp->req_sense_data));
3373 				XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen);
3374 				cont -= slen;
3375 				if (cont == 0) {
3376 					isp_done(cont_xs);
3377 				} else {
3378 					isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3379 					    "Expecting Status Continuations for %u bytes",
3380 					    cont);
3381 				}
3382 			} else {
3383 				isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
3384 			}
3385 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3386 			continue;
3387 #ifdef	ISP_TARGET_MODE
3388 		case RQSTYPE_NOTIFY_ACK:	/* Can be set to ATIO queue. */
3389 		case RQSTYPE_CTIO7:
3390 		case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue. */
3391 		case RQSTYPE_ABTS_RSP:
3392 			isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp));
3393 			/* More then one IOCB could be consumed. */
3394 			while (sptr != cptr) {
3395 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3396 				sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
3397 				hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
3398 			}
3399 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3400 			optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
3401 			continue;
3402 #endif
3403 		case RQSTYPE_RPT_ID_ACQ:	/* Can be set to ATIO queue.*/
3404 			isp_handle_rpt_id_acq(isp, hp);
3405 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3406 			continue;
3407 		default:
3408 			/* We don't know what was this -- log and skip. */
3409 			isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
3410 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3411 			continue;
3412 		}
3413 
3414 		xs = isp_find_xs(isp, sp->req_handle);
3415 		if (xs == NULL) {
3416 			/*
3417 			 * Only whine if this isn't the expected fallout of
3418 			 * aborting the command or resetting the target.
3419 			 */
3420 			if (sp->req_completion_status != RQCS_ABORTED &&
3421 			    sp->req_completion_status != RQCS_RESET_OCCURRED)
3422 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)",
3423 				    sp->req_handle, sp->req_completion_status);
3424 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3425 			continue;
3426 		}
3427 
3428 		resp = snsp = sp->req_rsp_sense;
3429 		rlen = slen = totslen = 0;
3430 		scsi_status = sp->req_scsi_status;
3431 		if (scsi_status & RQCS_RV) {
3432 			rlen = sp->req_response_len;
3433 			snsp += rlen;
3434 		}
3435 		if (scsi_status & RQCS_SV) {
3436 			totslen = sp->req_sense_len;
3437 			slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen);
3438 		}
3439 		*XS_STSP(xs) = scsi_status & 0xff;
3440 		if (scsi_status & RQCS_RESID)
3441 			XS_SET_RESID(xs, sp->req_fcp_residual);
3442 		else
3443 			XS_SET_RESID(xs, 0);
3444 
3445 		if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
3446 			const char *ptr;
3447 			char lb[64];
3448 			const char *rnames[10] = {
3449 			    "Task Management function complete",
3450 			    "FCP_DATA length different than FCP_BURST_LEN",
3451 			    "FCP_CMND fields invalid",
3452 			    "FCP_DATA parameter mismatch with FCP_DATA_RO",
3453 			    "Task Management function rejected",
3454 			    "Task Management function failed",
3455 			    NULL,
3456 			    NULL,
3457 			    "Task Management function succeeded",
3458 			    "Task Management function incorrect logical unit number",
3459 			};
3460 			uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
3461 			if (code >= nitems(rnames) || rnames[code] == NULL) {
3462 				ISP_SNPRINTF(lb, sizeof(lb),
3463 				    "Unknown FCP Response Code 0x%x", code);
3464 				ptr = lb;
3465 			} else {
3466 				ptr = rnames[code];
3467 			}
3468 			isp_xs_prt(isp, xs, ISP_LOGWARN,
3469 			    "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
3470 			    rlen, ptr, XS_CDBP(xs)[0] & 0xff);
3471 			if (code != FCP_RSPNS_TMF_DONE &&
3472 			    code != FCP_RSPNS_TMF_SUCCEEDED)
3473 				XS_SETERR(xs, HBA_BOTCH);
3474 		}
3475 		isp_parse_status_24xx(isp, sp, xs);
3476 		if (slen > 0) {
3477 			XS_SAVE_SENSE(xs, snsp, slen);
3478 			if (totslen > slen) {
3479 				cont = totslen - slen;
3480 				cont_xs = xs;
3481 				isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3482 				    "Expecting Status Continuations for %u bytes",
3483 				    cont);
3484 			}
3485 		}
3486 
3487 		ISP_DMAFREE(isp, xs);
3488 		isp_destroy_handle(isp, sp->req_handle);
3489 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3490 
3491 		/* Complete command if we expect no Status Continuations. */
3492 		if (cont == 0)
3493 			isp_done(xs);
3494 	}
3495 
3496 	/* We haven't received all Status Continuations, but that is it. */
3497 	if (cont > 0)
3498 		isp_done(cont_xs);
3499 
3500 	/* If we processed any IOCBs, let ISP know about it. */
3501 	if (optr != isp->isp_resodx) {
3502 		ISP_WRITE(isp, BIU2400_RSPOUTP, optr);
3503 		isp->isp_resodx = optr;
3504 	}
3505 }
3506 
3507 
3508 void
3509 isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
3510 {
3511 	fcparam *fcp;
3512 	uint16_t chan;
3513 
3514 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3515 
3516 	switch (mbox) {
3517 	case ASYNC_SYSTEM_ERROR:
3518 		isp->isp_state = ISP_CRASHED;
3519 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3520 			FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
3521 			isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
3522 		}
3523 		/*
3524 		 * Were we waiting for a mailbox command to complete?
3525 		 * If so, it's dead, so wake up the waiter.
3526 		 */
3527 		if (isp->isp_mboxbsy) {
3528 			isp->isp_obits = 1;
3529 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
3530 			isp->isp_mboxbsy = 0;
3531 		}
3532 		/*
3533 		 * It's up to the handler for isp_async to reinit stuff and
3534 		 * restart the firmware
3535 		 */
3536 		isp_async(isp, ISPASYNC_FW_CRASH);
3537 		break;
3538 
3539 	case ASYNC_RQS_XFER_ERR:
3540 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3541 		break;
3542 
3543 	case ASYNC_RSP_XFER_ERR:
3544 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3545 		break;
3546 
3547 	case ASYNC_ATIO_XFER_ERR:
3548 		isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
3549 		break;
3550 
3551 	case ASYNC_LIP_OCCURRED:
3552 	case ASYNC_LIP_NOS_OLS_RECV:
3553 	case ASYNC_LIP_ERROR:
3554 	case ASYNC_PTPMODE:
3555 		/*
3556 		 * These are broadcast events that have to be sent across
3557 		 * all active channels.
3558 		 */
3559 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3560 			fcp = FCPARAM(isp, chan);
3561 			int topo = fcp->isp_topo;
3562 
3563 			if (fcp->role == ISP_ROLE_NONE)
3564 				continue;
3565 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3566 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3567 			ISP_SET_SENDMARKER(isp, chan, 1);
3568 			isp_async(isp, ISPASYNC_LIP, chan);
3569 #ifdef	ISP_TARGET_MODE
3570 			isp_target_async(isp, chan, mbox);
3571 #endif
3572 			/*
3573 			 * We've had problems with data corruption occurring on
3574 			 * commands that complete (with no apparent error) after
3575 			 * we receive a LIP. This has been observed mostly on
3576 			 * Local Loop topologies. To be safe, let's just mark
3577 			 * all active initiator commands as dead.
3578 			 */
3579 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
3580 				int i, j;
3581 				for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
3582 					XS_T *xs;
3583 					isp_hdl_t *hdp;
3584 
3585 					hdp = &isp->isp_xflist[i];
3586 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
3587 						continue;
3588 					}
3589 					xs = hdp->cmd;
3590 					if (XS_CHANNEL(xs) != chan) {
3591 						continue;
3592 					}
3593 					j++;
3594 					isp_prt(isp, ISP_LOG_WARN1,
3595 					    "%d.%d.%jx bus reset set at %s:%u",
3596 					    XS_CHANNEL(xs), XS_TGT(xs),
3597 					    (uintmax_t)XS_LUN(xs),
3598 					    __func__, __LINE__);
3599 					XS_SETERR(xs, HBA_BUSRESET);
3600 				}
3601 				if (j) {
3602 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
3603 				}
3604 			}
3605 		}
3606 		break;
3607 
3608 	case ASYNC_LOOP_UP:
3609 		/*
3610 		 * This is a broadcast event that has to be sent across
3611 		 * all active channels.
3612 		 */
3613 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3614 			fcp = FCPARAM(isp, chan);
3615 			if (fcp->role == ISP_ROLE_NONE)
3616 				continue;
3617 			fcp->isp_linkstate = 1;
3618 			if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3619 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3620 			ISP_SET_SENDMARKER(isp, chan, 1);
3621 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
3622 #ifdef	ISP_TARGET_MODE
3623 			isp_target_async(isp, chan, mbox);
3624 #endif
3625 		}
3626 		break;
3627 
3628 	case ASYNC_LOOP_DOWN:
3629 		/*
3630 		 * This is a broadcast event that has to be sent across
3631 		 * all active channels.
3632 		 */
3633 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3634 			fcp = FCPARAM(isp, chan);
3635 			if (fcp->role == ISP_ROLE_NONE)
3636 				continue;
3637 			ISP_SET_SENDMARKER(isp, chan, 1);
3638 			fcp->isp_linkstate = 0;
3639 			fcp->isp_loopstate = LOOP_NIL;
3640 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
3641 #ifdef	ISP_TARGET_MODE
3642 			isp_target_async(isp, chan, mbox);
3643 #endif
3644 		}
3645 		break;
3646 
3647 	case ASYNC_LOOP_RESET:
3648 		/*
3649 		 * This is a broadcast event that has to be sent across
3650 		 * all active channels.
3651 		 */
3652 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3653 			fcp = FCPARAM(isp, chan);
3654 			if (fcp->role == ISP_ROLE_NONE)
3655 				continue;
3656 			ISP_SET_SENDMARKER(isp, chan, 1);
3657 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3658 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3659 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
3660 #ifdef	ISP_TARGET_MODE
3661 			isp_target_async(isp, chan, mbox);
3662 #endif
3663 		}
3664 		break;
3665 
3666 	case ASYNC_PDB_CHANGED:
3667 	{
3668 		int echan, nphdl, nlstate, reason;
3669 
3670 		nphdl = ISP_READ(isp, OUTMAILBOX1);
3671 		nlstate = ISP_READ(isp, OUTMAILBOX2);
3672 		reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
3673 		if (ISP_CAP_MULTI_ID(isp)) {
3674 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3675 			if (chan == 0xff || nphdl == NIL_HANDLE) {
3676 				chan = 0;
3677 				echan = isp->isp_nchan - 1;
3678 			} else if (chan >= isp->isp_nchan) {
3679 				break;
3680 			} else {
3681 				echan = chan;
3682 			}
3683 		} else {
3684 			chan = echan = 0;
3685 		}
3686 		for (; chan <= echan; chan++) {
3687 			fcp = FCPARAM(isp, chan);
3688 			if (fcp->role == ISP_ROLE_NONE)
3689 				continue;
3690 			if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
3691 				if (nphdl != NIL_HANDLE &&
3692 				    nphdl == fcp->isp_login_hdl &&
3693 				    reason == PDB24XX_AE_OPN_2)
3694 					continue;
3695 				fcp->isp_loopstate = LOOP_LTEST_DONE;
3696 			} else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3697 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3698 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3699 			    ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
3700 		}
3701 		break;
3702 	}
3703 	case ASYNC_CHANGE_NOTIFY:
3704 	{
3705 		int portid;
3706 
3707 		portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
3708 		    ISP_READ(isp, OUTMAILBOX2);
3709 		if (ISP_CAP_MULTI_ID(isp)) {
3710 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3711 			if (chan >= isp->isp_nchan)
3712 				break;
3713 		} else {
3714 			chan = 0;
3715 		}
3716 		fcp = FCPARAM(isp, chan);
3717 		if (fcp->role == ISP_ROLE_NONE)
3718 			break;
3719 		if (fcp->isp_loopstate > LOOP_LTEST_DONE)
3720 			fcp->isp_loopstate = LOOP_LTEST_DONE;
3721 		else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3722 			fcp->isp_loopstate = LOOP_HAVE_LINK;
3723 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3724 		    ISPASYNC_CHANGE_SNS, portid);
3725 		break;
3726 	}
3727 	case ASYNC_ERR_LOGGING_DISABLED:
3728 		isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
3729 		    ISP_READ(isp, OUTMAILBOX1));
3730 		break;
3731 	case ASYNC_P2P_INIT_ERR:
3732 		isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
3733 		    ISP_READ(isp, OUTMAILBOX1));
3734 		break;
3735 	case ASYNC_RCV_ERR:
3736 		isp_prt(isp, ISP_LOGWARN, "Receive Error");
3737 		break;
3738 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
3739 		isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
3740 		break;
3741 	case ASYNC_FW_RESTART_COMPLETE:
3742 		isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
3743 		break;
3744 	case ASYNC_TEMPERATURE_ALERT:
3745 		isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
3746 		    ISP_READ(isp, OUTMAILBOX1));
3747 		break;
3748 	case ASYNC_INTER_DRIVER_COMP:
3749 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete");
3750 		break;
3751 	case ASYNC_INTER_DRIVER_NOTIFY:
3752 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification");
3753 		break;
3754 	case ASYNC_INTER_DRIVER_TIME_EXT:
3755 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended");
3756 		break;
3757 	case ASYNC_TRANSCEIVER_INSERTION:
3758 		isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)",
3759 		    ISP_READ(isp, OUTMAILBOX1));
3760 		break;
3761 	case ASYNC_TRANSCEIVER_REMOVAL:
3762 		isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal");
3763 		break;
3764 	case ASYNC_NIC_FW_STATE_CHANGE:
3765 		isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change");
3766 		break;
3767 	case ASYNC_AUTOLOAD_FW_COMPLETE:
3768 		isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
3769 		break;
3770 	case ASYNC_AUTOLOAD_FW_FAILURE:
3771 		isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
3772 		break;
3773 	default:
3774 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
3775 		break;
3776 	}
3777 }
3778 
3779 /*
3780  * Handle completions with control handles by waking up waiting threads.
3781  */
3782 static int
3783 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp)
3784 {
3785 	uint32_t hdl;
3786 	void *ptr;
3787 
3788 	switch (hp->rqs_entry_type) {
3789 	case RQSTYPE_RESPONSE:
3790 	case RQSTYPE_MARKER:
3791 	case RQSTYPE_NOTIFY_ACK:
3792 	case RQSTYPE_CTIO7:
3793 	case RQSTYPE_TSK_MGMT:
3794 	case RQSTYPE_CT_PASSTHRU:
3795 	case RQSTYPE_VP_MODIFY:
3796 	case RQSTYPE_VP_CTRL:
3797 	case RQSTYPE_ABORT_IO:
3798 	case RQSTYPE_MBOX:
3799 	case RQSTYPE_LOGIN:
3800 	case RQSTYPE_ELS_PASSTHRU:
3801 		ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
3802 		if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL)
3803 			break;
3804 		ptr = isp_find_xs(isp, hdl);
3805 		if (ptr != NULL) {
3806 			isp_destroy_handle(isp, hdl);
3807 			memcpy(ptr, hp, QENTRY_LEN);
3808 			wakeup(ptr);
3809 		}
3810 		return (1);
3811 	}
3812 	return (0);
3813 }
3814 
3815 static void
3816 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp)
3817 {
3818 	fcparam *fcp;
3819 	isp_ridacq_t rid;
3820 	int chan, c;
3821 	uint32_t portid;
3822 
3823 	isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
3824 	portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
3825 	    rid.ridacq_vp_port_lo;
3826 	if (rid.ridacq_format == 0) {
3827 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3828 			fcp = FCPARAM(isp, chan);
3829 			if (fcp->role == ISP_ROLE_NONE)
3830 				continue;
3831 			c = (chan == 0) ? 127 : (chan - 1);
3832 			if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
3833 			    chan == 0) {
3834 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3835 				isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3836 				    chan, ISPASYNC_CHANGE_OTHER);
3837 			} else {
3838 				fcp->isp_loopstate = LOOP_NIL;
3839 				isp_async(isp, ISPASYNC_LOOP_DOWN,
3840 				    chan);
3841 			}
3842 		}
3843 	} else {
3844 		fcp = FCPARAM(isp, rid.ridacq_vp_index);
3845 		if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
3846 		    rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
3847 			fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
3848 			fcp->isp_portid = portid;
3849 			fcp->isp_loopstate = LOOP_HAVE_ADDR;
3850 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3851 			    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
3852 		} else {
3853 			fcp->isp_loopstate = LOOP_NIL;
3854 			isp_async(isp, ISPASYNC_LOOP_DOWN,
3855 			    rid.ridacq_vp_index);
3856 		}
3857 	}
3858 }
3859 
3860 static void
3861 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs)
3862 {
3863 	int ru_marked, sv_marked;
3864 	int chan = XS_CHANNEL(xs);
3865 
3866 	switch (sp->req_completion_status) {
3867 	case RQCS_COMPLETE:
3868 		return;
3869 
3870 	case RQCS_DMA_ERROR:
3871 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
3872 		if (XS_NOERR(xs))
3873 			XS_SETERR(xs, HBA_BOTCH);
3874 		break;
3875 
3876 	case RQCS_TRANSPORT_ERROR:
3877 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
3878 		if (XS_NOERR(xs))
3879 			XS_SETERR(xs, HBA_BOTCH);
3880 		break;
3881 
3882 	case RQCS_RESET_OCCURRED:
3883 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
3884 		FCPARAM(isp, chan)->sendmarker = 1;
3885 		if (XS_NOERR(xs))
3886 			XS_SETERR(xs, HBA_BUSRESET);
3887 		return;
3888 
3889 	case RQCS_ABORTED:
3890 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
3891 		FCPARAM(isp, chan)->sendmarker = 1;
3892 		if (XS_NOERR(xs))
3893 			XS_SETERR(xs, HBA_ABORTED);
3894 		return;
3895 
3896 	case RQCS_TIMEOUT:
3897 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
3898 		if (XS_NOERR(xs))
3899 			XS_SETERR(xs, HBA_CMDTIMEOUT);
3900 		return;
3901 
3902 	case RQCS_DATA_OVERRUN:
3903 		XS_SET_RESID(xs, sp->req_resid);
3904 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
3905 		if (XS_NOERR(xs))
3906 			XS_SETERR(xs, HBA_DATAOVR);
3907 		return;
3908 
3909 	case RQCS_DRE:		/* data reassembly error */
3910 		isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
3911 		if (XS_NOERR(xs))
3912 			XS_SETERR(xs, HBA_BOTCH);
3913 		return;
3914 
3915 	case RQCS_TABORT:	/* aborted by target */
3916 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
3917 		if (XS_NOERR(xs))
3918 			XS_SETERR(xs, HBA_ABORTED);
3919 		return;
3920 
3921 	case RQCS_DATA_UNDERRUN:
3922 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
3923 		/*
3924 		 * We can get an underrun w/o things being marked
3925 		 * if we got a non-zero status.
3926 		 */
3927 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
3928 		if ((ru_marked == 0 && sv_marked == 0) ||
3929 		    (sp->req_resid > XS_XFRLEN(xs))) {
3930 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
3931 			if (XS_NOERR(xs))
3932 				XS_SETERR(xs, HBA_BOTCH);
3933 			return;
3934 		}
3935 		XS_SET_RESID(xs, sp->req_resid);
3936 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
3937 		return;
3938 
3939 	case RQCS_PORT_UNAVAILABLE:
3940 		/*
3941 		 * No such port on the loop. Moral equivalent of SELTIMEO
3942 		 */
3943 	case RQCS_PORT_LOGGED_OUT:
3944 	{
3945 		const char *reason;
3946 		uint8_t sts = sp->req_completion_status & 0xff;
3947 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
3948 		fcportdb_t *lp;
3949 
3950 		/*
3951 		 * It was there (maybe)- treat as a selection timeout.
3952 		 */
3953 		if (sts == RQCS_PORT_UNAVAILABLE) {
3954 			reason = "unavailable";
3955 		} else {
3956 			reason = "logout";
3957 		}
3958 
3959 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
3960 		    chan, reason, XS_TGT(xs));
3961 
3962 		/* XXX: Should we trigger rescan or FW announce change? */
3963 
3964 		if (XS_NOERR(xs)) {
3965 			lp = &fcp->portdb[XS_TGT(xs)];
3966 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3967 				*XS_STSP(xs) = SCSI_BUSY;
3968 				XS_SETERR(xs, HBA_TGTBSY);
3969 			} else
3970 				XS_SETERR(xs, HBA_SELTIMEOUT);
3971 		}
3972 		return;
3973 	}
3974 	case RQCS_PORT_CHANGED:
3975 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
3976 		if (XS_NOERR(xs)) {
3977 			*XS_STSP(xs) = SCSI_BUSY;
3978 			XS_SETERR(xs, HBA_TGTBSY);
3979 		}
3980 		return;
3981 
3982 	case RQCS_ENOMEM:	/* f/w resource unavailable */
3983 		isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
3984 		if (XS_NOERR(xs)) {
3985 			*XS_STSP(xs) = SCSI_BUSY;
3986 			XS_SETERR(xs, HBA_TGTBSY);
3987 		}
3988 		return;
3989 
3990 	case RQCS_TMO:		/* task management overrun */
3991 		isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
3992 		if (XS_NOERR(xs)) {
3993 			*XS_STSP(xs) = SCSI_BUSY;
3994 			XS_SETERR(xs, HBA_TGTBSY);
3995 		}
3996 		return;
3997 
3998 	default:
3999 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
4000 		break;
4001 	}
4002 	if (XS_NOERR(xs))
4003 		XS_SETERR(xs, HBA_BOTCH);
4004 }
4005 
4006 #define	ISP_FC_IBITS(op)	((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
4007 #define	ISP_FC_OBITS(op)	((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
4008 
4009 #define	ISP_FC_OPMAP(in0, out0)							  0,   0,   0, in0,    0,    0,    0, out0
4010 #define	ISP_FC_OPMAP_HALF(in1, in0, out1, out0)					  0,   0, in1, in0,    0,    0, out1, out0
4011 #define	ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0)		in3, in2, in1, in0, out3, out2, out1, out0
4012 static const uint32_t mbpfc[] = {
4013 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4014 	ISP_FC_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4015 	ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f),	/* 0x02: MBOX_EXEC_FIRMWARE */
4016 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x03: MBOX_LOAD_FLASH_FIRMWARE */
4017 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4018 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4019 	ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4020 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4021 	ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4022 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
4023 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x0a: MBOX_DUMP_RISC_RAM_2100 */
4024 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
4025 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x0c: */
4026 	ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
4027 	ISP_FC_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4028 	ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
4029 	ISP_FC_OPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4030 	ISP_FC_OPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
4031 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
4032 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4033 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03),	/* 0x14: MBOX_STOP_FIRMWARE */
4034 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
4035 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
4036 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
4037 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
4038 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
4039 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
4040 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4041 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
4042 	ISP_FC_OPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4043 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x1e: */
4044 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4045 	ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf),	/* 0x20: MBOX_GET_LOOP_ID */
4046 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x21: */
4047 	ISP_FC_OPMAP(0x03, 0x4b),	/* 0x22: MBOX_GET_TIMEOUT_PARAMS */
4048 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x23: */
4049 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x24: */
4050 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x25: */
4051 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x26: */
4052 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x27: */
4053 	ISP_FC_OPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
4054 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
4055 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2a: */
4056 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2b: */
4057 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2c: */
4058 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2d: */
4059 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2e: */
4060 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2f: */
4061 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x30: */
4062 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x31: */
4063 	ISP_FC_OPMAP(0x4b, 0x4b),	/* 0x32: MBOX_SET_TIMEOUT_PARAMS */
4064 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x33: */
4065 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x34: */
4066 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x35: */
4067 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x36: */
4068 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x37: */
4069 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
4070 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
4071 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3a: */
4072 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3b: */
4073 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3c: */
4074 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3d: */
4075 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3e: */
4076 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3f: */
4077 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
4078 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
4079 	ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
4080 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
4081 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x44: */
4082 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x45: */
4083 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x46: */
4084 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
4085 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
4086 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
4087 	ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
4088 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4b: */
4089 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4c: */
4090 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4d: */
4091 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4e: */
4092 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4f: */
4093 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x50: */
4094 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x51: */
4095 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x52: */
4096 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x53: */
4097 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
4098 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x55: */
4099 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x56: */
4100 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x57: */
4101 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x58: */
4102 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x59: */
4103 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5a: */
4104 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
4105 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
4106 	ISP_FC_OPMAP(0x07, 0x1f),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
4107 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5e: */
4108 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5f: */
4109 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x60: MBOX_INIT_FIRMWARE */
4110 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x61: */
4111 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
4112 	ISP_FC_OPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
4113 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
4114 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
4115 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
4116 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
4117 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
4118 	ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f),	/* 0x69: MBOX_GET_FW_STATE */
4119 	ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
4120 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
4121 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
4122 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x6d: */
4123 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
4124 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
4125 	ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
4126 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
4127 	ISP_FC_OPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
4128 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x73: */
4129 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
4130 	ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07),	/* 0x75: GET PORT/NODE NAME LIST */
4131 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
4132 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
4133 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x78: */
4134 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x79: */
4135 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7a: */
4136 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7b: */
4137 	ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07),	/* 0x7c: Get ID List */
4138 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
4139 	ISP_FC_OPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
4140 };
4141 #define	MAX_FC_OPCODE	0x7e
4142 /*
4143  * Footnotes
4144  *
4145  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
4146  *	do not access at this time in the core driver. The caller is
4147  *	responsible for setting this register first (Gross!). The assumption
4148  *	is that we won't overflow.
4149  */
4150 
4151 static const char *fc_mbcmd_names[] = {
4152 	"NO-OP",			/* 00h */
4153 	"LOAD RAM",
4154 	"EXEC FIRMWARE",
4155 	"LOAD FLASH FIRMWARE",
4156 	"WRITE RAM WORD",
4157 	"READ RAM WORD",
4158 	"MAILBOX REG TEST",
4159 	"VERIFY CHECKSUM",
4160 	"ABOUT FIRMWARE",
4161 	"LOAD RAM (2100)",
4162 	"DUMP RAM (2100)",
4163 	"LOAD RISC RAM",
4164 	"DUMP RISC RAM",
4165 	"WRITE RAM WORD EXTENDED",
4166 	"CHECK FIRMWARE",
4167 	"READ RAM WORD EXTENDED",
4168 	"INIT REQUEST QUEUE",		/* 10h */
4169 	"INIT RESULT QUEUE",
4170 	"EXECUTE IOCB",
4171 	"WAKE UP",
4172 	"STOP FIRMWARE",
4173 	"ABORT",
4174 	"ABORT DEVICE",
4175 	"ABORT TARGET",
4176 	"BUS RESET",
4177 	"STOP QUEUE",
4178 	"START QUEUE",
4179 	"SINGLE STEP QUEUE",
4180 	"ABORT QUEUE",
4181 	"GET DEV QUEUE STATUS",
4182 	NULL,
4183 	"GET FIRMWARE STATUS",
4184 	"GET LOOP ID",			/* 20h */
4185 	NULL,
4186 	"GET TIMEOUT PARAMS",
4187 	NULL,
4188 	NULL,
4189 	NULL,
4190 	NULL,
4191 	NULL,
4192 	"GET FIRMWARE OPTIONS",
4193 	"GET PORT QUEUE PARAMS",
4194 	"GENERATE SYSTEM ERROR",
4195 	NULL,
4196 	NULL,
4197 	NULL,
4198 	NULL,
4199 	NULL,
4200 	"WRITE SFP",			/* 30h */
4201 	"READ SFP",
4202 	"SET TIMEOUT PARAMS",
4203 	NULL,
4204 	NULL,
4205 	NULL,
4206 	NULL,
4207 	NULL,
4208 	"SET FIRMWARE OPTIONS",
4209 	"SET PORT QUEUE PARAMS",
4210 	NULL,
4211 	"SET FC LED CONF",
4212 	NULL,
4213 	"RESTART NIC FIRMWARE",
4214 	"ACCESS CONTROL",
4215 	NULL,
4216 	"LOOP PORT BYPASS",		/* 40h */
4217 	"LOOP PORT ENABLE",
4218 	"GET RESOURCE COUNT",
4219 	"REQUEST NON PARTICIPATING MODE",
4220 	"DIAGNOSTIC ECHO TEST",
4221 	"DIAGNOSTIC LOOPBACK",
4222 	NULL,
4223 	"GET PORT DATABASE ENHANCED",
4224 	"INIT FIRMWARE MULTI ID",
4225 	"GET VP DATABASE",
4226 	"GET VP DATABASE ENTRY",
4227 	NULL,
4228 	NULL,
4229 	NULL,
4230 	NULL,
4231 	NULL,
4232 	"GET FCF LIST",			/* 50h */
4233 	"GET DCBX PARAMETERS",
4234 	NULL,
4235 	"HOST MEMORY COPY",
4236 	"EXECUTE IOCB A64",
4237 	NULL,
4238 	NULL,
4239 	"SEND RNID",
4240 	NULL,
4241 	"SET PARAMETERS",
4242 	"GET PARAMETERS",
4243 	"DRIVER HEARTBEAT",
4244 	"FIRMWARE HEARTBEAT",
4245 	"GET/SET DATA RATE",
4246 	"SEND RNFT",
4247 	NULL,
4248 	"INIT FIRMWARE",		/* 60h */
4249 	"GET INIT CONTROL BLOCK",
4250 	"INIT LIP",
4251 	"GET FC-AL POSITION MAP",
4252 	"GET PORT DATABASE",
4253 	"CLEAR ACA",
4254 	"TARGET RESET",
4255 	"CLEAR TASK SET",
4256 	"ABORT TASK SET",
4257 	"GET FW STATE",
4258 	"GET PORT NAME",
4259 	"GET LINK STATUS",
4260 	"INIT LIP RESET",
4261 	"GET LINK STATS & PRIVATE DATA CNTS",
4262 	"SEND SNS",
4263 	"FABRIC LOGIN",
4264 	"SEND CHANGE REQUEST",		/* 70h */
4265 	"FABRIC LOGOUT",
4266 	"INIT LIP LOGIN",
4267 	NULL,
4268 	"LOGIN LOOP PORT",
4269 	"GET PORT/NODE NAME LIST",
4270 	"SET VENDOR ID",
4271 	"INITIALIZE IP MAILBOX",
4272 	NULL,
4273 	NULL,
4274 	"GET XGMAC STATS",
4275 	NULL,
4276 	"GET ID LIST",
4277 	"SEND LFA",
4278 	"LUN RESET"
4279 };
4280 
4281 static void
4282 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
4283 {
4284 	const char *cname, *xname, *sname;
4285 	char tname[16], mname[16];
4286 	unsigned int ibits, obits, box, opcode, t, to;
4287 
4288 	opcode = mbp->param[0];
4289 	if (opcode > MAX_FC_OPCODE) {
4290 		mbp->param[0] = MBOX_INVALID_COMMAND;
4291 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
4292 		return;
4293 	}
4294 	cname = fc_mbcmd_names[opcode];
4295 	ibits = ISP_FC_IBITS(opcode);
4296 	obits = ISP_FC_OBITS(opcode);
4297 	if (cname == NULL) {
4298 		cname = tname;
4299 		ISP_SNPRINTF(tname, sizeof(tname), "opcode %x", opcode);
4300 	}
4301 	isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
4302 
4303 	/*
4304 	 * Pick up any additional bits that the caller might have set.
4305 	 */
4306 	ibits |= mbp->ibits;
4307 	obits |= mbp->obits;
4308 
4309 	/*
4310 	 * Mask any bits that the caller wants us to mask
4311 	 */
4312 	ibits &= mbp->ibitm;
4313 	obits &= mbp->obitm;
4314 
4315 
4316 	if (ibits == 0 && obits == 0) {
4317 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
4318 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
4319 		return;
4320 	}
4321 
4322 	for (box = 0; box < ISP_NMBOX(isp); box++) {
4323 		if (ibits & (1 << box)) {
4324 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
4325 			    mbp->param[box]);
4326 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
4327 		}
4328 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
4329 	}
4330 
4331 	isp->isp_obits = obits;
4332 	isp->isp_mboxbsy = 1;
4333 
4334 	/*
4335 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
4336 	 */
4337 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
4338 
4339 	/*
4340 	 * While we haven't finished the command, spin our wheels here.
4341 	 */
4342 	to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4343 	for (t = 0; t < to; t += 100) {
4344 		if (!isp->isp_mboxbsy)
4345 			break;
4346 		ISP_RUN_ISR(isp);
4347 		if (!isp->isp_mboxbsy)
4348 			break;
4349 		ISP_DELAY(100);
4350 	}
4351 
4352 	/*
4353 	 * Did the command time out?
4354 	 */
4355 	if (isp->isp_mboxbsy) {
4356 		isp->isp_mboxbsy = 0;
4357 		isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4358 		    opcode, to, mbp->func, mbp->lineno);
4359 		mbp->param[0] = MBOX_TIMEOUT;
4360 		goto out;
4361 	}
4362 
4363 	/*
4364 	 * Copy back output registers.
4365 	 */
4366 	for (box = 0; box < ISP_NMBOX(isp); box++) {
4367 		if (obits & (1 << box)) {
4368 			mbp->param[box] = isp->isp_mboxtmp[box];
4369 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
4370 			    mbp->param[box]);
4371 		}
4372 	}
4373 
4374 out:
4375 	if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
4376 		return;
4377 
4378 	if ((mbp->param[0] & 0xbfe0) == 0 &&
4379 	    (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
4380 		return;
4381 
4382 	xname = NULL;
4383 	sname = "";
4384 	switch (mbp->param[0]) {
4385 	case MBOX_INVALID_COMMAND:
4386 		xname = "INVALID COMMAND";
4387 		break;
4388 	case MBOX_HOST_INTERFACE_ERROR:
4389 		xname = "HOST INTERFACE ERROR";
4390 		break;
4391 	case MBOX_TEST_FAILED:
4392 		xname = "TEST FAILED";
4393 		break;
4394 	case MBOX_COMMAND_ERROR:
4395 		xname = "COMMAND ERROR";
4396 		ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
4397 		    mbp->param[1]);
4398 		sname = mname;
4399 		break;
4400 	case MBOX_COMMAND_PARAM_ERROR:
4401 		xname = "COMMAND PARAMETER ERROR";
4402 		break;
4403 	case MBOX_PORT_ID_USED:
4404 		xname = "PORT ID ALREADY IN USE";
4405 		break;
4406 	case MBOX_LOOP_ID_USED:
4407 		xname = "LOOP ID ALREADY IN USE";
4408 		break;
4409 	case MBOX_ALL_IDS_USED:
4410 		xname = "ALL LOOP IDS IN USE";
4411 		break;
4412 	case MBOX_NOT_LOGGED_IN:
4413 		xname = "NOT LOGGED IN";
4414 		break;
4415 	case MBOX_LINK_DOWN_ERROR:
4416 		xname = "LINK DOWN ERROR";
4417 		break;
4418 	case MBOX_LOOPBACK_ERROR:
4419 		xname = "LOOPBACK ERROR";
4420 		break;
4421 	case MBOX_CHECKSUM_ERROR:
4422 		xname = "CHECKSUM ERROR";
4423 		break;
4424 	case MBOX_INVALID_PRODUCT_KEY:
4425 		xname = "INVALID PRODUCT KEY";
4426 		break;
4427 	case MBOX_REGS_BUSY:
4428 		xname = "REGISTERS BUSY";
4429 		break;
4430 	case MBOX_TIMEOUT:
4431 		xname = "TIMEOUT";
4432 		break;
4433 	default:
4434 		ISP_SNPRINTF(mname, sizeof(mname), "error 0x%x", mbp->param[0]);
4435 		xname = mname;
4436 		break;
4437 	}
4438 	if (xname) {
4439 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
4440 		    cname, xname, sname);
4441 	}
4442 }
4443 
4444 static int
4445 isp_fw_state(ispsoftc_t *isp, int chan)
4446 {
4447 	mbreg_t mbs;
4448 
4449 	MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
4450 	isp_mboxcmd(isp, &mbs);
4451 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
4452 		return (mbs.param[1]);
4453 	return (FW_ERROR);
4454 }
4455 
4456 static void
4457 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
4458 {
4459 	fcparam *fcp = FCPARAM(isp, chan);
4460 
4461 	/*
4462 	 * Establish some default parameters.
4463 	 */
4464 	fcp->role = DEFAULT_ROLE(isp, chan);
4465 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4466 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4467 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
4468 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
4469 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
4470 	fcp->isp_fwoptions = 0;
4471 	fcp->isp_xfwoptions = 0;
4472 	fcp->isp_zfwoptions = 0;
4473 	fcp->isp_lasthdl = NIL_HANDLE;
4474 	fcp->isp_login_hdl = NIL_HANDLE;
4475 
4476 	fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
4477 	fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
4478 	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
4479 		fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
4480 	fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
4481 	fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
4482 	fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
4483 
4484 	/*
4485 	 * Now try and read NVRAM unless told to not do so.
4486 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
4487 	 */
4488 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4489 		int i, j = 0;
4490 		/*
4491 		 * Give a couple of tries at reading NVRAM.
4492 		 */
4493 		for (i = 0; i < 2; i++) {
4494 			j = isp_read_nvram(isp);
4495 			if (j == 0) {
4496 				break;
4497 			}
4498 		}
4499 		if (j) {
4500 			isp->isp_confopts |= ISP_CFG_NONVRAM;
4501 		}
4502 	}
4503 
4504 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
4505 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
4506 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
4507 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
4508 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
4509 	    isp_class3_roles[fcp->role]);
4510 }
4511 
4512 /*
4513  * Re-initialize the ISP and complete all orphaned commands
4514  * with a 'botched' notice. The reset/init routines should
4515  * not disturb an already active list of commands.
4516  */
4517 
4518 int
4519 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
4520 {
4521 	int i, res = 0;
4522 
4523 	if (isp->isp_state > ISP_RESETSTATE)
4524 		isp_stop(isp);
4525 	if (isp->isp_state != ISP_RESETSTATE)
4526 		isp_reset(isp, do_load_defaults);
4527 	if (isp->isp_state != ISP_RESETSTATE) {
4528 		res = EIO;
4529 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
4530 		goto cleanup;
4531 	}
4532 
4533 	isp_init(isp);
4534 	if (isp->isp_state > ISP_RESETSTATE &&
4535 	    isp->isp_state != ISP_RUNSTATE) {
4536 		res = EIO;
4537 		isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
4538 		ISP_DISABLE_INTS(isp);
4539 	}
4540 
4541 cleanup:
4542 	isp_clear_commands(isp);
4543 	for (i = 0; i < isp->isp_nchan; i++)
4544 		isp_clear_portdb(isp, i);
4545 	return (res);
4546 }
4547 
4548 /*
4549  * NVRAM Routines
4550  */
4551 static inline uint32_t
4552 flash_data_addr(ispsoftc_t *isp, uint32_t faddr)
4553 {
4554 	fcparam *fcp = FCPARAM(isp, 0);
4555 
4556 	return (fcp->flash_data_addr + faddr);
4557 }
4558 
4559 static int
4560 isp_read_flash_dword(ispsoftc_t *isp, uint32_t addr, uint32_t *data)
4561 {
4562 	int loops = 0;
4563 
4564 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, addr & ~0x80000000);
4565 	for (loops = 0; loops < 30000; loops++) {
4566 		if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4567 			*data = ISP_READ(isp, BIU2400_FLASH_DATA);
4568 			return (ISP_SUCCESS);
4569 		}
4570 		ISP_DELAY(10);
4571 	}
4572 	isp_prt(isp, ISP_LOGERR,
4573 	    "Flash read dword at 0x%x timeout.", addr);
4574 	*data = 0xffffffff;
4575 	return (ISP_FUNCTION_TIMEOUT);
4576 }
4577 
4578 static int
4579 isp_read_flash_data(ispsoftc_t *isp, uint32_t *dwptr, uint32_t faddr, uint32_t dwords)
4580 {
4581 	int loops = 0;
4582 	int rval = ISP_SUCCESS;
4583 
4584 	/* Dword reads to flash. */
4585 	faddr =  flash_data_addr(isp, faddr);
4586 	for (loops = 0; loops < dwords; loops++, faddr++, dwptr++) {
4587 		rval = isp_read_flash_dword(isp, faddr, dwptr);
4588 		if (rval != ISP_SUCCESS)
4589 			break;
4590 		*dwptr = htole32(*dwptr);
4591 	}
4592 
4593 	return (rval);
4594 }
4595 
4596 static void
4597 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
4598 {
4599 	fcparam *fcp = FCPARAM(isp, 0);
4600 	int loops = 0;
4601 	uint32_t base = fcp->flash_data_addr;
4602 
4603 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, (base + addr) & ~0x80000000);
4604 	for (loops = 0; loops < 30000; loops++) {
4605 		ISP_DELAY(10);
4606 		if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4607 			*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
4608 			ISP_SWIZZLE_NVRAM_LONG(isp, rp);
4609 			return;
4610 		}
4611 	}
4612 	isp_prt(isp, ISP_LOGERR,
4613 	    "Flash read dword at 0x%x timeout.", (base + addr));
4614 	*rp = 0xffffffff;
4615 }
4616 
4617 static int
4618 isp_read_flthdr_2xxx(ispsoftc_t *isp)
4619 {
4620 	fcparam *fcp = FCPARAM(isp, 0);
4621 	int retval = 0;
4622 	uint32_t addr, lwrds, *dptr;
4623 	uint16_t csum;
4624 	uint8_t flthdr_data[FLT_HEADER_SIZE];
4625 
4626 	addr = fcp->flt_region_flt;
4627 	dptr = (uint32_t *) flthdr_data;
4628 
4629 	isp_prt(isp, ISP_LOGDEBUG0, "FLTL[DEF]: 0x%x", addr);
4630 	for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) {
4631 		isp_rd_2xxx_flash(isp, addr++, dptr++);
4632 	}
4633 	dptr = (uint32_t *) flthdr_data;
4634 	for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) {
4635 		uint16_t tmp;
4636 		ISP_IOXGET_16(isp, &dptr[lwrds], tmp);
4637 		csum += tmp;
4638 	}
4639 	if (csum != 0) {
4640 		retval = -1;
4641 		goto out;
4642 	}
4643 	isp_parse_flthdr_2xxx(isp, flthdr_data);
4644 out:
4645 	return (retval);
4646 }
4647 
4648 static void
4649 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data)
4650 {
4651 	fcparam *fcp = FCPARAM(isp, 0);
4652 	uint16_t ver, csum;
4653 
4654 	ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data)));
4655 	fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data)));
4656 	csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data)));
4657 
4658 	if ((fcp->flt_length == 0) ||
4659 	    (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) {
4660 		isp_prt(isp, ISP_LOGERR,
4661 		    "FLT[DEF]: Invalid length=0x%x(%d)",
4662 		    fcp->flt_length, fcp->flt_length);
4663 	}
4664 	isp_prt(isp, ISP_LOGDEBUG0,
4665 	    "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x",
4666 	    ver, fcp->flt_length, fcp->flt_length, csum);
4667 }
4668 
4669 static int
4670 isp_read_flt_2xxx(ispsoftc_t *isp)
4671 {
4672 	fcparam *fcp = FCPARAM(isp, 0);
4673 	int retval = 0;
4674 	int len = fcp->flt_length - FLT_HEADER_SIZE;
4675 	uint32_t addr, lwrds, *dptr;
4676 	uint8_t flt_data[len];
4677 	fcp->flt_region_entries = len / FLT_REGION_SIZE;
4678 
4679 	addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2);
4680 	dptr = (uint32_t *) flt_data;
4681 	isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d",
4682 	    fcp->flt_region_entries);
4683 	for (lwrds = 0; lwrds < len >> 2; lwrds++) {
4684 		isp_rd_2xxx_flash(isp, addr++, dptr++);
4685 	}
4686 	retval = isp_parse_flt_2xxx(isp, flt_data);
4687 	return (retval);
4688 }
4689 
4690 static int
4691 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data)
4692 {
4693 	fcparam *fcp = FCPARAM(isp, 0);
4694 	int count;
4695 	struct flt_region region[fcp->flt_region_entries];
4696 
4697 	for (count = 0; count < fcp->flt_region_entries; count++) {
4698 		region[count].code =
4699 		    le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count)));
4700 		region[count].attribute =
4701 		    (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count));
4702 		region[count].reserved =
4703 		    (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count));
4704 		region[count].size =
4705 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2);
4706 		region[count].start =
4707 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2);
4708 		region[count].end =
4709 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2);
4710 
4711 		isp_prt(isp, ISP_LOGDEBUG0,
4712 		    "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x",
4713 		    region[count].code, region[count].start, region[count].end,
4714 		    region[count].size, region[count].attribute);
4715 
4716 		switch (region[count].code) {
4717 		case FLT_REG_FW:
4718 			fcp->flt_region_fw = region[count].start;
4719 			break;
4720 		case FLT_REG_BOOT_CODE:
4721 			fcp->flt_region_boot = region[count].start;
4722 			break;
4723 		case FLT_REG_VPD_0:
4724 			fcp->flt_region_vpd_nvram = region[count].start;
4725 			if (isp->isp_port == 0)
4726 				fcp->flt_region_vpd = region[count].start;
4727 			break;
4728 		case FLT_REG_VPD_1:
4729 			if (isp->isp_port == 1)
4730 				fcp->flt_region_vpd = region[count].start;
4731 			break;
4732 		case FLT_REG_VPD_2:
4733 			if (!IS_27XX(isp))
4734 				break;
4735 			if (isp->isp_port == 2)
4736 				fcp->flt_region_vpd = region[count].start;
4737 			break;
4738 		case FLT_REG_VPD_3:
4739 			if (!IS_27XX(isp))
4740 				break;
4741 			if (isp->isp_port == 3)
4742 				fcp->flt_region_vpd = region[count].start;
4743 			break;
4744 		case FLT_REG_NVRAM_0:
4745 			if (isp->isp_port == 0)
4746 				fcp->flt_region_nvram = region[count].start;
4747 			break;
4748 		case FLT_REG_NVRAM_1:
4749 			if (isp->isp_port == 1)
4750 				fcp->flt_region_nvram = region[count].start;
4751 			break;
4752 		case FLT_REG_NVRAM_2:
4753 			if (!IS_27XX(isp))
4754 				break;
4755 			if (isp->isp_port == 2)
4756 				fcp->flt_region_nvram = region[count].start;
4757 			break;
4758 		case FLT_REG_NVRAM_3:
4759 			if (!IS_27XX(isp))
4760 				break;
4761 			if (isp->isp_port == 3)
4762 				fcp->flt_region_nvram = region[count].start;
4763 			break;
4764 		case FLT_REG_FDT:
4765 			fcp->flt_region_fdt = region[count].start;
4766 			break;
4767 		case FLT_REG_FLT:
4768 			fcp->flt_region_flt = region[count].start;
4769 			break;
4770 		case FLT_REG_NPIV_CONF_0:
4771 			if (isp->isp_port == 0)
4772 				fcp->flt_region_npiv_conf = region[count].start;
4773 			break;
4774 		case FLT_REG_NPIV_CONF_1:
4775 			if (isp->isp_port == 1)
4776 				fcp->flt_region_npiv_conf = region[count].start;
4777 			break;
4778 		case FLT_REG_GOLD_FW:
4779 			fcp->flt_region_gold_fw = region[count].start;
4780 			break;
4781 		case FLT_REG_FCP_PRIO_0:
4782 			if (isp->isp_port == 0)
4783 				fcp->flt_region_fcp_prio = region[count].start;
4784 			break;
4785 		case FLT_REG_FCP_PRIO_1:
4786 			if (isp->isp_port == 1)
4787 				fcp->flt_region_fcp_prio = region[count].start;
4788 			break;
4789 		case FLT_REG_IMG_PRI_27XX:
4790 			if (IS_27XX(isp))
4791 				fcp->flt_region_img_status_pri = region[count].start;
4792 			break;
4793 		case FLT_REG_IMG_SEC_27XX:
4794 			if (IS_27XX(isp))
4795 				fcp->flt_region_img_status_sec = region[count].start;
4796 			break;
4797 		case FLT_REG_FW_SEC_27XX:
4798 			if (IS_27XX(isp))
4799 				fcp->flt_region_fw_sec = region[count].start;
4800 			break;
4801 		case FLT_REG_BOOTLOAD_SEC_27XX:
4802 			if (IS_27XX(isp))
4803 				fcp->flt_region_boot_sec = region[count].start;
4804 			break;
4805 		case FLT_REG_AUX_IMG_PRI_28XX:
4806 			if (IS_27XX(isp))
4807 				fcp->flt_region_aux_img_status_pri = region[count].start;
4808 			break;
4809 		case FLT_REG_AUX_IMG_SEC_28XX:
4810 			if (IS_27XX(isp))
4811 				fcp->flt_region_aux_img_status_sec = region[count].start;
4812 			break;
4813 		case FLT_REG_NVRAM_SEC_28XX_0:
4814 			if (IS_27XX(isp))
4815 				if (isp->isp_port == 0)
4816 					fcp->flt_region_nvram_sec = region[count].start;
4817 			break;
4818 		case FLT_REG_NVRAM_SEC_28XX_1:
4819 			if (IS_27XX(isp))
4820 				if (isp->isp_port == 1)
4821 					fcp->flt_region_nvram_sec = region[count].start;
4822 			break;
4823 		case FLT_REG_NVRAM_SEC_28XX_2:
4824 			if (IS_27XX(isp))
4825 				if (isp->isp_port == 2)
4826 					fcp->flt_region_nvram_sec = region[count].start;
4827 			break;
4828 		case FLT_REG_NVRAM_SEC_28XX_3:
4829 			if (IS_27XX(isp))
4830 				if (isp->isp_port == 3)
4831 					fcp->flt_region_nvram_sec = region[count].start;
4832 			break;
4833 		case FLT_REG_VPD_SEC_27XX_0:
4834 		case FLT_REG_VPD_SEC_28XX_0:
4835 			if (IS_27XX(isp)) {
4836 				fcp->flt_region_vpd_nvram_sec = region[count].start;
4837 				if (isp->isp_port == 0)
4838 					fcp->flt_region_vpd_sec = region[count].start;
4839 			}
4840 			break;
4841 		case FLT_REG_VPD_SEC_27XX_1:
4842 		case FLT_REG_VPD_SEC_28XX_1:
4843 			if (IS_27XX(isp))
4844 				if (isp->isp_port == 1)
4845 					fcp->flt_region_vpd_sec = region[count].start;
4846 			break;
4847 		case FLT_REG_VPD_SEC_27XX_2:
4848 		case FLT_REG_VPD_SEC_28XX_2:
4849 			if (IS_27XX(isp))
4850 				if (isp->isp_port == 2)
4851 					fcp->flt_region_vpd_sec = region[count].start;
4852 			break;
4853 		case FLT_REG_VPD_SEC_27XX_3:
4854 		case FLT_REG_VPD_SEC_28XX_3:
4855 			if (IS_27XX(isp))
4856 				if (isp->isp_port == 3)
4857 					fcp->flt_region_vpd_sec = region[count].start;
4858 			break;
4859 		}
4860 	}
4861 	isp_prt(isp, ISP_LOGCONFIG,
4862 	    "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x "
4863 	    "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x",
4864 	    fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram,
4865 	    fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt,
4866 	    fcp->flt_region_flt, fcp->flt_region_npiv_conf,
4867 	    fcp->flt_region_fcp_prio);
4868 
4869 	return (0);
4870 }
4871 
4872 static void
4873 isp_print_image(ispsoftc_t *isp, char *name, struct isp_image_status *image_status)
4874 {
4875 	isp_prt(isp, ISP_LOGDEBUG0,
4876 	    "%s %s: mask=0x%02x gen=0x%04x ver=%u.%u map=0x%01x sum=0x%08x sig=0x%08x",
4877 	    name, "status",
4878 	    image_status->image_status_mask,
4879 	    le16toh(image_status->generation),
4880 	    image_status->ver_major,
4881 	    image_status->ver_minor,
4882 	    image_status->bitmap,
4883 	    le32toh(image_status->checksum),
4884 	    le32toh(image_status->signature));
4885 }
4886 
4887 static bool
4888 isp_check_aux_image_status_signature(struct isp_image_status *image_status)
4889 {
4890 	unsigned long signature = le32toh(image_status->signature);
4891 
4892 	return (signature != ISP28XX_AUX_IMG_STATUS_SIGN);
4893 }
4894 
4895 static bool
4896 isp_check_image_status_signature(struct isp_image_status *image_status)
4897 {
4898 	unsigned long signature = le32toh(image_status->signature);
4899 
4900 	return ((signature != ISP27XX_IMG_STATUS_SIGN) &&
4901 	    (signature != ISP28XX_IMG_STATUS_SIGN));
4902 }
4903 
4904 static unsigned long
4905 isp_image_status_checksum(struct isp_image_status *image_status)
4906 {
4907 	uint32_t *p = (uint32_t *)image_status;
4908 	unsigned int n = sizeof(*image_status) / sizeof(*p);
4909 	uint32_t sum = 0;
4910 
4911 	for ( ; n--; p++)
4912 		sum += le32toh(*((uint32_t *)(p)));
4913 
4914 	return (sum);
4915 }
4916 
4917 static inline unsigned int
4918 isp_component_bitmask(struct isp_image_status *aux, unsigned int bitmask)
4919 {
4920 	return (aux->bitmap & bitmask ?
4921 	    ISP27XX_SECONDARY_IMAGE : ISP27XX_PRIMARY_IMAGE);
4922 }
4923 
4924 static void
4925 isp_component_status(struct active_regions *active_regions, struct isp_image_status *aux)
4926 {
4927 	active_regions->aux.board_config =
4928 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_BOARD_CONFIG);
4929 
4930 	active_regions->aux.vpd_nvram =
4931 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_VPD_NVRAM);
4932 
4933 	active_regions->aux.npiv_config_0_1 =
4934 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_0_1);
4935 
4936 	active_regions->aux.npiv_config_2_3 =
4937 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_2_3);
4938 
4939 	active_regions->aux.nvme_params =
4940 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NVME_PARAMS);
4941 }
4942 
4943 static int
4944 isp_compare_image_generation(ispsoftc_t *isp,
4945     struct isp_image_status *pri_image_status,
4946     struct isp_image_status *sec_image_status)
4947 {
4948 	/* calculate generation delta as uint16 (this accounts for wrap) */
4949 	int16_t delta =
4950 	    le16toh(pri_image_status->generation) -
4951 	    le16toh(sec_image_status->generation);
4952 
4953 	isp_prt(isp, ISP_LOGDEBUG0, "generation delta = %d", delta);
4954 
4955 	return (delta);
4956 }
4957 
4958 static void
4959 isp_get_aux_images(ispsoftc_t *isp, struct active_regions *active_regions)
4960 {
4961 	fcparam *fcp = FCPARAM(isp, 0);
4962 	struct isp_image_status pri_aux_image_status, sec_aux_image_status;
4963 	bool valid_pri_image = false, valid_sec_image = false;
4964 	bool active_pri_image = false, active_sec_image = false;
4965 
4966 	if (!fcp->flt_region_aux_img_status_pri) {
4967 		isp_prt(isp, ISP_LOGWARN,
4968 		    "Primary aux image not addressed");
4969 		goto check_sec_image;
4970 	}
4971 
4972 	isp_read_flash_data(isp, (uint32_t *)&pri_aux_image_status,
4973 	    fcp->flt_region_aux_img_status_pri,
4974 	    sizeof(pri_aux_image_status) >> 2);
4975 	isp_print_image(isp, "Primary aux image", &pri_aux_image_status);
4976 
4977 	if (isp_check_aux_image_status_signature(&pri_aux_image_status)) {
4978 		isp_prt(isp, ISP_LOGERR,
4979 		    "Primary aux image signature (0x%x) not valid",
4980 		    le32toh(pri_aux_image_status.signature));
4981 		goto check_sec_image;
4982 	}
4983 
4984 	if (isp_image_status_checksum(&pri_aux_image_status)) {
4985 		isp_prt(isp, ISP_LOGERR,
4986 		    "Primary aux image checksum failed");
4987 		goto check_sec_image;
4988 	}
4989 
4990 	valid_pri_image = true;
4991 
4992 	if (pri_aux_image_status.image_status_mask & 1) {
4993 		isp_prt(isp, ISP_LOGCONFIG,
4994 		    "Primary aux image is active");
4995 		active_pri_image = true;
4996 	}
4997 
4998 check_sec_image:
4999 	if (!fcp->flt_region_aux_img_status_sec) {
5000 		isp_prt(isp, ISP_LOGWARN,
5001 		    "Secondary aux image not addressed");
5002 		goto check_valid_image;
5003 	}
5004 
5005 	isp_read_flash_data(isp, (uint32_t *)&sec_aux_image_status,
5006 	    fcp->flt_region_aux_img_status_sec,
5007 	    sizeof(sec_aux_image_status) >> 2);
5008 	isp_print_image(isp, "Secondary aux image", &sec_aux_image_status);
5009 
5010 	if (isp_check_aux_image_status_signature(&sec_aux_image_status)) {
5011 		isp_prt(isp, ISP_LOGERR,
5012 		    "Secondary aux image signature (0x%x) not valid",
5013 		    le32toh(sec_aux_image_status.signature));
5014 		goto check_valid_image;
5015 	}
5016 
5017 	if (isp_image_status_checksum(&sec_aux_image_status)) {
5018 		isp_prt(isp, ISP_LOGERR,
5019 		    "Secondary aux image checksum failed");
5020 		goto check_valid_image;
5021 	}
5022 
5023 	valid_sec_image = true;
5024 
5025 	if (sec_aux_image_status.image_status_mask & 1) {
5026 		isp_prt(isp, ISP_LOGCONFIG,
5027 		    "Secondary aux image is active");
5028 		active_sec_image = true;
5029 	}
5030 
5031 check_valid_image:
5032 	if (valid_pri_image && active_pri_image &&
5033 	    valid_sec_image && active_sec_image) {
5034 		if (isp_compare_image_generation(isp, &pri_aux_image_status,
5035 		    &sec_aux_image_status) >= 0) {
5036 			isp_component_status(active_regions,
5037 			    &pri_aux_image_status);
5038 		} else {
5039 			isp_component_status(active_regions,
5040 			    &sec_aux_image_status);
5041 		}
5042 	} else if (valid_pri_image && active_pri_image) {
5043 		isp_component_status(active_regions, &pri_aux_image_status);
5044 	} else if (valid_sec_image && active_sec_image) {
5045 		isp_component_status(active_regions, &sec_aux_image_status);
5046 	}
5047 
5048 	isp_prt(isp, ISP_LOGDEBUG0,
5049 	    "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u",
5050 	    active_regions->aux.board_config,
5051 	    active_regions->aux.vpd_nvram,
5052 	    active_regions->aux.npiv_config_0_1,
5053 	    active_regions->aux.npiv_config_2_3,
5054 	    active_regions->aux.nvme_params);
5055 }
5056 
5057 static void
5058 isp_get_active_image(ispsoftc_t *isp, struct active_regions * active_regions)
5059 {
5060 	fcparam *fcp = FCPARAM(isp, 0);
5061 	struct isp_image_status pri_image_status, sec_image_status;
5062 	bool valid_pri_image = false, valid_sec_image = false;
5063 	bool active_pri_image = false, active_sec_image = false;
5064 
5065 	if (!fcp->flt_region_img_status_pri) {
5066 		isp_prt(isp, ISP_LOGWARN,
5067 		    "Primary image not addressed");
5068 		goto check_sec_image;
5069 	}
5070 
5071 	if (isp_read_flash_data(isp, (uint32_t *) &pri_image_status,
5072 	    fcp->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
5073 	    ISP_SUCCESS)
5074 		goto check_sec_image;
5075 
5076 	isp_print_image(isp, "Primary image", &pri_image_status);
5077 
5078 	if (isp_check_image_status_signature(&pri_image_status)) {
5079 		isp_prt(isp, ISP_LOGERR,
5080 		    "Primary image signature (0x%x) not valid",
5081 		    le32toh(pri_image_status.signature));
5082 		goto check_sec_image;
5083 	}
5084 
5085 	if (isp_image_status_checksum(&pri_image_status)) {
5086 		isp_prt(isp, ISP_LOGERR,
5087 		    "Primary image checksum failed");
5088 		goto check_sec_image;
5089 	}
5090 
5091 	valid_pri_image = true;
5092 
5093 	if (pri_image_status.image_status_mask & 1) {
5094 		isp_prt(isp, ISP_LOGCONFIG,
5095 		    "Primary image is active");
5096 		active_pri_image = true;
5097 	}
5098 
5099 check_sec_image:
5100 	if (!fcp->flt_region_img_status_sec) {
5101 		isp_prt(isp, ISP_LOGWARN,
5102 		    "Secondary image not addressed");
5103 		return;
5104 	}
5105 
5106 	if (isp_read_flash_data(isp, (uint32_t *) &sec_image_status,
5107 	    fcp->flt_region_img_status_sec, sizeof(sec_image_status) >> 2) !=
5108 	    ISP_SUCCESS)
5109 		return;
5110 
5111 	isp_print_image(isp, "Secondary image", &sec_image_status);
5112 
5113 	if (isp_check_image_status_signature(&sec_image_status)) {
5114 		isp_prt(isp, ISP_LOGERR,
5115 		    "Secondary image signature (0x%x) not valid",
5116 		    le32toh(sec_image_status.signature));
5117 	}
5118 
5119 	if (isp_image_status_checksum(&sec_image_status)) {
5120 		isp_prt(isp, ISP_LOGERR,
5121 		    "Secondary image checksum failed");
5122 		goto check_valid_image;
5123 	}
5124 
5125 	valid_sec_image = true;
5126 
5127 	if (sec_image_status.image_status_mask & 1) {
5128 		isp_prt(isp, ISP_LOGCONFIG,
5129 		    "Secondary image is active");
5130 		active_sec_image = true;
5131 	}
5132 
5133 check_valid_image:
5134 	if (valid_pri_image && active_pri_image)
5135 		active_regions->global = ISP27XX_PRIMARY_IMAGE;
5136 
5137 	if (valid_sec_image && active_sec_image) {
5138 		if (!active_regions->global ||
5139 		    isp_compare_image_generation(isp,
5140 			&pri_image_status, &sec_image_status) < 0) {
5141 			active_regions->global = ISP27XX_SECONDARY_IMAGE;
5142 		}
5143 	}
5144 
5145 	isp_prt(isp, ISP_LOGDEBUG0, "active image %s (%u)",
5146 	    active_regions->global == ISP27XX_DEFAULT_IMAGE ?
5147 		"default (boot/fw)" :
5148 	    active_regions->global == ISP27XX_PRIMARY_IMAGE ?
5149 		"primary" :
5150 	    active_regions->global == ISP27XX_SECONDARY_IMAGE ?
5151 		"secondary" : "invalid",
5152 	    active_regions->global);
5153 }
5154 
5155 static bool isp_risc_firmware_invalid(ispsoftc_t *isp, uint32_t *dword)
5156 {
5157 	return ((dword[4] | dword[5] | dword[6] | dword[7]) == 0 ||
5158 	    (~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]) == 0);
5159 }
5160 
5161 static int
5162 isp_load_ram(ispsoftc_t *isp, uint32_t *data, uint32_t risc_addr,
5163     uint32_t risc_code_size)
5164 {
5165 	mbreg_t mbs;
5166 	int rval = ISP_SUCCESS;
5167 
5168 	MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
5169 	MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
5170 	mbs.param[1] = risc_addr;
5171 	mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
5172 	mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
5173 	mbs.param[4] = risc_code_size >> 16;
5174 	mbs.param[5] = risc_code_size;
5175 	mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
5176 	mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
5177 	mbs.param[8] = risc_addr >> 16;
5178 	isp_prt(isp, ISP_LOGDEBUG0,
5179 	    "LOAD RISC RAM %u (0x%x) words at load address 0x%x",
5180 	    risc_code_size, risc_code_size, risc_addr);
5181 	isp_mboxcmd(isp, &mbs);
5182 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5183 		isp_prt(isp, ISP_LOGERR, "F/W download failed");
5184 		rval = ISP_FUNCTION_FAILED;
5185 	}
5186 
5187 	return (rval);
5188 }
5189 
5190 static int
5191 isp_load_risc_flash(ispsoftc_t *isp, uint32_t *srisc_addr, uint32_t faddr)
5192 {
5193 	fcparam *fcp = FCPARAM(isp, 0);
5194 	int rval = ISP_SUCCESS;
5195 	unsigned int segments, fragment;
5196 	unsigned long i;
5197 	unsigned int j;
5198 	unsigned long dlen;
5199 	uint32_t *dcode;
5200 	uint32_t risc_addr, risc_size = 0;
5201 
5202 	isp_prt(isp, ISP_LOGDEBUG0,
5203 	    "Accessing flash firmware at 0x%x.", faddr);
5204 
5205 	dcode = isp->isp_rquest;
5206 	isp_read_flash_data(isp, dcode, faddr, 8);
5207 	if (isp_risc_firmware_invalid(isp, dcode)) {
5208 		snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5209 		    "invalid");
5210 		isp_prt(isp, ISP_LOGERR,
5211 		    "Unable to verify the integrity of flash firmware image.");
5212 		isp_prt(isp, ISP_LOGERR,
5213 		    "Firmware data: 0x%08x 0x%08x 0x%08x 0x%08x.",
5214 		    dcode[0], dcode[1], dcode[2], dcode[3]);
5215 		return (ISP_FUNCTION_FAILED);
5216 	} else {
5217 		for (i = 0; i < 4; i++)
5218 			fcp->fw_flashrev[i] = be32toh(dcode[4 + i]);
5219 		snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5220 		    "%u.%u.%u", fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5221 		    fcp->fw_flashrev[2]);
5222 		isp_prt(isp, ISP_LOGCONFIG,
5223 		    "Firmware revision (flash) %u.%u.%u (%x).",
5224 		    fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5225 		    fcp->fw_flashrev[2], fcp->fw_flashrev[3]);
5226 
5227 		/* If ispfw(4) is loaded compare versions and use the newest */
5228 		if (isp->isp_osinfo.ispfw != NULL) {
5229 			int ispfw_newer = 0;
5230 
5231 			if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) {
5232 				ispfw_newer = 1;
5233 			}
5234 
5235 			if (isp->isp_confopts & ISP_CFG_FWLOAD_FORCE) {
5236 				isp_prt(isp, ISP_LOGCONFIG,
5237 				    "Loading RISC with %s ispfw(4) firmware %s",
5238 				    (ispfw_newer == 0) ? "older" : "newer",
5239 				    "because fwload_force is set");
5240 				return (ISP_ABORTED);
5241 			}
5242 			if (ispfw_newer != 0) {
5243 				isp_prt(isp, ISP_LOGCONFIG,
5244 				    "Loading RISC with newer ispfw(4) firmware");
5245 				return (ISP_ABORTED);
5246 			}
5247 			isp_prt(isp, ISP_LOGCONFIG,
5248 			    "Loading RISC with newer flash firmware");
5249 		}
5250 	}
5251 
5252 	dcode = isp->isp_rquest;
5253 	segments = ISP_RISC_CODE_SEGMENTS;
5254 	for (j = 0; j < segments; j++) {
5255 		isp_prt(isp, ISP_LOGDEBUG0, "Loading segment %u", j);
5256 		isp_read_flash_data(isp, dcode, faddr, 10);
5257 		risc_addr = be32toh(dcode[2]);
5258 		risc_size = be32toh(dcode[3]);
5259 
5260 		dlen = min(risc_size, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
5261 		for (fragment = 0; risc_size; fragment++) {
5262 			if (dlen > risc_size)
5263 				dlen = risc_size;
5264 
5265 			isp_prt(isp, ISP_LOGDEBUG0,
5266 			    "Loading fragment %u: 0x%x <- 0x%x (0x%lx dwords)",
5267 			    fragment, risc_addr, faddr, dlen);
5268 			isp_read_flash_data(isp, dcode, faddr, dlen);
5269 			for (i = 0; i < dlen; i++) {
5270 				dcode[i] = bswap32(dcode[i]);
5271 			}
5272 
5273 			rval = isp_load_ram(isp, dcode, risc_addr, dlen);
5274 			if (rval) {
5275 				isp_prt(isp, ISP_LOGERR,
5276 				    "Failed to load firmware fragment %u.",
5277 				    fragment);
5278 				return (ISP_FUNCTION_FAILED);
5279 			}
5280 
5281 			faddr += dlen;
5282 			risc_addr += dlen;
5283 			risc_size -= dlen;
5284 		}
5285 	}
5286 
5287 	return (rval);
5288 }
5289 
5290 static int
5291 isp_load_risc(ispsoftc_t *isp, uint32_t *srisc_addr)
5292 {
5293 	fcparam *fcp = FCPARAM(isp, 0);
5294 	int rval = ISP_SUCCESS;
5295 	struct active_regions active_regions = { };
5296 
5297 	/*
5298 	 * Starting with 27xx there is a primary and secondary firmware region
5299 	 * in flash. All older controllers just have one firmware region.
5300 	 */
5301 	if (!IS_27XX(isp))
5302 		goto try_primary_fw;
5303 
5304 	isp_get_active_image(isp, &active_regions);
5305 
5306 	if (active_regions.global != ISP27XX_SECONDARY_IMAGE)
5307 		goto try_primary_fw;
5308 
5309 	isp_prt(isp, ISP_LOGCONFIG,
5310 	    "Loading secondary firmware image.");
5311 	rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw_sec);
5312 	return (rval);
5313 
5314 try_primary_fw:
5315 	isp_prt(isp, ISP_LOGCONFIG,
5316 	    "Loading primary firmware image.");
5317 	rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw);
5318 	return (rval);
5319 }
5320 
5321 static int
5322 isp_read_nvram(ispsoftc_t *isp)
5323 {
5324 	fcparam *fcp = FCPARAM(isp, 0);
5325 	int retval = 0;
5326 	uint32_t addr, csum, lwrds, *dptr;
5327 	uint8_t nvram_data[ISP2400_NVRAM_SIZE];
5328 	struct active_regions active_regions = { };
5329 
5330 	if (IS_27XX(isp))
5331 		isp_get_aux_images(isp, &active_regions);
5332 
5333 	addr = fcp->flt_region_nvram;
5334 
5335 	if (IS_28XX(isp)) {
5336 		if (active_regions.aux.vpd_nvram == ISP27XX_SECONDARY_IMAGE)
5337 			addr = fcp->flt_region_nvram_sec;
5338 
5339 		isp_prt(isp, ISP_LOGCONFIG, "Loading %s NVRAM image",
5340 		    active_regions.aux.vpd_nvram == ISP27XX_PRIMARY_IMAGE ?
5341 		    "primary" : "secondary");
5342 	}
5343 
5344 	dptr = (uint32_t *) nvram_data;
5345 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5346 		isp_rd_2xxx_flash(isp, addr++, dptr++);
5347 	}
5348 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5349 	    nvram_data[2] != 'P') {
5350 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
5351 		    nvram_data[0], nvram_data[1], nvram_data[2]);
5352 		retval = -1;
5353 		goto out;
5354 	}
5355 	dptr = (uint32_t *) nvram_data;
5356 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5357 		uint32_t tmp;
5358 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
5359 		csum += tmp;
5360 	}
5361 	if (csum != 0) {
5362 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5363 		retval = -1;
5364 		goto out;
5365 	}
5366 	isp_parse_nvram_2400(isp, nvram_data);
5367 out:
5368 	return (retval);
5369 }
5370 
5371 static void
5372 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
5373 {
5374 	fcparam *fcp = FCPARAM(isp, 0);
5375 	uint64_t wwn;
5376 
5377 	isp_prt(isp, ISP_LOGDEBUG0,
5378 	    "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
5379 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
5380 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
5381 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
5382 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
5383 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
5384 	isp_prt(isp, ISP_LOGDEBUG0,
5385 	    "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
5386 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
5387 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
5388 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
5389 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
5390 
5391 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
5392 	fcp->isp_wwpn_nvram = wwn;
5393 
5394 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
5395 	if (wwn) {
5396 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
5397 			wwn = 0;
5398 		}
5399 	}
5400 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
5401 		wwn = fcp->isp_wwpn_nvram;
5402 		wwn &= ~((uint64_t) 0xfff << 48);
5403 	}
5404 	fcp->isp_wwnn_nvram = wwn;
5405 
5406 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
5407 		DEFAULT_FRAMESIZE(isp) =
5408 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
5409 	}
5410 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
5411 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
5412 	}
5413 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
5414 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
5415 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
5416 }
5417