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