xref: /freebsd/sys/dev/isp/isp.c (revision 2f9966ff63d65bd474478888c9088eeae3f9c669)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  *  Copyright (c) 2009-2020 Alexander Motin <mav@FreeBSD.org>
5  *  Copyright (c) 1997-2009 by Matthew Jacob
6  *  All rights reserved.
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *
12  *  1. Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *  2. Redistributions in binary form must reproduce the above copyright
15  *     notice, this list of conditions and the following disclaimer in the
16  *     documentation and/or other materials provided with the distribution.
17  *
18  *  THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  *  ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22  *  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  *  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  *  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  *  SUCH DAMAGE.
29  *
30  */
31 
32 /*
33  * Machine and OS Independent (well, as best as possible)
34  * code for the Qlogic ISP SCSI and FC-SCSI adapters.
35  */
36 
37 /*
38  * Inspiration and ideas about this driver are from Erik Moe's Linux driver
39  * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
40  * ideas dredged from the Solaris driver.
41  */
42 
43 /*
44  * Include header file appropriate for platform we're building on.
45  */
46 #ifdef	__NetBSD__
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD$");
49 #include <dev/ic/isp_netbsd.h>
50 #endif
51 #ifdef	__FreeBSD__
52 #include <sys/param.h>
53 #include <sys/cdefs.h>
54 #include <sys/firmware.h>
55 #include <dev/isp/isp_freebsd.h>
56 #endif
57 #ifdef	__OpenBSD__
58 #include <dev/ic/isp_openbsd.h>
59 #endif
60 #ifdef	__linux__
61 #include "isp_linux.h"
62 #endif
63 #ifdef	__svr4__
64 #include "isp_solaris.h"
65 #endif
66 
67 /*
68  * Local static data
69  */
70 static const char notresp[] = "Unknown IOCB in RESPONSE Queue (type 0x%x) @ idx %d (next %d)";
71 static const char bun[] = "bad underrun (count %d, resid %d, status %s)";
72 static const char lipd[] = "Chan %d LIP destroyed %d active commands";
73 static const char sacq[] = "unable to acquire scratch area";
74 
75 static const uint8_t alpa_map[] = {
76 	0xef, 0xe8, 0xe4, 0xe2, 0xe1, 0xe0, 0xdc, 0xda,
77 	0xd9, 0xd6, 0xd5, 0xd4, 0xd3, 0xd2, 0xd1, 0xce,
78 	0xcd, 0xcc, 0xcb, 0xca, 0xc9, 0xc7, 0xc6, 0xc5,
79 	0xc3, 0xbc, 0xba, 0xb9, 0xb6, 0xb5, 0xb4, 0xb3,
80 	0xb2, 0xb1, 0xae, 0xad, 0xac, 0xab, 0xaa, 0xa9,
81 	0xa7, 0xa6, 0xa5, 0xa3, 0x9f, 0x9e, 0x9d, 0x9b,
82 	0x98, 0x97, 0x90, 0x8f, 0x88, 0x84, 0x82, 0x81,
83 	0x80, 0x7c, 0x7a, 0x79, 0x76, 0x75, 0x74, 0x73,
84 	0x72, 0x71, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69,
85 	0x67, 0x66, 0x65, 0x63, 0x5c, 0x5a, 0x59, 0x56,
86 	0x55, 0x54, 0x53, 0x52, 0x51, 0x4e, 0x4d, 0x4c,
87 	0x4b, 0x4a, 0x49, 0x47, 0x46, 0x45, 0x43, 0x3c,
88 	0x3a, 0x39, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31,
89 	0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x27, 0x26,
90 	0x25, 0x23, 0x1f, 0x1e, 0x1d, 0x1b, 0x18, 0x17,
91 	0x10, 0x0f, 0x08, 0x04, 0x02, 0x01, 0x00
92 };
93 
94 /*
95  * Local function prototypes.
96  */
97 static int isp_handle_control(ispsoftc_t *, isphdr_t *);
98 static void isp_handle_rpt_id_acq(ispsoftc_t *, isphdr_t *);
99 static void isp_parse_status_24xx(ispsoftc_t *, isp24xx_statusreq_t *, XS_T *);
100 static void isp_clear_portdb(ispsoftc_t *, int);
101 static void isp_mark_portdb(ispsoftc_t *, int);
102 static int isp_plogx(ispsoftc_t *, int, uint16_t, uint32_t, int);
103 static int isp_getpdb(ispsoftc_t *, int, uint16_t, isp_pdb_t *);
104 static int isp_gethandles(ispsoftc_t *, int, uint16_t *, int *, int);
105 static void isp_dump_chip_portdb(ispsoftc_t *, int);
106 static uint64_t isp_get_wwn(ispsoftc_t *, int, int, int);
107 static int isp_fclink_test(ispsoftc_t *, int, int);
108 static int isp_pdb_sync(ispsoftc_t *, int);
109 static int isp_scan_loop(ispsoftc_t *, int);
110 static int isp_gid_pt(ispsoftc_t *, int);
111 static int isp_scan_fabric(ispsoftc_t *, int);
112 static int isp_login_device(ispsoftc_t *, int, uint32_t, isp_pdb_t *, uint16_t *);
113 static int isp_register_fc4_type(ispsoftc_t *, int);
114 static int isp_register_fc4_features_24xx(ispsoftc_t *, int);
115 static int isp_register_port_name_24xx(ispsoftc_t *, int);
116 static int isp_register_node_name_24xx(ispsoftc_t *, int);
117 static uint16_t isp_next_handle(ispsoftc_t *, uint16_t *);
118 static int isp_fw_state(ispsoftc_t *, int);
119 static void isp_mboxcmd(ispsoftc_t *, mbreg_t *);
120 
121 static void isp_get_flash_addrs(ispsoftc_t *);
122 static void isp_setdfltfcparm(ispsoftc_t *, int);
123 static int isp_read_flash_dword(ispsoftc_t *, uint32_t, uint32_t *);
124 static int isp_read_flash_data(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
125 static void isp_rd_2xxx_flash(ispsoftc_t *, uint32_t, uint32_t *);
126 static int isp_read_flthdr_2xxx(ispsoftc_t *);
127 static void isp_parse_flthdr_2xxx(ispsoftc_t *, uint8_t *);
128 static int isp_read_flt_2xxx(ispsoftc_t *);
129 static int isp_parse_flt_2xxx(ispsoftc_t *, uint8_t *);
130 static int isp_read_nvram(ispsoftc_t *);
131 static void isp_parse_nvram_2400(ispsoftc_t *, uint8_t *);
132 
133 static void isp_print_image(ispsoftc_t *, char *, struct isp_image_status *);
134 static bool isp_check_aux_image_status_signature(struct isp_image_status *);
135 static bool isp_check_image_status_signature(struct isp_image_status *);
136 static unsigned long isp_image_status_checksum(struct isp_image_status *);
137 static void isp_component_status(struct active_regions *, struct isp_image_status *);
138 static int isp_compare_image_generation(ispsoftc_t *, struct isp_image_status *, struct isp_image_status *);
139 static void isp_get_aux_images(ispsoftc_t *, struct active_regions *);
140 static void isp_get_active_image(ispsoftc_t *, struct active_regions *);
141 static bool isp_risc_firmware_invalid(ispsoftc_t *, uint32_t *);
142 static int isp_load_ram(ispsoftc_t *, uint32_t *, uint32_t, uint32_t);
143 static int isp_load_risc_flash(ispsoftc_t *, uint32_t *, uint32_t);
144 static int isp_load_risc(ispsoftc_t *, uint32_t *);
145 
146 static void
147 isp_change_fw_state(ispsoftc_t *isp, int chan, int state)
148 {
149 	fcparam *fcp = FCPARAM(isp, chan);
150 
151 	if (fcp->isp_fwstate == state)
152 		return;
153 	isp_prt(isp, ISP_LOGCONFIG|ISP_LOG_SANCFG,
154 	    "Chan %d Firmware state <%s->%s>", chan,
155 	    isp_fc_fw_statename(fcp->isp_fwstate), isp_fc_fw_statename(state));
156 	fcp->isp_fwstate = state;
157 }
158 
159 static void
160 isp_get_flash_addrs(ispsoftc_t *isp)
161 {
162 	fcparam *fcp = FCPARAM(isp, 0);
163 	int r = 0;
164 
165 	if (IS_28XX(isp)) {
166 		fcp->flash_data_addr = ISP28XX_BASE_ADDR;
167 		fcp->flt_region_flt = ISP28XX_FLT_ADDR;
168 	} else if (IS_26XX(isp)) {	/* 26xx and 27xx are identical */
169 		fcp->flash_data_addr = ISP27XX_BASE_ADDR;
170 		fcp->flt_region_flt = ISP27XX_FLT_ADDR;
171 	} else if (IS_25XX(isp)) {
172 		fcp->flash_data_addr = ISP25XX_BASE_ADDR;
173 		fcp->flt_region_flt = ISP25XX_FLT_ADDR;
174 	} else {
175 		fcp->flash_data_addr = ISP24XX_BASE_ADDR;
176 		fcp->flt_region_flt = ISP24XX_FLT_ADDR;
177 	}
178 	fcp->flt_length = 0;
179 	r = isp_read_flthdr_2xxx(isp);
180 	if (r == 0) {
181 		isp_read_flt_2xxx(isp);
182 	} else { /* fallback to hardcoded NVRAM address */
183 		if (IS_28XX(isp)) {
184 			fcp->flt_region_nvram = 0x300000;
185 		} else if (IS_26XX(isp)) {
186 			fcp->flash_data_addr = 0x7fe7c000;
187 			fcp->flt_region_nvram = 0;
188 		} else if (IS_25XX(isp)) {
189 			fcp->flt_region_nvram = 0x48000;
190 		} else {
191 			fcp->flash_data_addr = 0x7ffe0000;
192 			fcp->flt_region_nvram = 0;
193 		}
194 		fcp->flt_region_nvram += ISP2400_NVRAM_PORT_ADDR(isp->isp_port);
195 	}
196 }
197 
198 /*
199  * Reset Hardware.
200  *
201  * Hit the chip over the head, download new f/w if available and set it running.
202  *
203  * Locking done elsewhere.
204  */
205 
206 void
207 isp_reset(ispsoftc_t *isp, int do_load_defaults)
208 {
209 	mbreg_t mbs;
210 	char *buf;
211 	uint16_t fwt;
212 	uint32_t code_org, val;
213 	int loaded_fw, loops, i, dodnld = 1;
214 	const char *btype = "????";
215 	static const char dcrc[] = "Downloaded RISC Code Checksum Failure";
216 
217 	isp->isp_state = ISP_NILSTATE;
218 	ISP_DISABLE_INTS(isp);
219 
220 	/*
221 	 * Put the board into PAUSE mode (so we can read the SXP registers
222 	 * or write FPM/FBM registers).
223 	 */
224 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_HOST_INT);
225 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
226 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_PAUSE);
227 
228 	switch (isp->isp_type) {
229 	case ISP_HA_FC_2400:
230 		btype = "2422";
231 		break;
232 	case ISP_HA_FC_2500:
233 		btype = "2532";
234 		break;
235 	case ISP_HA_FC_2600:
236 		btype = "2600";
237 		break;
238 	case ISP_HA_FC_2700:
239 		btype = "2700";
240 		break;
241 	case ISP_HA_FC_2800:
242 		btype = "2800";
243 		break;
244 	default:
245 		break;
246 	}
247 
248 	/*
249 	 * Stop DMA and wait for it to stop.
250 	 */
251 	ISP_WRITE(isp, BIU2400_CSR, BIU2400_DMA_STOP|(3 << 4));
252 	for (loops = 0; loops < 100000; loops++) {
253 		ISP_DELAY(10);
254 		val = ISP_READ(isp, BIU2400_CSR);
255 		if ((val & BIU2400_DMA_ACTIVE) == 0) {
256 			break;
257 		}
258 	}
259 	if (val & BIU2400_DMA_ACTIVE)
260 		isp_prt(isp, ISP_LOGERR, "DMA Failed to Stop on Reset");
261 
262 	/*
263 	 * Hold it in SOFT_RESET and STOP state for 100us.
264 	 */
265 	ISP_WRITE(isp, BIU2400_CSR, BIU2400_SOFT_RESET|BIU2400_DMA_STOP|(3 << 4));
266 	ISP_DELAY(100);
267 	for (loops = 0; loops < 10000; loops++) {
268 		ISP_DELAY(5);
269 		val = ISP_READ(isp, OUTMAILBOX0);
270 		if (val != 0x4)
271 			break;
272 	}
273 	switch (val) {
274 	case 0x0:
275 		break;
276 	case 0x4:
277 		isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
278 		return;
279 	case 0xf:
280 		isp_prt(isp, ISP_LOGERR, "Board configuration error.");
281 		return;
282 	default:
283 		isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
284 		return;
285 	}
286 
287 	/*
288 	 * Reset RISC Processor
289 	 */
290 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RESET);
291 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_RELEASE);
292 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RESET);
293 
294 	/*
295 	 * Post-RISC Reset stuff.
296 	 */
297 	for (loops = 0; loops < 10000; loops++) {
298 		ISP_DELAY(5);
299 		val = ISP_READ(isp, OUTMAILBOX0);
300 		if (val != 0x4)
301 			break;
302 	}
303 	switch (val) {
304 	case 0x0:
305 		break;
306 	case 0x4:
307 		isp_prt(isp, ISP_LOGERR, "The ROM code is busy after 50ms.");
308 		return;
309 	case 0xf:
310 		isp_prt(isp, ISP_LOGERR, "Board configuration error.");
311 		return;
312 	default:
313 		isp_prt(isp, ISP_LOGERR, "Unknown RISC Status Code 0x%x.", val);
314 		return;
315 	}
316 
317 	isp->isp_reqidx = isp->isp_reqodx = 0;
318 	isp->isp_resodx = 0;
319 	isp->isp_atioodx = 0;
320 	ISP_WRITE(isp, BIU2400_REQINP, 0);
321 	ISP_WRITE(isp, BIU2400_REQOUTP, 0);
322 	ISP_WRITE(isp, BIU2400_RSPINP, 0);
323 	ISP_WRITE(isp, BIU2400_RSPOUTP, 0);
324 	if (!IS_26XX(isp)) {
325 		ISP_WRITE(isp, BIU2400_PRI_REQINP, 0);
326 		ISP_WRITE(isp, BIU2400_PRI_REQOUTP, 0);
327 	}
328 	ISP_WRITE(isp, BIU2400_ATIO_RSPINP, 0);
329 	ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, 0);
330 
331 	/*
332 	 * Up until this point we've done everything by just reading or
333 	 * setting registers. From this point on we rely on at least *some*
334 	 * kind of firmware running in the card.
335 	 */
336 
337 	/*
338 	 * Do some sanity checking by running a NOP command.
339 	 * If it succeeds, the ROM firmware is now running.
340 	 */
341 	MBSINIT(&mbs, MBOX_NO_OP, MBLOGALL, 0);
342 	isp_mboxcmd(isp, &mbs);
343 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
344 		isp_prt(isp, ISP_LOGERR, "NOP command failed (%x)", mbs.param[0]);
345 		return;
346 	}
347 
348 	/*
349 	 * Do some operational tests
350 	 */
351 	{
352 		static const uint16_t patterns[MAX_MAILBOX] = {
353 			0x0000, 0xdead, 0xbeef, 0xffff,
354 			0xa5a5, 0x5a5a, 0x7f7f, 0x7ff7,
355 			0x3421, 0xabcd, 0xdcba, 0xfeef,
356 			0xbead, 0xdebe, 0x2222, 0x3333,
357 			0x5555, 0x6666, 0x7777, 0xaaaa,
358 			0xffff, 0xdddd, 0x9999, 0x1fbc,
359 			0x6666, 0x6677, 0x1122, 0x33ff,
360 			0x0000, 0x0001, 0x1000, 0x1010,
361 		};
362 		int nmbox = ISP_NMBOX(isp);
363 		MBSINIT(&mbs, MBOX_MAILBOX_REG_TEST, MBLOGALL, 0);
364 		for (i = 1; i < nmbox; i++) {
365 			mbs.param[i] = patterns[i];
366 		}
367 		isp_mboxcmd(isp, &mbs);
368 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
369 			return;
370 		}
371 		for (i = 1; i < nmbox; i++) {
372 			if (mbs.param[i] != patterns[i]) {
373 				isp_prt(isp, ISP_LOGERR, "Register Test Failed at Register %d: should have 0x%04x but got 0x%04x", i, patterns[i], mbs.param[i]);
374 				return;
375 			}
376 		}
377 	}
378 
379 	/*
380 	 * Early setup DMA for the request and response queues.
381 	 * We do this now so we can use the request queue
382 	 * for dma to load firmware from.
383 	 */
384 
385 	if (ISP_MBOXDMASETUP(isp) != 0) {
386 		isp_prt(isp, ISP_LOGERR, "Cannot setup DMA");
387 		return;
388 	}
389 
390 	/*
391 	 * FW load priority
392 	 * For 27xx and newer:
393 	 * Load ispfw(4) firmware unless requested not to do so.
394 	 * Request (active) flash firmware information. Compare
395 	 * version numbers of ispfw(4) and flash firmware. Load
396 	 * the highest version into RAM of the adapter.
397 	 * If loading ispfw(4) is disabled or loading it failed
398 	 * (eg. no firmware available) we just load firmware from
399 	 * flash. If this fails for whatever reason we fallback
400 	 * to let the adapter MBOX_LOAD_FLASH_FIRMWARE by itself
401 	 * followed by MBOX_EXEC_FIRMWARE and hope the best to
402 	 * get it up and running.
403 	 *
404 	 * For 26xx and older:
405 	 * Load ispfw(4) firmware unless requested not to do so
406 	 * and load it into RAM of the adapter. If loading
407 	 * ispfw(4) is disabled or loading it failed (eg. no
408 	 * firmware available) we just let the adapter
409 	 * MBOX_EXEC_FIRMWARE to start the flash firmware.
410 	 * For the 26xx a preceding MBOX_LOAD_FLASH_FIRMWARE
411 	 * is required.
412 	 */
413 
414 	fcparam *fcp = FCPARAM(isp, 0);
415 
416 	/* read FLT to get flash region addresses */
417 	isp_get_flash_addrs(isp);
418 
419 	/* set informational sysctl(8) to sane value */
420 	snprintf(fcp->fw_version_ispfw, sizeof(fcp->fw_version_ispfw),
421 	    "not loaded");
422 	snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
423 	    "not loaded");
424 	snprintf(fcp->fw_version_run, sizeof(fcp->fw_version_run),
425 	    "not loaded");
426 
427 
428 	/* Try to load ispfw(4) first */
429 	if (!(isp->isp_confopts & ISP_CFG_NORELOAD)) {
430 		char fwname[32];
431 		snprintf(fwname, sizeof(fwname), "isp_%04x", isp->isp_did);
432 		isp->isp_osinfo.ispfw = firmware_get(fwname);
433 		if (isp->isp_osinfo.ispfw != NULL) {
434 			isp->isp_mdvec->dv_ispfw = isp->isp_osinfo.ispfw->data;
435 			const uint32_t *ispfwptr = isp->isp_mdvec->dv_ispfw;
436 			for (i = 0; i < 4; i++)
437 				fcp->fw_ispfwrev[i] = ispfwptr[4 + i];
438 			isp_prt(isp, ISP_LOGCONFIG,
439 			    "Loaded ispfw(4) firmware %s", fwname);
440 			snprintf(fcp->fw_version_ispfw,
441 			    sizeof(fcp->fw_version_ispfw),
442 			    "%u.%u.%u", fcp->fw_ispfwrev[0],
443 			    fcp->fw_ispfwrev[1], fcp->fw_ispfwrev[2]);
444 			isp_prt(isp, ISP_LOGCONFIG,
445 			    "Firmware revision (ispfw) %u.%u.%u (%x).",
446 			    fcp->fw_ispfwrev[0], fcp->fw_ispfwrev[1],
447 			    fcp->fw_ispfwrev[2], fcp->fw_ispfwrev[3]);
448 		} else {
449 			isp_prt(isp, ISP_LOGDEBUG0,
450 			    "Unable to load ispfw(4) firmware %s", fwname);
451 		}
452 	}
453 
454 	loaded_fw = 0;
455 	dodnld = 0;
456 
457 	if (IS_27XX(isp)) {
458 		switch (isp_load_risc(isp, 0)) {
459 		case ISP_ABORTED:
460 			/* 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 	}
3092 	case ISPCTL_FCLINK_TEST:
3093 	{
3094 		int usdelay;
3095 
3096 		va_start(ap, ctl);
3097 		chan = va_arg(ap, int);
3098 		usdelay = va_arg(ap, int);
3099 		va_end(ap);
3100 		if (usdelay == 0)
3101 			usdelay = 250000;
3102 		return (isp_fclink_test(isp, chan, usdelay));
3103 	}
3104 	case ISPCTL_SCAN_FABRIC:
3105 
3106 		va_start(ap, ctl);
3107 		chan = va_arg(ap, int);
3108 		va_end(ap);
3109 		return (isp_scan_fabric(isp, chan));
3110 
3111 	case ISPCTL_SCAN_LOOP:
3112 
3113 		va_start(ap, ctl);
3114 		chan = va_arg(ap, int);
3115 		va_end(ap);
3116 		return (isp_scan_loop(isp, chan));
3117 
3118 	case ISPCTL_PDB_SYNC:
3119 
3120 		va_start(ap, ctl);
3121 		chan = va_arg(ap, int);
3122 		va_end(ap);
3123 		return (isp_pdb_sync(isp, chan));
3124 
3125 	case ISPCTL_SEND_LIP:
3126 		break;
3127 
3128 	case ISPCTL_GET_PDB:
3129 	{
3130 		isp_pdb_t *pdb;
3131 		va_start(ap, ctl);
3132 		chan = va_arg(ap, int);
3133 		tgt = va_arg(ap, int);
3134 		pdb = va_arg(ap, isp_pdb_t *);
3135 		va_end(ap);
3136 		return (isp_getpdb(isp, chan, tgt, pdb));
3137 	}
3138 	case ISPCTL_GET_NAMES:
3139 	{
3140 		uint64_t *wwnn, *wwnp;
3141 		va_start(ap, ctl);
3142 		chan = va_arg(ap, int);
3143 		tgt = va_arg(ap, int);
3144 		wwnn = va_arg(ap, uint64_t *);
3145 		wwnp = va_arg(ap, uint64_t *);
3146 		va_end(ap);
3147 		if (wwnn == NULL && wwnp == NULL) {
3148 			break;
3149 		}
3150 		if (wwnn) {
3151 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
3152 			if (*wwnn == INI_NONE) {
3153 				break;
3154 			}
3155 		}
3156 		if (wwnp) {
3157 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
3158 			if (*wwnp == INI_NONE) {
3159 				break;
3160 			}
3161 		}
3162 		return (0);
3163 	}
3164 	case ISPCTL_RUN_MBOXCMD:
3165 	{
3166 		va_start(ap, ctl);
3167 		mbr = va_arg(ap, mbreg_t *);
3168 		va_end(ap);
3169 		isp_mboxcmd(isp, mbr);
3170 		return (0);
3171 	}
3172 	case ISPCTL_PLOGX:
3173 	{
3174 		isp_plcmd_t *p;
3175 		int r;
3176 
3177 		va_start(ap, ctl);
3178 		p = va_arg(ap, isp_plcmd_t *);
3179 		va_end(ap);
3180 
3181 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
3182 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags));
3183 		}
3184 		do {
3185 			isp_next_handle(isp, &p->handle);
3186 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags);
3187 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3188 				p->handle = r >> 16;
3189 				r = 0;
3190 				break;
3191 			}
3192 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
3193 		return (r);
3194 	}
3195 	case ISPCTL_CHANGE_ROLE:
3196 	{
3197 		int role;
3198 
3199 		va_start(ap, ctl);
3200 		chan = va_arg(ap, int);
3201 		role = va_arg(ap, int);
3202 		va_end(ap);
3203 		return (isp_fc_change_role(isp, chan, role));
3204 	}
3205 	default:
3206 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
3207 		break;
3208 
3209 	}
3210 	return (-1);
3211 }
3212 
3213 /*
3214  * Interrupt Service Routine(s).
3215  *
3216  * External (OS) framework has done the appropriate locking,
3217  * and the locking will be held throughout this function.
3218  */
3219 
3220 #ifdef	ISP_TARGET_MODE
3221 void
3222 isp_intr_atioq(ispsoftc_t *isp)
3223 {
3224 	void *addr;
3225 	uint32_t iptr, optr, oop;
3226 
3227 	iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
3228 	optr = isp->isp_atioodx;
3229 	while (optr != iptr) {
3230 		oop = optr;
3231 		MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
3232 		addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
3233 		switch (((isphdr_t *)addr)->rqs_entry_type) {
3234 		case RQSTYPE_NOTIFY:
3235 		case RQSTYPE_ATIO:
3236 		case RQSTYPE_NOTIFY_ACK:	/* Can be set to ATIO queue.*/
3237 		case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue.*/
3238 			(void) isp_target_notify(isp, addr, &oop,
3239 			    ATIO_QUEUE_LEN(isp));
3240 			break;
3241 		case RQSTYPE_RPT_ID_ACQ:	/* Can be set to ATIO queue.*/
3242 		default:
3243 			isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
3244 			break;
3245 		}
3246 		optr = ISP_NXT_QENTRY(oop, ATIO_QUEUE_LEN(isp));
3247 	}
3248 	if (isp->isp_atioodx != optr) {
3249 		ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
3250 		isp->isp_atioodx = optr;
3251 	}
3252 }
3253 #endif
3254 
3255 void
3256 isp_intr_mbox(ispsoftc_t *isp, uint16_t mbox0)
3257 {
3258 	int i, obits;
3259 
3260 	if (!isp->isp_mboxbsy) {
3261 		isp_prt(isp, ISP_LOGWARN, "mailbox 0x%x with no waiters", mbox0);
3262 		return;
3263 	}
3264 	obits = isp->isp_obits;
3265 	isp->isp_mboxtmp[0] = mbox0;
3266 	for (i = 1; i < ISP_NMBOX(isp); i++) {
3267 		if ((obits & (1 << i)) == 0)
3268 			continue;
3269 		isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
3270 	}
3271 	isp->isp_mboxbsy = 0;
3272 }
3273 
3274 void
3275 isp_intr_respq(ispsoftc_t *isp)
3276 {
3277 	XS_T *xs, *cont_xs;
3278 	uint8_t qe[QENTRY_LEN];
3279 	isp24xx_statusreq_t *sp = (isp24xx_statusreq_t *)qe;
3280 	ispstatus_cont_t *scp = (ispstatus_cont_t *)qe;
3281 	isphdr_t *hp;
3282 	uint8_t *resp, *snsp, etype;
3283 	uint16_t scsi_status;
3284 	uint32_t iptr, cont = 0, cptr, optr, rlen, slen, totslen;
3285 #ifdef	ISP_TARGET_MODE
3286 	uint32_t sptr;
3287 #endif
3288 
3289 	/*
3290 	 * We can't be getting this now.
3291 	 */
3292 	if (isp->isp_state != ISP_RUNSTATE) {
3293 		isp_prt(isp, ISP_LOGINFO, "respq interrupt when not ready");
3294 		return;
3295 	}
3296 
3297 	iptr = ISP_READ(isp, BIU2400_RSPINP);
3298 	optr = isp->isp_resodx;
3299 	while (optr != iptr) {
3300 		cptr = optr;
3301 #ifdef	ISP_TARGET_MODE
3302 		sptr = optr;
3303 #endif
3304 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, cptr);
3305 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
3306 
3307 		/*
3308 		 * Synchronize our view of this response queue entry.
3309 		 */
3310 		MEMORYBARRIER(isp, SYNC_RESULT, cptr, QENTRY_LEN, -1);
3311 		if (isp->isp_dblev & ISP_LOGDEBUG1)
3312 			isp_print_qentry(isp, "Response Queue Entry", cptr, hp);
3313 		isp_get_hdr(isp, hp, &sp->req_header);
3314 
3315 		/*
3316 		 * Log IOCBs rejected by the firmware.  We can't really do
3317 		 * much more about them, since it just should not happen.
3318 		 */
3319 		if (sp->req_header.rqs_flags & RQSFLAG_BADTYPE) {
3320 			isp_print_qentry(isp, "invalid entry type", cptr, hp);
3321 			continue;
3322 		}
3323 		if (sp->req_header.rqs_flags & RQSFLAG_BADPARAM) {
3324 			isp_print_qentry(isp, "invalid entry parameter", cptr, hp);
3325 			continue;
3326 		}
3327 		if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
3328 			isp_print_qentry(isp, "invalid entry count", cptr, hp);
3329 			continue;
3330 		}
3331 		if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
3332 			isp_print_qentry(isp, "invalid entry order", cptr, hp);
3333 			continue;
3334 		}
3335 
3336 		etype = sp->req_header.rqs_entry_type;
3337 
3338 		/* We expected Status Continuation, but got different IOCB. */
3339 		if (cont > 0 && etype != RQSTYPE_STATUS_CONT) {
3340 			cont = 0;
3341 			isp_done(cont_xs);
3342 		}
3343 
3344 		if (isp_handle_control(isp, hp)) {
3345 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3346 			continue;
3347 		}
3348 
3349 		switch (etype) {
3350 		case RQSTYPE_RESPONSE:
3351 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp);
3352 			break;
3353 		case RQSTYPE_MARKER:
3354 			isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
3355 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3356 			continue;
3357 		case RQSTYPE_STATUS_CONT:
3358 			isp_get_cont_response(isp, (ispstatus_cont_t *)hp, scp);
3359 			if (cont > 0) {
3360 				slen = min(cont, sizeof(scp->req_sense_data));
3361 				XS_SENSE_APPEND(cont_xs, scp->req_sense_data, slen);
3362 				cont -= slen;
3363 				if (cont == 0) {
3364 					isp_done(cont_xs);
3365 				} else {
3366 					isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3367 					    "Expecting Status Continuations for %u bytes",
3368 					    cont);
3369 				}
3370 			} else {
3371 				isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
3372 			}
3373 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3374 			continue;
3375 #ifdef	ISP_TARGET_MODE
3376 		case RQSTYPE_NOTIFY_ACK:	/* Can be set to ATIO queue. */
3377 		case RQSTYPE_CTIO7:
3378 		case RQSTYPE_ABTS_RCVD:		/* Can be set to ATIO queue. */
3379 		case RQSTYPE_ABTS_RSP:
3380 			isp_target_notify(isp, hp, &cptr, RESULT_QUEUE_LEN(isp));
3381 			/* More then one IOCB could be consumed. */
3382 			while (sptr != cptr) {
3383 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3384 				sptr = ISP_NXT_QENTRY(sptr, RESULT_QUEUE_LEN(isp));
3385 				hp = (isphdr_t *)ISP_QUEUE_ENTRY(isp->isp_result, sptr);
3386 			}
3387 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3388 			optr = ISP_NXT_QENTRY(cptr, RESULT_QUEUE_LEN(isp));
3389 			continue;
3390 #endif
3391 		case RQSTYPE_RPT_ID_ACQ:	/* Can be set to ATIO queue.*/
3392 			isp_handle_rpt_id_acq(isp, hp);
3393 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3394 			continue;
3395 		default:
3396 			/* We don't know what was this -- log and skip. */
3397 			isp_prt(isp, ISP_LOGERR, notresp, etype, cptr, optr);
3398 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3399 			continue;
3400 		}
3401 
3402 		xs = isp_find_xs(isp, sp->req_handle);
3403 		if (xs == NULL) {
3404 			/*
3405 			 * Only whine if this isn't the expected fallout of
3406 			 * aborting the command or resetting the target.
3407 			 */
3408 			if (sp->req_completion_status != RQCS_ABORTED &&
3409 			    sp->req_completion_status != RQCS_RESET_OCCURRED)
3410 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)",
3411 				    sp->req_handle, sp->req_completion_status);
3412 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3413 			continue;
3414 		}
3415 
3416 		resp = snsp = sp->req_rsp_sense;
3417 		rlen = slen = totslen = 0;
3418 		scsi_status = sp->req_scsi_status;
3419 		if (scsi_status & RQCS_RV) {
3420 			rlen = sp->req_response_len;
3421 			snsp += rlen;
3422 		}
3423 		if (scsi_status & RQCS_SV) {
3424 			totslen = sp->req_sense_len;
3425 			slen = MIN(totslen, sizeof(sp->req_rsp_sense) - rlen);
3426 		}
3427 		*XS_STSP(xs) = scsi_status & 0xff;
3428 		if (scsi_status & RQCS_RESID)
3429 			XS_SET_RESID(xs, sp->req_fcp_residual);
3430 		else
3431 			XS_SET_RESID(xs, 0);
3432 
3433 		if (rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
3434 			const char *ptr;
3435 			char lb[64];
3436 			const char *rnames[10] = {
3437 			    "Task Management function complete",
3438 			    "FCP_DATA length different than FCP_BURST_LEN",
3439 			    "FCP_CMND fields invalid",
3440 			    "FCP_DATA parameter mismatch with FCP_DATA_RO",
3441 			    "Task Management function rejected",
3442 			    "Task Management function failed",
3443 			    NULL,
3444 			    NULL,
3445 			    "Task Management function succeeded",
3446 			    "Task Management function incorrect logical unit number",
3447 			};
3448 			uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
3449 			if (code >= nitems(rnames) || rnames[code] == NULL) {
3450 				ISP_SNPRINTF(lb, sizeof(lb),
3451 				    "Unknown FCP Response Code 0x%x", code);
3452 				ptr = lb;
3453 			} else {
3454 				ptr = rnames[code];
3455 			}
3456 			isp_xs_prt(isp, xs, ISP_LOGWARN,
3457 			    "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
3458 			    rlen, ptr, XS_CDBP(xs)[0] & 0xff);
3459 			if (code != FCP_RSPNS_TMF_DONE &&
3460 			    code != FCP_RSPNS_TMF_SUCCEEDED)
3461 				XS_SETERR(xs, HBA_BOTCH);
3462 		}
3463 		isp_parse_status_24xx(isp, sp, xs);
3464 		if (slen > 0) {
3465 			XS_SAVE_SENSE(xs, snsp, slen);
3466 			if (totslen > slen) {
3467 				cont = totslen - slen;
3468 				cont_xs = xs;
3469 				isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN,
3470 				    "Expecting Status Continuations for %u bytes",
3471 				    cont);
3472 			}
3473 		}
3474 
3475 		ISP_DMAFREE(isp, xs);
3476 		isp_destroy_handle(isp, sp->req_handle);
3477 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
3478 
3479 		/* Complete command if we expect no Status Continuations. */
3480 		if (cont == 0)
3481 			isp_done(xs);
3482 	}
3483 
3484 	/* We haven't received all Status Continuations, but that is it. */
3485 	if (cont > 0)
3486 		isp_done(cont_xs);
3487 
3488 	/* If we processed any IOCBs, let ISP know about it. */
3489 	if (optr != isp->isp_resodx) {
3490 		ISP_WRITE(isp, BIU2400_RSPOUTP, optr);
3491 		isp->isp_resodx = optr;
3492 	}
3493 }
3494 
3495 
3496 void
3497 isp_intr_async(ispsoftc_t *isp, uint16_t mbox)
3498 {
3499 	fcparam *fcp;
3500 	uint16_t chan;
3501 
3502 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
3503 
3504 	switch (mbox) {
3505 	case ASYNC_SYSTEM_ERROR:
3506 		isp->isp_state = ISP_CRASHED;
3507 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3508 			FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
3509 			isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
3510 		}
3511 		/*
3512 		 * Were we waiting for a mailbox command to complete?
3513 		 * If so, it's dead, so wake up the waiter.
3514 		 */
3515 		if (isp->isp_mboxbsy) {
3516 			isp->isp_obits = 1;
3517 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
3518 			isp->isp_mboxbsy = 0;
3519 		}
3520 		/*
3521 		 * It's up to the handler for isp_async to reinit stuff and
3522 		 * restart the firmware
3523 		 */
3524 		isp_async(isp, ISPASYNC_FW_CRASH);
3525 		break;
3526 
3527 	case ASYNC_RQS_XFER_ERR:
3528 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
3529 		break;
3530 
3531 	case ASYNC_RSP_XFER_ERR:
3532 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
3533 		break;
3534 
3535 	case ASYNC_ATIO_XFER_ERR:
3536 		isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
3537 		break;
3538 
3539 	case ASYNC_LIP_OCCURRED:
3540 	case ASYNC_LIP_NOS_OLS_RECV:
3541 	case ASYNC_LIP_ERROR:
3542 	case ASYNC_PTPMODE:
3543 		/*
3544 		 * These are broadcast events that have to be sent across
3545 		 * all active channels.
3546 		 */
3547 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3548 			fcp = FCPARAM(isp, chan);
3549 			int topo = fcp->isp_topo;
3550 
3551 			if (fcp->role == ISP_ROLE_NONE)
3552 				continue;
3553 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3554 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3555 			ISP_SET_SENDMARKER(isp, chan, 1);
3556 			isp_async(isp, ISPASYNC_LIP, chan);
3557 #ifdef	ISP_TARGET_MODE
3558 			isp_target_async(isp, chan, mbox);
3559 #endif
3560 			/*
3561 			 * We've had problems with data corruption occurring on
3562 			 * commands that complete (with no apparent error) after
3563 			 * we receive a LIP. This has been observed mostly on
3564 			 * Local Loop topologies. To be safe, let's just mark
3565 			 * all active initiator commands as dead.
3566 			 */
3567 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
3568 				int i, j;
3569 				for (i = j = 0; i < ISP_HANDLE_NUM(isp); i++) {
3570 					XS_T *xs;
3571 					isp_hdl_t *hdp;
3572 
3573 					hdp = &isp->isp_xflist[i];
3574 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
3575 						continue;
3576 					}
3577 					xs = hdp->cmd;
3578 					if (XS_CHANNEL(xs) != chan) {
3579 						continue;
3580 					}
3581 					j++;
3582 					isp_prt(isp, ISP_LOG_WARN1,
3583 					    "%d.%d.%jx bus reset set at %s:%u",
3584 					    XS_CHANNEL(xs), XS_TGT(xs),
3585 					    (uintmax_t)XS_LUN(xs),
3586 					    __func__, __LINE__);
3587 					XS_SETERR(xs, HBA_BUSRESET);
3588 				}
3589 				if (j) {
3590 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
3591 				}
3592 			}
3593 		}
3594 		break;
3595 
3596 	case ASYNC_LOOP_UP:
3597 		/*
3598 		 * This is a broadcast event that has to be sent across
3599 		 * all active channels.
3600 		 */
3601 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3602 			fcp = FCPARAM(isp, chan);
3603 			if (fcp->role == ISP_ROLE_NONE)
3604 				continue;
3605 			fcp->isp_linkstate = 1;
3606 			if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3607 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3608 			ISP_SET_SENDMARKER(isp, chan, 1);
3609 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
3610 #ifdef	ISP_TARGET_MODE
3611 			isp_target_async(isp, chan, mbox);
3612 #endif
3613 		}
3614 		break;
3615 
3616 	case ASYNC_LOOP_DOWN:
3617 		/*
3618 		 * This is a broadcast event that has to be sent across
3619 		 * all active channels.
3620 		 */
3621 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3622 			fcp = FCPARAM(isp, chan);
3623 			if (fcp->role == ISP_ROLE_NONE)
3624 				continue;
3625 			ISP_SET_SENDMARKER(isp, chan, 1);
3626 			fcp->isp_linkstate = 0;
3627 			fcp->isp_loopstate = LOOP_NIL;
3628 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
3629 #ifdef	ISP_TARGET_MODE
3630 			isp_target_async(isp, chan, mbox);
3631 #endif
3632 		}
3633 		break;
3634 
3635 	case ASYNC_LOOP_RESET:
3636 		/*
3637 		 * This is a broadcast event that has to be sent across
3638 		 * all active channels.
3639 		 */
3640 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3641 			fcp = FCPARAM(isp, chan);
3642 			if (fcp->role == ISP_ROLE_NONE)
3643 				continue;
3644 			ISP_SET_SENDMARKER(isp, chan, 1);
3645 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
3646 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3647 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
3648 #ifdef	ISP_TARGET_MODE
3649 			isp_target_async(isp, chan, mbox);
3650 #endif
3651 		}
3652 		break;
3653 
3654 	case ASYNC_PDB_CHANGED:
3655 	{
3656 		int echan, nphdl, nlstate, reason;
3657 
3658 		nphdl = ISP_READ(isp, OUTMAILBOX1);
3659 		nlstate = ISP_READ(isp, OUTMAILBOX2);
3660 		reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
3661 		if (ISP_CAP_MULTI_ID(isp)) {
3662 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3663 			if (chan == 0xff || nphdl == NIL_HANDLE) {
3664 				chan = 0;
3665 				echan = isp->isp_nchan - 1;
3666 			} else if (chan >= isp->isp_nchan) {
3667 				break;
3668 			} else {
3669 				echan = chan;
3670 			}
3671 		} else {
3672 			chan = echan = 0;
3673 		}
3674 		for (; chan <= echan; chan++) {
3675 			fcp = FCPARAM(isp, chan);
3676 			if (fcp->role == ISP_ROLE_NONE)
3677 				continue;
3678 			if (fcp->isp_loopstate > LOOP_LTEST_DONE) {
3679 				if (nphdl != NIL_HANDLE &&
3680 				    nphdl == fcp->isp_login_hdl &&
3681 				    reason == PDB24XX_AE_OPN_2)
3682 					continue;
3683 				fcp->isp_loopstate = LOOP_LTEST_DONE;
3684 			} else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3685 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3686 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3687 			    ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
3688 		}
3689 		break;
3690 	}
3691 	case ASYNC_CHANGE_NOTIFY:
3692 	{
3693 		int portid;
3694 
3695 		portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
3696 		    ISP_READ(isp, OUTMAILBOX2);
3697 		if (ISP_CAP_MULTI_ID(isp)) {
3698 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
3699 			if (chan >= isp->isp_nchan)
3700 				break;
3701 		} else {
3702 			chan = 0;
3703 		}
3704 		fcp = FCPARAM(isp, chan);
3705 		if (fcp->role == ISP_ROLE_NONE)
3706 			break;
3707 		if (fcp->isp_loopstate > LOOP_LTEST_DONE)
3708 			fcp->isp_loopstate = LOOP_LTEST_DONE;
3709 		else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
3710 			fcp->isp_loopstate = LOOP_HAVE_LINK;
3711 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
3712 		    ISPASYNC_CHANGE_SNS, portid);
3713 		break;
3714 	}
3715 	case ASYNC_ERR_LOGGING_DISABLED:
3716 		isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
3717 		    ISP_READ(isp, OUTMAILBOX1));
3718 		break;
3719 	case ASYNC_P2P_INIT_ERR:
3720 		isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
3721 		    ISP_READ(isp, OUTMAILBOX1));
3722 		break;
3723 	case ASYNC_RCV_ERR:
3724 		isp_prt(isp, ISP_LOGWARN, "Receive Error");
3725 		break;
3726 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
3727 		isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
3728 		break;
3729 	case ASYNC_FW_RESTART_COMPLETE:
3730 		isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
3731 		break;
3732 	case ASYNC_TEMPERATURE_ALERT:
3733 		isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
3734 		    ISP_READ(isp, OUTMAILBOX1));
3735 		break;
3736 	case ASYNC_INTER_DRIVER_COMP:
3737 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication complete");
3738 		break;
3739 	case ASYNC_INTER_DRIVER_NOTIFY:
3740 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication notification");
3741 		break;
3742 	case ASYNC_INTER_DRIVER_TIME_EXT:
3743 		isp_prt(isp, ISP_LOGDEBUG0, "Inter-driver communication time extended");
3744 		break;
3745 	case ASYNC_TRANSCEIVER_INSERTION:
3746 		isp_prt(isp, ISP_LOGDEBUG0, "Transceiver insertion (0x%x)",
3747 		    ISP_READ(isp, OUTMAILBOX1));
3748 		break;
3749 	case ASYNC_TRANSCEIVER_REMOVAL:
3750 		isp_prt(isp, ISP_LOGDEBUG0, "Transceiver removal");
3751 		break;
3752 	case ASYNC_NIC_FW_STATE_CHANGE:
3753 		isp_prt(isp, ISP_LOGDEBUG0, "NIC Firmware State Change");
3754 		break;
3755 	case ASYNC_AUTOLOAD_FW_COMPLETE:
3756 		isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
3757 		break;
3758 	case ASYNC_AUTOLOAD_FW_FAILURE:
3759 		isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
3760 		break;
3761 	default:
3762 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
3763 		break;
3764 	}
3765 }
3766 
3767 /*
3768  * Handle completions with control handles by waking up waiting threads.
3769  */
3770 static int
3771 isp_handle_control(ispsoftc_t *isp, isphdr_t *hp)
3772 {
3773 	uint32_t hdl;
3774 	void *ptr;
3775 
3776 	switch (hp->rqs_entry_type) {
3777 	case RQSTYPE_RESPONSE:
3778 	case RQSTYPE_MARKER:
3779 	case RQSTYPE_NOTIFY_ACK:
3780 	case RQSTYPE_CTIO7:
3781 	case RQSTYPE_TSK_MGMT:
3782 	case RQSTYPE_CT_PASSTHRU:
3783 	case RQSTYPE_VP_MODIFY:
3784 	case RQSTYPE_VP_CTRL:
3785 	case RQSTYPE_ABORT_IO:
3786 	case RQSTYPE_MBOX:
3787 	case RQSTYPE_LOGIN:
3788 	case RQSTYPE_ELS_PASSTHRU:
3789 		ISP_IOXGET_32(isp, (uint32_t *)(hp + 1), hdl);
3790 		if (ISP_H2HT(hdl) != ISP_HANDLE_CTRL)
3791 			break;
3792 		ptr = isp_find_xs(isp, hdl);
3793 		if (ptr != NULL) {
3794 			isp_destroy_handle(isp, hdl);
3795 			memcpy(ptr, hp, QENTRY_LEN);
3796 			wakeup(ptr);
3797 		}
3798 		return (1);
3799 	}
3800 	return (0);
3801 }
3802 
3803 static void
3804 isp_handle_rpt_id_acq(ispsoftc_t *isp, isphdr_t *hp)
3805 {
3806 	fcparam *fcp;
3807 	isp_ridacq_t rid;
3808 	int chan, c;
3809 	uint32_t portid;
3810 
3811 	isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
3812 	portid = (uint32_t)rid.ridacq_vp_port_hi << 16 |
3813 	    rid.ridacq_vp_port_lo;
3814 	if (rid.ridacq_format == 0) {
3815 		for (chan = 0; chan < isp->isp_nchan; chan++) {
3816 			fcp = FCPARAM(isp, chan);
3817 			if (fcp->role == ISP_ROLE_NONE)
3818 				continue;
3819 			c = (chan == 0) ? 127 : (chan - 1);
3820 			if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
3821 			    chan == 0) {
3822 				fcp->isp_loopstate = LOOP_HAVE_LINK;
3823 				isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3824 				    chan, ISPASYNC_CHANGE_OTHER);
3825 			} else {
3826 				fcp->isp_loopstate = LOOP_NIL;
3827 				isp_async(isp, ISPASYNC_LOOP_DOWN,
3828 				    chan);
3829 			}
3830 		}
3831 	} else {
3832 		fcp = FCPARAM(isp, rid.ridacq_vp_index);
3833 		if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
3834 		    rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
3835 			fcp->isp_topo = (rid.ridacq_map[0] >> 9) & 0x7;
3836 			fcp->isp_portid = portid;
3837 			fcp->isp_loopstate = LOOP_HAVE_ADDR;
3838 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
3839 			    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
3840 		} else {
3841 			fcp->isp_loopstate = LOOP_NIL;
3842 			isp_async(isp, ISPASYNC_LOOP_DOWN,
3843 			    rid.ridacq_vp_index);
3844 		}
3845 	}
3846 }
3847 
3848 static void
3849 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs)
3850 {
3851 	int ru_marked, sv_marked;
3852 	int chan = XS_CHANNEL(xs);
3853 
3854 	switch (sp->req_completion_status) {
3855 	case RQCS_COMPLETE:
3856 		return;
3857 
3858 	case RQCS_DMA_ERROR:
3859 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
3860 		if (XS_NOERR(xs))
3861 			XS_SETERR(xs, HBA_BOTCH);
3862 		break;
3863 
3864 	case RQCS_TRANSPORT_ERROR:
3865 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
3866 		if (XS_NOERR(xs))
3867 			XS_SETERR(xs, HBA_BOTCH);
3868 		break;
3869 
3870 	case RQCS_RESET_OCCURRED:
3871 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
3872 		FCPARAM(isp, chan)->sendmarker = 1;
3873 		if (XS_NOERR(xs))
3874 			XS_SETERR(xs, HBA_BUSRESET);
3875 		return;
3876 
3877 	case RQCS_ABORTED:
3878 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
3879 		FCPARAM(isp, chan)->sendmarker = 1;
3880 		if (XS_NOERR(xs))
3881 			XS_SETERR(xs, HBA_ABORTED);
3882 		return;
3883 
3884 	case RQCS_TIMEOUT:
3885 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
3886 		if (XS_NOERR(xs))
3887 			XS_SETERR(xs, HBA_CMDTIMEOUT);
3888 		return;
3889 
3890 	case RQCS_DATA_OVERRUN:
3891 		XS_SET_RESID(xs, sp->req_resid);
3892 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
3893 		if (XS_NOERR(xs))
3894 			XS_SETERR(xs, HBA_DATAOVR);
3895 		return;
3896 
3897 	case RQCS_DRE:		/* data reassembly error */
3898 		isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
3899 		if (XS_NOERR(xs))
3900 			XS_SETERR(xs, HBA_BOTCH);
3901 		return;
3902 
3903 	case RQCS_TABORT:	/* aborted by target */
3904 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
3905 		if (XS_NOERR(xs))
3906 			XS_SETERR(xs, HBA_ABORTED);
3907 		return;
3908 
3909 	case RQCS_DATA_UNDERRUN:
3910 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
3911 		/*
3912 		 * We can get an underrun w/o things being marked
3913 		 * if we got a non-zero status.
3914 		 */
3915 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
3916 		if ((ru_marked == 0 && sv_marked == 0) ||
3917 		    (sp->req_resid > XS_XFRLEN(xs))) {
3918 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
3919 			if (XS_NOERR(xs))
3920 				XS_SETERR(xs, HBA_BOTCH);
3921 			return;
3922 		}
3923 		XS_SET_RESID(xs, sp->req_resid);
3924 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
3925 		return;
3926 
3927 	case RQCS_PORT_UNAVAILABLE:
3928 		/*
3929 		 * No such port on the loop. Moral equivalent of SELTIMEO
3930 		 */
3931 	case RQCS_PORT_LOGGED_OUT:
3932 	{
3933 		const char *reason;
3934 		uint8_t sts = sp->req_completion_status & 0xff;
3935 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
3936 		fcportdb_t *lp;
3937 
3938 		/*
3939 		 * It was there (maybe)- treat as a selection timeout.
3940 		 */
3941 		if (sts == RQCS_PORT_UNAVAILABLE) {
3942 			reason = "unavailable";
3943 		} else {
3944 			reason = "logout";
3945 		}
3946 
3947 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
3948 		    chan, reason, XS_TGT(xs));
3949 
3950 		/* XXX: Should we trigger rescan or FW announce change? */
3951 
3952 		if (XS_NOERR(xs)) {
3953 			lp = &fcp->portdb[XS_TGT(xs)];
3954 			if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
3955 				*XS_STSP(xs) = SCSI_BUSY;
3956 				XS_SETERR(xs, HBA_TGTBSY);
3957 			} else
3958 				XS_SETERR(xs, HBA_SELTIMEOUT);
3959 		}
3960 		return;
3961 	}
3962 	case RQCS_PORT_CHANGED:
3963 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
3964 		if (XS_NOERR(xs)) {
3965 			*XS_STSP(xs) = SCSI_BUSY;
3966 			XS_SETERR(xs, HBA_TGTBSY);
3967 		}
3968 		return;
3969 
3970 	case RQCS_ENOMEM:	/* f/w resource unavailable */
3971 		isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
3972 		if (XS_NOERR(xs)) {
3973 			*XS_STSP(xs) = SCSI_BUSY;
3974 			XS_SETERR(xs, HBA_TGTBSY);
3975 		}
3976 		return;
3977 
3978 	case RQCS_TMO:		/* task management overrun */
3979 		isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
3980 		if (XS_NOERR(xs)) {
3981 			*XS_STSP(xs) = SCSI_BUSY;
3982 			XS_SETERR(xs, HBA_TGTBSY);
3983 		}
3984 		return;
3985 
3986 	default:
3987 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
3988 		break;
3989 	}
3990 	if (XS_NOERR(xs))
3991 		XS_SETERR(xs, HBA_BOTCH);
3992 }
3993 
3994 #define	ISP_FC_IBITS(op)	((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
3995 #define	ISP_FC_OBITS(op)	((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
3996 
3997 #define	ISP_FC_OPMAP(in0, out0)							  0,   0,   0, in0,    0,    0,    0, out0
3998 #define	ISP_FC_OPMAP_HALF(in1, in0, out1, out0)					  0,   0, in1, in0,    0,    0, out1, out0
3999 #define	ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0)		in3, in2, in1, in0, out3, out2, out1, out0
4000 static const uint32_t mbpfc[] = {
4001 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
4002 	ISP_FC_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
4003 	ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x1f),	/* 0x02: MBOX_EXEC_FIRMWARE */
4004 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x03: MBOX_LOAD_FLASH_FIRMWARE */
4005 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
4006 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
4007 	ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
4008 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
4009 	ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
4010 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
4011 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x0a: MBOX_DUMP_RISC_RAM_2100 */
4012 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
4013 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x0c: */
4014 	ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
4015 	ISP_FC_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
4016 	ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
4017 	ISP_FC_OPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
4018 	ISP_FC_OPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
4019 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
4020 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
4021 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03),	/* 0x14: MBOX_STOP_FIRMWARE */
4022 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
4023 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
4024 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
4025 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
4026 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
4027 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
4028 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
4029 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
4030 	ISP_FC_OPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
4031 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x1e: */
4032 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
4033 	ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf),	/* 0x20: MBOX_GET_LOOP_ID */
4034 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x21: */
4035 	ISP_FC_OPMAP(0x03, 0x4b),	/* 0x22: MBOX_GET_TIMEOUT_PARAMS */
4036 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x23: */
4037 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x24: */
4038 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x25: */
4039 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x26: */
4040 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x27: */
4041 	ISP_FC_OPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
4042 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
4043 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2a: */
4044 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2b: */
4045 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2c: */
4046 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2d: */
4047 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2e: */
4048 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2f: */
4049 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x30: */
4050 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x31: */
4051 	ISP_FC_OPMAP(0x4b, 0x4b),	/* 0x32: MBOX_SET_TIMEOUT_PARAMS */
4052 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x33: */
4053 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x34: */
4054 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x35: */
4055 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x36: */
4056 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x37: */
4057 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
4058 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
4059 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3a: */
4060 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3b: */
4061 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3c: */
4062 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3d: */
4063 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3e: */
4064 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3f: */
4065 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
4066 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
4067 	ISP_FC_OPMAP_HALF(0x0, 0x01, 0x1f, 0xcf),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
4068 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
4069 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x44: */
4070 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x45: */
4071 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x46: */
4072 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
4073 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
4074 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
4075 	ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
4076 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4b: */
4077 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4c: */
4078 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4d: */
4079 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4e: */
4080 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4f: */
4081 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x50: */
4082 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x51: */
4083 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x52: */
4084 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x53: */
4085 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
4086 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x55: */
4087 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x56: */
4088 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x57: */
4089 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x58: */
4090 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x59: */
4091 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5a: */
4092 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
4093 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
4094 	ISP_FC_OPMAP(0x07, 0x1f),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
4095 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5e: */
4096 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5f: */
4097 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x60: MBOX_INIT_FIRMWARE */
4098 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x61: */
4099 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
4100 	ISP_FC_OPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
4101 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
4102 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
4103 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
4104 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
4105 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
4106 	ISP_FC_OPMAP_HALF(0x00, 0x01, 0x0f, 0x1f),	/* 0x69: MBOX_GET_FW_STATE */
4107 	ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
4108 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
4109 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
4110 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x6d: */
4111 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
4112 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
4113 	ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
4114 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
4115 	ISP_FC_OPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
4116 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x73: */
4117 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
4118 	ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07),	/* 0x75: GET PORT/NODE NAME LIST */
4119 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
4120 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
4121 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x78: */
4122 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x79: */
4123 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7a: */
4124 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7b: */
4125 	ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07),	/* 0x7c: Get ID List */
4126 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
4127 	ISP_FC_OPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
4128 };
4129 #define	MAX_FC_OPCODE	0x7e
4130 /*
4131  * Footnotes
4132  *
4133  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
4134  *	do not access at this time in the core driver. The caller is
4135  *	responsible for setting this register first (Gross!). The assumption
4136  *	is that we won't overflow.
4137  */
4138 
4139 static const char *fc_mbcmd_names[] = {
4140 	"NO-OP",			/* 00h */
4141 	"LOAD RAM",
4142 	"EXEC FIRMWARE",
4143 	"LOAD FLASH FIRMWARE",
4144 	"WRITE RAM WORD",
4145 	"READ RAM WORD",
4146 	"MAILBOX REG TEST",
4147 	"VERIFY CHECKSUM",
4148 	"ABOUT FIRMWARE",
4149 	"LOAD RAM (2100)",
4150 	"DUMP RAM (2100)",
4151 	"LOAD RISC RAM",
4152 	"DUMP RISC RAM",
4153 	"WRITE RAM WORD EXTENDED",
4154 	"CHECK FIRMWARE",
4155 	"READ RAM WORD EXTENDED",
4156 	"INIT REQUEST QUEUE",		/* 10h */
4157 	"INIT RESULT QUEUE",
4158 	"EXECUTE IOCB",
4159 	"WAKE UP",
4160 	"STOP FIRMWARE",
4161 	"ABORT",
4162 	"ABORT DEVICE",
4163 	"ABORT TARGET",
4164 	"BUS RESET",
4165 	"STOP QUEUE",
4166 	"START QUEUE",
4167 	"SINGLE STEP QUEUE",
4168 	"ABORT QUEUE",
4169 	"GET DEV QUEUE STATUS",
4170 	NULL,
4171 	"GET FIRMWARE STATUS",
4172 	"GET LOOP ID",			/* 20h */
4173 	NULL,
4174 	"GET TIMEOUT PARAMS",
4175 	NULL,
4176 	NULL,
4177 	NULL,
4178 	NULL,
4179 	NULL,
4180 	"GET FIRMWARE OPTIONS",
4181 	"GET PORT QUEUE PARAMS",
4182 	"GENERATE SYSTEM ERROR",
4183 	NULL,
4184 	NULL,
4185 	NULL,
4186 	NULL,
4187 	NULL,
4188 	"WRITE SFP",			/* 30h */
4189 	"READ SFP",
4190 	"SET TIMEOUT PARAMS",
4191 	NULL,
4192 	NULL,
4193 	NULL,
4194 	NULL,
4195 	NULL,
4196 	"SET FIRMWARE OPTIONS",
4197 	"SET PORT QUEUE PARAMS",
4198 	NULL,
4199 	"SET FC LED CONF",
4200 	NULL,
4201 	"RESTART NIC FIRMWARE",
4202 	"ACCESS CONTROL",
4203 	NULL,
4204 	"LOOP PORT BYPASS",		/* 40h */
4205 	"LOOP PORT ENABLE",
4206 	"GET RESOURCE COUNT",
4207 	"REQUEST NON PARTICIPATING MODE",
4208 	"DIAGNOSTIC ECHO TEST",
4209 	"DIAGNOSTIC LOOPBACK",
4210 	NULL,
4211 	"GET PORT DATABASE ENHANCED",
4212 	"INIT FIRMWARE MULTI ID",
4213 	"GET VP DATABASE",
4214 	"GET VP DATABASE ENTRY",
4215 	NULL,
4216 	NULL,
4217 	NULL,
4218 	NULL,
4219 	NULL,
4220 	"GET FCF LIST",			/* 50h */
4221 	"GET DCBX PARAMETERS",
4222 	NULL,
4223 	"HOST MEMORY COPY",
4224 	"EXECUTE IOCB A64",
4225 	NULL,
4226 	NULL,
4227 	"SEND RNID",
4228 	NULL,
4229 	"SET PARAMETERS",
4230 	"GET PARAMETERS",
4231 	"DRIVER HEARTBEAT",
4232 	"FIRMWARE HEARTBEAT",
4233 	"GET/SET DATA RATE",
4234 	"SEND RNFT",
4235 	NULL,
4236 	"INIT FIRMWARE",		/* 60h */
4237 	"GET INIT CONTROL BLOCK",
4238 	"INIT LIP",
4239 	"GET FC-AL POSITION MAP",
4240 	"GET PORT DATABASE",
4241 	"CLEAR ACA",
4242 	"TARGET RESET",
4243 	"CLEAR TASK SET",
4244 	"ABORT TASK SET",
4245 	"GET FW STATE",
4246 	"GET PORT NAME",
4247 	"GET LINK STATUS",
4248 	"INIT LIP RESET",
4249 	"GET LINK STATS & PRIVATE DATA CNTS",
4250 	"SEND SNS",
4251 	"FABRIC LOGIN",
4252 	"SEND CHANGE REQUEST",		/* 70h */
4253 	"FABRIC LOGOUT",
4254 	"INIT LIP LOGIN",
4255 	NULL,
4256 	"LOGIN LOOP PORT",
4257 	"GET PORT/NODE NAME LIST",
4258 	"SET VENDOR ID",
4259 	"INITIALIZE IP MAILBOX",
4260 	NULL,
4261 	NULL,
4262 	"GET XGMAC STATS",
4263 	NULL,
4264 	"GET ID LIST",
4265 	"SEND LFA",
4266 	"LUN RESET"
4267 };
4268 
4269 static void
4270 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
4271 {
4272 	const char *cname, *xname, *sname;
4273 	char tname[16], mname[16];
4274 	unsigned int ibits, obits, box, opcode, t, to;
4275 
4276 	opcode = mbp->param[0];
4277 	if (opcode > MAX_FC_OPCODE) {
4278 		mbp->param[0] = MBOX_INVALID_COMMAND;
4279 		isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
4280 		return;
4281 	}
4282 	cname = fc_mbcmd_names[opcode];
4283 	ibits = ISP_FC_IBITS(opcode);
4284 	obits = ISP_FC_OBITS(opcode);
4285 	if (cname == NULL) {
4286 		cname = tname;
4287 		ISP_SNPRINTF(tname, sizeof(tname), "opcode %x", opcode);
4288 	}
4289 	isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
4290 
4291 	/*
4292 	 * Pick up any additional bits that the caller might have set.
4293 	 */
4294 	ibits |= mbp->ibits;
4295 	obits |= mbp->obits;
4296 
4297 	/*
4298 	 * Mask any bits that the caller wants us to mask
4299 	 */
4300 	ibits &= mbp->ibitm;
4301 	obits &= mbp->obitm;
4302 
4303 
4304 	if (ibits == 0 && obits == 0) {
4305 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
4306 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
4307 		return;
4308 	}
4309 
4310 	for (box = 0; box < ISP_NMBOX(isp); box++) {
4311 		if (ibits & (1 << box)) {
4312 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
4313 			    mbp->param[box]);
4314 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
4315 		}
4316 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
4317 	}
4318 
4319 	isp->isp_obits = obits;
4320 	isp->isp_mboxbsy = 1;
4321 
4322 	/*
4323 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
4324 	 */
4325 	ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
4326 
4327 	/*
4328 	 * While we haven't finished the command, spin our wheels here.
4329 	 */
4330 	to = (mbp->timeout == 0) ? MBCMD_DEFAULT_TIMEOUT : mbp->timeout;
4331 	for (t = 0; t < to; t += 100) {
4332 		if (!isp->isp_mboxbsy)
4333 			break;
4334 		ISP_RUN_ISR(isp);
4335 		if (!isp->isp_mboxbsy)
4336 			break;
4337 		ISP_DELAY(100);
4338 	}
4339 
4340 	/*
4341 	 * Did the command time out?
4342 	 */
4343 	if (isp->isp_mboxbsy) {
4344 		isp->isp_mboxbsy = 0;
4345 		isp_prt(isp, ISP_LOGWARN, "Mailbox Command (0x%x) Timeout (%uus) (%s:%d)",
4346 		    opcode, to, mbp->func, mbp->lineno);
4347 		mbp->param[0] = MBOX_TIMEOUT;
4348 		goto out;
4349 	}
4350 
4351 	/*
4352 	 * Copy back output registers.
4353 	 */
4354 	for (box = 0; box < ISP_NMBOX(isp); box++) {
4355 		if (obits & (1 << box)) {
4356 			mbp->param[box] = isp->isp_mboxtmp[box];
4357 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
4358 			    mbp->param[box]);
4359 		}
4360 	}
4361 
4362 out:
4363 	if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
4364 		return;
4365 
4366 	if ((mbp->param[0] & 0xbfe0) == 0 &&
4367 	    (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
4368 		return;
4369 
4370 	xname = NULL;
4371 	sname = "";
4372 	switch (mbp->param[0]) {
4373 	case MBOX_INVALID_COMMAND:
4374 		xname = "INVALID COMMAND";
4375 		break;
4376 	case MBOX_HOST_INTERFACE_ERROR:
4377 		xname = "HOST INTERFACE ERROR";
4378 		break;
4379 	case MBOX_TEST_FAILED:
4380 		xname = "TEST FAILED";
4381 		break;
4382 	case MBOX_COMMAND_ERROR:
4383 		xname = "COMMAND ERROR";
4384 		ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
4385 		    mbp->param[1]);
4386 		sname = mname;
4387 		break;
4388 	case MBOX_COMMAND_PARAM_ERROR:
4389 		xname = "COMMAND PARAMETER ERROR";
4390 		break;
4391 	case MBOX_PORT_ID_USED:
4392 		xname = "PORT ID ALREADY IN USE";
4393 		break;
4394 	case MBOX_LOOP_ID_USED:
4395 		xname = "LOOP ID ALREADY IN USE";
4396 		break;
4397 	case MBOX_ALL_IDS_USED:
4398 		xname = "ALL LOOP IDS IN USE";
4399 		break;
4400 	case MBOX_NOT_LOGGED_IN:
4401 		xname = "NOT LOGGED IN";
4402 		break;
4403 	case MBOX_LINK_DOWN_ERROR:
4404 		xname = "LINK DOWN ERROR";
4405 		break;
4406 	case MBOX_LOOPBACK_ERROR:
4407 		xname = "LOOPBACK ERROR";
4408 		break;
4409 	case MBOX_CHECKSUM_ERROR:
4410 		xname = "CHECKSUM ERROR";
4411 		break;
4412 	case MBOX_INVALID_PRODUCT_KEY:
4413 		xname = "INVALID PRODUCT KEY";
4414 		break;
4415 	case MBOX_REGS_BUSY:
4416 		xname = "REGISTERS BUSY";
4417 		break;
4418 	case MBOX_TIMEOUT:
4419 		xname = "TIMEOUT";
4420 		break;
4421 	default:
4422 		ISP_SNPRINTF(mname, sizeof(mname), "error 0x%x", mbp->param[0]);
4423 		xname = mname;
4424 		break;
4425 	}
4426 	if (xname) {
4427 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
4428 		    cname, xname, sname);
4429 	}
4430 }
4431 
4432 static int
4433 isp_fw_state(ispsoftc_t *isp, int chan)
4434 {
4435 	mbreg_t mbs;
4436 
4437 	MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
4438 	isp_mboxcmd(isp, &mbs);
4439 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE)
4440 		return (mbs.param[1]);
4441 	return (FW_ERROR);
4442 }
4443 
4444 static void
4445 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
4446 {
4447 	fcparam *fcp = FCPARAM(isp, chan);
4448 
4449 	/*
4450 	 * Establish some default parameters.
4451 	 */
4452 	fcp->role = DEFAULT_ROLE(isp, chan);
4453 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4454 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4455 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
4456 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
4457 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
4458 	fcp->isp_fwoptions = 0;
4459 	fcp->isp_xfwoptions = 0;
4460 	fcp->isp_zfwoptions = 0;
4461 	fcp->isp_lasthdl = NIL_HANDLE;
4462 	fcp->isp_login_hdl = NIL_HANDLE;
4463 
4464 	fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
4465 	fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
4466 	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
4467 		fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
4468 	fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
4469 	fcp->isp_xfwoptions |= ICB2400_OPT2_LOOP_2_PTP;
4470 	fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
4471 
4472 	/*
4473 	 * Now try and read NVRAM unless told to not do so.
4474 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
4475 	 */
4476 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4477 		int i, j = 0;
4478 		/*
4479 		 * Give a couple of tries at reading NVRAM.
4480 		 */
4481 		for (i = 0; i < 2; i++) {
4482 			j = isp_read_nvram(isp);
4483 			if (j == 0) {
4484 				break;
4485 			}
4486 		}
4487 		if (j) {
4488 			isp->isp_confopts |= ISP_CFG_NONVRAM;
4489 		}
4490 	}
4491 
4492 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
4493 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
4494 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
4495 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
4496 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
4497 	    isp_class3_roles[fcp->role]);
4498 }
4499 
4500 /*
4501  * Re-initialize the ISP and complete all orphaned commands
4502  * with a 'botched' notice. The reset/init routines should
4503  * not disturb an already active list of commands.
4504  */
4505 
4506 int
4507 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
4508 {
4509 	int i, res = 0;
4510 
4511 	if (isp->isp_state > ISP_RESETSTATE)
4512 		isp_stop(isp);
4513 	if (isp->isp_state != ISP_RESETSTATE)
4514 		isp_reset(isp, do_load_defaults);
4515 	if (isp->isp_state != ISP_RESETSTATE) {
4516 		res = EIO;
4517 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
4518 		goto cleanup;
4519 	}
4520 
4521 	isp_init(isp);
4522 	if (isp->isp_state > ISP_RESETSTATE &&
4523 	    isp->isp_state != ISP_RUNSTATE) {
4524 		res = EIO;
4525 		isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
4526 		ISP_DISABLE_INTS(isp);
4527 	}
4528 
4529 cleanup:
4530 	isp_clear_commands(isp);
4531 	for (i = 0; i < isp->isp_nchan; i++)
4532 		isp_clear_portdb(isp, i);
4533 	return (res);
4534 }
4535 
4536 /*
4537  * NVRAM Routines
4538  */
4539 static inline uint32_t
4540 flash_data_addr(ispsoftc_t *isp, uint32_t faddr)
4541 {
4542 	fcparam *fcp = FCPARAM(isp, 0);
4543 
4544 	return (fcp->flash_data_addr + faddr);
4545 }
4546 
4547 static int
4548 isp_read_flash_dword(ispsoftc_t *isp, uint32_t addr, uint32_t *data)
4549 {
4550 	int loops = 0;
4551 
4552 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, addr & ~0x80000000);
4553 	for (loops = 0; loops < 30000; loops++) {
4554 		if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4555 			*data = ISP_READ(isp, BIU2400_FLASH_DATA);
4556 			return (ISP_SUCCESS);
4557 		}
4558 		ISP_DELAY(10);
4559 	}
4560 	isp_prt(isp, ISP_LOGERR,
4561 	    "Flash read dword at 0x%x timeout.", addr);
4562 	*data = 0xffffffff;
4563 	return (ISP_FUNCTION_TIMEOUT);
4564 }
4565 
4566 static int
4567 isp_read_flash_data(ispsoftc_t *isp, uint32_t *dwptr, uint32_t faddr, uint32_t dwords)
4568 {
4569 	int loops = 0;
4570 	int rval = ISP_SUCCESS;
4571 
4572 	/* Dword reads to flash. */
4573 	faddr =  flash_data_addr(isp, faddr);
4574 	for (loops = 0; loops < dwords; loops++, faddr++, dwptr++) {
4575 		rval = isp_read_flash_dword(isp, faddr, dwptr);
4576 		if (rval != ISP_SUCCESS)
4577 			break;
4578 		*dwptr = htole32(*dwptr);
4579 	}
4580 
4581 	return (rval);
4582 }
4583 
4584 static void
4585 isp_rd_2xxx_flash(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
4586 {
4587 	fcparam *fcp = FCPARAM(isp, 0);
4588 	int loops = 0;
4589 	uint32_t base = fcp->flash_data_addr;
4590 
4591 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, (base + addr) & ~0x80000000);
4592 	for (loops = 0; loops < 30000; loops++) {
4593 		ISP_DELAY(10);
4594 		if (ISP_READ(isp, BIU2400_FLASH_ADDR & 0x80000000)) {
4595 			*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
4596 			ISP_SWIZZLE_NVRAM_LONG(isp, rp);
4597 			return;
4598 		}
4599 	}
4600 	isp_prt(isp, ISP_LOGERR,
4601 	    "Flash read dword at 0x%x timeout.", (base + addr));
4602 	*rp = 0xffffffff;
4603 }
4604 
4605 static int
4606 isp_read_flthdr_2xxx(ispsoftc_t *isp)
4607 {
4608 	fcparam *fcp = FCPARAM(isp, 0);
4609 	int retval = 0;
4610 	uint32_t addr, lwrds, *dptr;
4611 	uint16_t csum;
4612 	uint8_t flthdr_data[FLT_HEADER_SIZE];
4613 
4614 	addr = fcp->flt_region_flt;
4615 	dptr = (uint32_t *) flthdr_data;
4616 
4617 	isp_prt(isp, ISP_LOGDEBUG0, "FLTL[DEF]: 0x%x", addr);
4618 	for (lwrds = 0; lwrds < FLT_HEADER_SIZE >> 2; lwrds++) {
4619 		isp_rd_2xxx_flash(isp, addr++, dptr++);
4620 	}
4621 	dptr = (uint32_t *) flthdr_data;
4622 	for (csum = 0, lwrds = 0; lwrds < FLT_HEADER_SIZE >> 4; lwrds++) {
4623 		uint16_t tmp;
4624 		ISP_IOXGET_16(isp, &dptr[lwrds], tmp);
4625 		csum += tmp;
4626 	}
4627 	if (csum != 0) {
4628 		retval = -1;
4629 		goto out;
4630 	}
4631 	isp_parse_flthdr_2xxx(isp, flthdr_data);
4632 out:
4633 	return (retval);
4634 }
4635 
4636 static void
4637 isp_parse_flthdr_2xxx(ispsoftc_t *isp, uint8_t *flthdr_data)
4638 {
4639 	fcparam *fcp = FCPARAM(isp, 0);
4640 	uint16_t ver, csum;
4641 
4642 	ver = le16toh((uint16_t) (ISP2XXX_FLT_VERSION(flthdr_data)));
4643 	fcp->flt_length = le16toh((uint16_t) (ISP2XXX_FLT_LENGTH(flthdr_data)));
4644 	csum = le16toh((uint16_t) (ISP2XXX_FLT_CSUM(flthdr_data)));
4645 
4646 	if ((fcp->flt_length == 0) ||
4647 	    (fcp->flt_length > (FLT_HEADER_SIZE + FLT_REGIONS_SIZE))) {
4648 		isp_prt(isp, ISP_LOGERR,
4649 		    "FLT[DEF]: Invalid length=0x%x(%d)",
4650 		    fcp->flt_length, fcp->flt_length);
4651 	}
4652 	isp_prt(isp, ISP_LOGDEBUG0,
4653 	    "FLT[DEF]: version=0x%x length=0x%x(%d) checksum=0x%x",
4654 	    ver, fcp->flt_length, fcp->flt_length, csum);
4655 }
4656 
4657 static int
4658 isp_read_flt_2xxx(ispsoftc_t *isp)
4659 {
4660 	fcparam *fcp = FCPARAM(isp, 0);
4661 	int retval = 0;
4662 	int len = fcp->flt_length - FLT_HEADER_SIZE;
4663 	uint32_t addr, lwrds, *dptr;
4664 	uint8_t flt_data[len];
4665 	fcp->flt_region_entries = len / FLT_REGION_SIZE;
4666 
4667 	addr = fcp->flt_region_flt + (FLT_HEADER_SIZE >> 2);
4668 	dptr = (uint32_t *) flt_data;
4669 	isp_prt(isp, ISP_LOGDEBUG0, "FLT[DEF]: regions=%d",
4670 	    fcp->flt_region_entries);
4671 	for (lwrds = 0; lwrds < len >> 2; lwrds++) {
4672 		isp_rd_2xxx_flash(isp, addr++, dptr++);
4673 	}
4674 	retval = isp_parse_flt_2xxx(isp, flt_data);
4675 	return (retval);
4676 }
4677 
4678 static int
4679 isp_parse_flt_2xxx(ispsoftc_t *isp, uint8_t *flt_data)
4680 {
4681 	fcparam *fcp = FCPARAM(isp, 0);
4682 	int count;
4683 	struct flt_region region[fcp->flt_region_entries];
4684 
4685 	for (count = 0; count < fcp->flt_region_entries; count++) {
4686 		region[count].code =
4687 		    le16toh((uint16_t) (ISP2XXX_FLT_REG_CODE(flt_data, count)));
4688 		region[count].attribute =
4689 		    (uint8_t) (ISP2XXX_FLT_REG_ATTR(flt_data, count));
4690 		region[count].reserved =
4691 		    (uint8_t) (ISP2XXX_FLT_REG_RES(flt_data, count));
4692 		region[count].size =
4693 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_SIZE(flt_data, count)) >> 2);
4694 		region[count].start =
4695 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_START(flt_data, count)) >> 2);
4696 		region[count].end =
4697 		    le32toh((uint32_t) (ISP2XXX_FLT_REG_END(flt_data, count)) >> 2);
4698 
4699 		isp_prt(isp, ISP_LOGDEBUG0,
4700 		    "FLT[0x%x]: start=0x%x end=0x%x size=0x%x attribute=0x%x",
4701 		    region[count].code, region[count].start, region[count].end,
4702 		    region[count].size, region[count].attribute);
4703 
4704 		switch (region[count].code) {
4705 		case FLT_REG_FW:
4706 			fcp->flt_region_fw = region[count].start;
4707 			break;
4708 		case FLT_REG_BOOT_CODE:
4709 			fcp->flt_region_boot = region[count].start;
4710 			break;
4711 		case FLT_REG_VPD_0:
4712 			fcp->flt_region_vpd_nvram = region[count].start;
4713 			if (isp->isp_port == 0)
4714 				fcp->flt_region_vpd = region[count].start;
4715 			break;
4716 		case FLT_REG_VPD_1:
4717 			if (isp->isp_port == 1)
4718 				fcp->flt_region_vpd = region[count].start;
4719 			break;
4720 		case FLT_REG_VPD_2:
4721 			if (!IS_27XX(isp))
4722 				break;
4723 			if (isp->isp_port == 2)
4724 				fcp->flt_region_vpd = region[count].start;
4725 			break;
4726 		case FLT_REG_VPD_3:
4727 			if (!IS_27XX(isp))
4728 				break;
4729 			if (isp->isp_port == 3)
4730 				fcp->flt_region_vpd = region[count].start;
4731 			break;
4732 		case FLT_REG_NVRAM_0:
4733 			if (isp->isp_port == 0)
4734 				fcp->flt_region_nvram = region[count].start;
4735 			break;
4736 		case FLT_REG_NVRAM_1:
4737 			if (isp->isp_port == 1)
4738 				fcp->flt_region_nvram = region[count].start;
4739 			break;
4740 		case FLT_REG_NVRAM_2:
4741 			if (!IS_27XX(isp))
4742 				break;
4743 			if (isp->isp_port == 2)
4744 				fcp->flt_region_nvram = region[count].start;
4745 			break;
4746 		case FLT_REG_NVRAM_3:
4747 			if (!IS_27XX(isp))
4748 				break;
4749 			if (isp->isp_port == 3)
4750 				fcp->flt_region_nvram = region[count].start;
4751 			break;
4752 		case FLT_REG_FDT:
4753 			fcp->flt_region_fdt = region[count].start;
4754 			break;
4755 		case FLT_REG_FLT:
4756 			fcp->flt_region_flt = region[count].start;
4757 			break;
4758 		case FLT_REG_NPIV_CONF_0:
4759 			if (isp->isp_port == 0)
4760 				fcp->flt_region_npiv_conf = region[count].start;
4761 			break;
4762 		case FLT_REG_NPIV_CONF_1:
4763 			if (isp->isp_port == 1)
4764 				fcp->flt_region_npiv_conf = region[count].start;
4765 			break;
4766 		case FLT_REG_GOLD_FW:
4767 			fcp->flt_region_gold_fw = region[count].start;
4768 			break;
4769 		case FLT_REG_FCP_PRIO_0:
4770 			if (isp->isp_port == 0)
4771 				fcp->flt_region_fcp_prio = region[count].start;
4772 			break;
4773 		case FLT_REG_FCP_PRIO_1:
4774 			if (isp->isp_port == 1)
4775 				fcp->flt_region_fcp_prio = region[count].start;
4776 			break;
4777 		case FLT_REG_IMG_PRI_27XX:
4778 			if (IS_27XX(isp))
4779 				fcp->flt_region_img_status_pri = region[count].start;
4780 			break;
4781 		case FLT_REG_IMG_SEC_27XX:
4782 			if (IS_27XX(isp))
4783 				fcp->flt_region_img_status_sec = region[count].start;
4784 			break;
4785 		case FLT_REG_FW_SEC_27XX:
4786 			if (IS_27XX(isp))
4787 				fcp->flt_region_fw_sec = region[count].start;
4788 			break;
4789 		case FLT_REG_BOOTLOAD_SEC_27XX:
4790 			if (IS_27XX(isp))
4791 				fcp->flt_region_boot_sec = region[count].start;
4792 			break;
4793 		case FLT_REG_AUX_IMG_PRI_28XX:
4794 			if (IS_27XX(isp))
4795 				fcp->flt_region_aux_img_status_pri = region[count].start;
4796 			break;
4797 		case FLT_REG_AUX_IMG_SEC_28XX:
4798 			if (IS_27XX(isp))
4799 				fcp->flt_region_aux_img_status_sec = region[count].start;
4800 			break;
4801 		case FLT_REG_NVRAM_SEC_28XX_0:
4802 			if (IS_27XX(isp))
4803 				if (isp->isp_port == 0)
4804 					fcp->flt_region_nvram_sec = region[count].start;
4805 			break;
4806 		case FLT_REG_NVRAM_SEC_28XX_1:
4807 			if (IS_27XX(isp))
4808 				if (isp->isp_port == 1)
4809 					fcp->flt_region_nvram_sec = region[count].start;
4810 			break;
4811 		case FLT_REG_NVRAM_SEC_28XX_2:
4812 			if (IS_27XX(isp))
4813 				if (isp->isp_port == 2)
4814 					fcp->flt_region_nvram_sec = region[count].start;
4815 			break;
4816 		case FLT_REG_NVRAM_SEC_28XX_3:
4817 			if (IS_27XX(isp))
4818 				if (isp->isp_port == 3)
4819 					fcp->flt_region_nvram_sec = region[count].start;
4820 			break;
4821 		case FLT_REG_VPD_SEC_27XX_0:
4822 		case FLT_REG_VPD_SEC_28XX_0:
4823 			if (IS_27XX(isp)) {
4824 				fcp->flt_region_vpd_nvram_sec = region[count].start;
4825 				if (isp->isp_port == 0)
4826 					fcp->flt_region_vpd_sec = region[count].start;
4827 			}
4828 			break;
4829 		case FLT_REG_VPD_SEC_27XX_1:
4830 		case FLT_REG_VPD_SEC_28XX_1:
4831 			if (IS_27XX(isp))
4832 				if (isp->isp_port == 1)
4833 					fcp->flt_region_vpd_sec = region[count].start;
4834 			break;
4835 		case FLT_REG_VPD_SEC_27XX_2:
4836 		case FLT_REG_VPD_SEC_28XX_2:
4837 			if (IS_27XX(isp))
4838 				if (isp->isp_port == 2)
4839 					fcp->flt_region_vpd_sec = region[count].start;
4840 			break;
4841 		case FLT_REG_VPD_SEC_27XX_3:
4842 		case FLT_REG_VPD_SEC_28XX_3:
4843 			if (IS_27XX(isp))
4844 				if (isp->isp_port == 3)
4845 					fcp->flt_region_vpd_sec = region[count].start;
4846 			break;
4847 		}
4848 	}
4849 	isp_prt(isp, ISP_LOGCONFIG,
4850 	    "FLT[FLT]: boot=0x%x fw=0x%x vpd_nvram=0x%x vpd=0x%x nvram=0x%x "
4851 	    "fdt=0x%x flt=0x%x npiv=0x%x fcp_prif_cfg=0x%x",
4852 	    fcp->flt_region_boot, fcp->flt_region_fw, fcp->flt_region_vpd_nvram,
4853 	    fcp->flt_region_vpd, fcp->flt_region_nvram, fcp->flt_region_fdt,
4854 	    fcp->flt_region_flt, fcp->flt_region_npiv_conf,
4855 	    fcp->flt_region_fcp_prio);
4856 
4857 	return (0);
4858 }
4859 
4860 static void
4861 isp_print_image(ispsoftc_t *isp, char *name, struct isp_image_status *image_status)
4862 {
4863 	isp_prt(isp, ISP_LOGDEBUG0,
4864 	    "%s %s: mask=0x%02x gen=0x%04x ver=%u.%u map=0x%01x sum=0x%08x sig=0x%08x",
4865 	    name, "status",
4866 	    image_status->image_status_mask,
4867 	    le16toh(image_status->generation),
4868 	    image_status->ver_major,
4869 	    image_status->ver_minor,
4870 	    image_status->bitmap,
4871 	    le32toh(image_status->checksum),
4872 	    le32toh(image_status->signature));
4873 }
4874 
4875 static bool
4876 isp_check_aux_image_status_signature(struct isp_image_status *image_status)
4877 {
4878 	unsigned long signature = le32toh(image_status->signature);
4879 
4880 	return (signature != ISP28XX_AUX_IMG_STATUS_SIGN);
4881 }
4882 
4883 static bool
4884 isp_check_image_status_signature(struct isp_image_status *image_status)
4885 {
4886 	unsigned long signature = le32toh(image_status->signature);
4887 
4888 	return ((signature != ISP27XX_IMG_STATUS_SIGN) &&
4889 	    (signature != ISP28XX_IMG_STATUS_SIGN));
4890 }
4891 
4892 static unsigned long
4893 isp_image_status_checksum(struct isp_image_status *image_status)
4894 {
4895 	uint32_t *p = (uint32_t *)image_status;
4896 	unsigned int n = sizeof(*image_status) / sizeof(*p);
4897 	uint32_t sum = 0;
4898 
4899 	for ( ; n--; p++)
4900 		sum += le32toh(*((uint32_t *)(p)));
4901 
4902 	return (sum);
4903 }
4904 
4905 static inline unsigned int
4906 isp_component_bitmask(struct isp_image_status *aux, unsigned int bitmask)
4907 {
4908 	return (aux->bitmap & bitmask ?
4909 	    ISP27XX_SECONDARY_IMAGE : ISP27XX_PRIMARY_IMAGE);
4910 }
4911 
4912 static void
4913 isp_component_status(struct active_regions *active_regions, struct isp_image_status *aux)
4914 {
4915 	active_regions->aux.board_config =
4916 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_BOARD_CONFIG);
4917 
4918 	active_regions->aux.vpd_nvram =
4919 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_VPD_NVRAM);
4920 
4921 	active_regions->aux.npiv_config_0_1 =
4922 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_0_1);
4923 
4924 	active_regions->aux.npiv_config_2_3 =
4925 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NPIV_CONFIG_2_3);
4926 
4927 	active_regions->aux.nvme_params =
4928 	    isp_component_bitmask(aux, ISP28XX_AUX_IMG_NVME_PARAMS);
4929 }
4930 
4931 static int
4932 isp_compare_image_generation(ispsoftc_t *isp,
4933     struct isp_image_status *pri_image_status,
4934     struct isp_image_status *sec_image_status)
4935 {
4936 	/* calculate generation delta as uint16 (this accounts for wrap) */
4937 	int16_t delta =
4938 	    le16toh(pri_image_status->generation) -
4939 	    le16toh(sec_image_status->generation);
4940 
4941 	isp_prt(isp, ISP_LOGDEBUG0, "generation delta = %d", delta);
4942 
4943 	return (delta);
4944 }
4945 
4946 static void
4947 isp_get_aux_images(ispsoftc_t *isp, struct active_regions *active_regions)
4948 {
4949 	fcparam *fcp = FCPARAM(isp, 0);
4950 	struct isp_image_status pri_aux_image_status, sec_aux_image_status;
4951 	bool valid_pri_image = false, valid_sec_image = false;
4952 	bool active_pri_image = false, active_sec_image = false;
4953 
4954 	if (!fcp->flt_region_aux_img_status_pri) {
4955 		isp_prt(isp, ISP_LOGWARN,
4956 		    "Primary aux image not addressed");
4957 		goto check_sec_image;
4958 	}
4959 
4960 	isp_read_flash_data(isp, (uint32_t *)&pri_aux_image_status,
4961 	    fcp->flt_region_aux_img_status_pri,
4962 	    sizeof(pri_aux_image_status) >> 2);
4963 	isp_print_image(isp, "Primary aux image", &pri_aux_image_status);
4964 
4965 	if (isp_check_aux_image_status_signature(&pri_aux_image_status)) {
4966 		isp_prt(isp, ISP_LOGERR,
4967 		    "Primary aux image signature (0x%x) not valid",
4968 		    le32toh(pri_aux_image_status.signature));
4969 		goto check_sec_image;
4970 	}
4971 
4972 	if (isp_image_status_checksum(&pri_aux_image_status)) {
4973 		isp_prt(isp, ISP_LOGERR,
4974 		    "Primary aux image checksum failed");
4975 		goto check_sec_image;
4976 	}
4977 
4978 	valid_pri_image = true;
4979 
4980 	if (pri_aux_image_status.image_status_mask & 1) {
4981 		isp_prt(isp, ISP_LOGCONFIG,
4982 		    "Primary aux image is active");
4983 		active_pri_image = true;
4984 	}
4985 
4986 check_sec_image:
4987 	if (!fcp->flt_region_aux_img_status_sec) {
4988 		isp_prt(isp, ISP_LOGWARN,
4989 		    "Secondary aux image not addressed");
4990 		goto check_valid_image;
4991 	}
4992 
4993 	isp_read_flash_data(isp, (uint32_t *)&sec_aux_image_status,
4994 	    fcp->flt_region_aux_img_status_sec,
4995 	    sizeof(sec_aux_image_status) >> 2);
4996 	isp_print_image(isp, "Secondary aux image", &sec_aux_image_status);
4997 
4998 	if (isp_check_aux_image_status_signature(&sec_aux_image_status)) {
4999 		isp_prt(isp, ISP_LOGERR,
5000 		    "Secondary aux image signature (0x%x) not valid",
5001 		    le32toh(sec_aux_image_status.signature));
5002 		goto check_valid_image;
5003 	}
5004 
5005 	if (isp_image_status_checksum(&sec_aux_image_status)) {
5006 		isp_prt(isp, ISP_LOGERR,
5007 		    "Secondary aux image checksum failed");
5008 		goto check_valid_image;
5009 	}
5010 
5011 	valid_sec_image = true;
5012 
5013 	if (sec_aux_image_status.image_status_mask & 1) {
5014 		isp_prt(isp, ISP_LOGCONFIG,
5015 		    "Secondary aux image is active");
5016 		active_sec_image = true;
5017 	}
5018 
5019 check_valid_image:
5020 	if (valid_pri_image && active_pri_image &&
5021 	    valid_sec_image && active_sec_image) {
5022 		if (isp_compare_image_generation(isp, &pri_aux_image_status,
5023 		    &sec_aux_image_status) >= 0) {
5024 			isp_component_status(active_regions,
5025 			    &pri_aux_image_status);
5026 		} else {
5027 			isp_component_status(active_regions,
5028 			    &sec_aux_image_status);
5029 		}
5030 	} else if (valid_pri_image && active_pri_image) {
5031 		isp_component_status(active_regions, &pri_aux_image_status);
5032 	} else if (valid_sec_image && active_sec_image) {
5033 		isp_component_status(active_regions, &sec_aux_image_status);
5034 	}
5035 
5036 	isp_prt(isp, ISP_LOGDEBUG0,
5037 	    "aux images active: BCFG=%u VPD/NVR=%u NPIV0/1=%u NPIV2/3=%u, NVME=%u",
5038 	    active_regions->aux.board_config,
5039 	    active_regions->aux.vpd_nvram,
5040 	    active_regions->aux.npiv_config_0_1,
5041 	    active_regions->aux.npiv_config_2_3,
5042 	    active_regions->aux.nvme_params);
5043 }
5044 
5045 static void
5046 isp_get_active_image(ispsoftc_t *isp, struct active_regions * active_regions)
5047 {
5048 	fcparam *fcp = FCPARAM(isp, 0);
5049 	struct isp_image_status pri_image_status, sec_image_status;
5050 	bool valid_pri_image = false, valid_sec_image = false;
5051 	bool active_pri_image = false, active_sec_image = false;
5052 
5053 	if (!fcp->flt_region_img_status_pri) {
5054 		isp_prt(isp, ISP_LOGWARN,
5055 		    "Primary image not addressed");
5056 		goto check_sec_image;
5057 	}
5058 
5059 	if (isp_read_flash_data(isp, (uint32_t *) &pri_image_status,
5060 	    fcp->flt_region_img_status_pri, sizeof(pri_image_status) >> 2) !=
5061 	    ISP_SUCCESS)
5062 		goto check_sec_image;
5063 
5064 	isp_print_image(isp, "Primary image", &pri_image_status);
5065 
5066 	if (isp_check_image_status_signature(&pri_image_status)) {
5067 		isp_prt(isp, ISP_LOGERR,
5068 		    "Primary image signature (0x%x) not valid",
5069 		    le32toh(pri_image_status.signature));
5070 		goto check_sec_image;
5071 	}
5072 
5073 	if (isp_image_status_checksum(&pri_image_status)) {
5074 		isp_prt(isp, ISP_LOGERR,
5075 		    "Primary image checksum failed");
5076 		goto check_sec_image;
5077 	}
5078 
5079 	valid_pri_image = true;
5080 
5081 	if (pri_image_status.image_status_mask & 1) {
5082 		isp_prt(isp, ISP_LOGCONFIG,
5083 		    "Primary image is active");
5084 		active_pri_image = true;
5085 	}
5086 
5087 check_sec_image:
5088 	if (!fcp->flt_region_img_status_sec) {
5089 		isp_prt(isp, ISP_LOGWARN,
5090 		    "Secondary image not addressed");
5091 		return;
5092 	}
5093 
5094 	if (isp_read_flash_data(isp, (uint32_t *) &sec_image_status,
5095 	    fcp->flt_region_img_status_sec, sizeof(sec_image_status) >> 2) !=
5096 	    ISP_SUCCESS)
5097 		return;
5098 
5099 	isp_print_image(isp, "Secondary image", &sec_image_status);
5100 
5101 	if (isp_check_image_status_signature(&sec_image_status)) {
5102 		isp_prt(isp, ISP_LOGERR,
5103 		    "Secondary image signature (0x%x) not valid",
5104 		    le32toh(sec_image_status.signature));
5105 	}
5106 
5107 	if (isp_image_status_checksum(&sec_image_status)) {
5108 		isp_prt(isp, ISP_LOGERR,
5109 		    "Secondary image checksum failed");
5110 		goto check_valid_image;
5111 	}
5112 
5113 	valid_sec_image = true;
5114 
5115 	if (sec_image_status.image_status_mask & 1) {
5116 		isp_prt(isp, ISP_LOGCONFIG,
5117 		    "Secondary image is active");
5118 		active_sec_image = true;
5119 	}
5120 
5121 check_valid_image:
5122 	if (valid_pri_image && active_pri_image)
5123 		active_regions->global = ISP27XX_PRIMARY_IMAGE;
5124 
5125 	if (valid_sec_image && active_sec_image) {
5126 		if (!active_regions->global ||
5127 		    isp_compare_image_generation(isp,
5128 			&pri_image_status, &sec_image_status) < 0) {
5129 			active_regions->global = ISP27XX_SECONDARY_IMAGE;
5130 		}
5131 	}
5132 
5133 	isp_prt(isp, ISP_LOGDEBUG0, "active image %s (%u)",
5134 	    active_regions->global == ISP27XX_DEFAULT_IMAGE ?
5135 		"default (boot/fw)" :
5136 	    active_regions->global == ISP27XX_PRIMARY_IMAGE ?
5137 		"primary" :
5138 	    active_regions->global == ISP27XX_SECONDARY_IMAGE ?
5139 		"secondary" : "invalid",
5140 	    active_regions->global);
5141 }
5142 
5143 static bool isp_risc_firmware_invalid(ispsoftc_t *isp, uint32_t *dword)
5144 {
5145 	return ((dword[4] | dword[5] | dword[6] | dword[7]) == 0 ||
5146 	    (~dword[4] | ~dword[5] | ~dword[6] | ~dword[7]) == 0);
5147 }
5148 
5149 static int
5150 isp_load_ram(ispsoftc_t *isp, uint32_t *data, uint32_t risc_addr,
5151     uint32_t risc_code_size)
5152 {
5153 	mbreg_t mbs;
5154 	int rval = ISP_SUCCESS;
5155 
5156 	MEMORYBARRIER(isp, SYNC_REQUEST, 0, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)), -1);
5157 	MBSINIT(&mbs, MBOX_LOAD_RISC_RAM, MBLOGALL, 0);
5158 	mbs.param[1] = risc_addr;
5159 	mbs.param[2] = DMA_WD1(isp->isp_rquest_dma);
5160 	mbs.param[3] = DMA_WD0(isp->isp_rquest_dma);
5161 	mbs.param[4] = risc_code_size >> 16;
5162 	mbs.param[5] = risc_code_size;
5163 	mbs.param[6] = DMA_WD3(isp->isp_rquest_dma);
5164 	mbs.param[7] = DMA_WD2(isp->isp_rquest_dma);
5165 	mbs.param[8] = risc_addr >> 16;
5166 	isp_prt(isp, ISP_LOGDEBUG0,
5167 	    "LOAD RISC RAM %u (0x%x) words at load address 0x%x",
5168 	    risc_code_size, risc_code_size, risc_addr);
5169 	isp_mboxcmd(isp, &mbs);
5170 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
5171 		isp_prt(isp, ISP_LOGERR, "F/W download failed");
5172 		rval = ISP_FUNCTION_FAILED;
5173 	}
5174 
5175 	return (rval);
5176 }
5177 
5178 static int
5179 isp_load_risc_flash(ispsoftc_t *isp, uint32_t *srisc_addr, uint32_t faddr)
5180 {
5181 	fcparam *fcp = FCPARAM(isp, 0);
5182 	int rval = ISP_SUCCESS;
5183 	unsigned int segments, fragment;
5184 	unsigned long i;
5185 	unsigned int j;
5186 	unsigned long dlen;
5187 	uint32_t *dcode;
5188 	uint32_t risc_addr, risc_size = 0;
5189 
5190 	isp_prt(isp, ISP_LOGDEBUG0,
5191 	    "Accessing flash firmware at 0x%x.", faddr);
5192 
5193 	dcode = isp->isp_rquest;
5194 	isp_read_flash_data(isp, dcode, faddr, 8);
5195 	if (isp_risc_firmware_invalid(isp, dcode)) {
5196 		snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5197 		    "invalid");
5198 		isp_prt(isp, ISP_LOGERR,
5199 		    "Unable to verify the integrity of flash firmware image.");
5200 		isp_prt(isp, ISP_LOGERR,
5201 		    "Firmware data: 0x%08x 0x%08x 0x%08x 0x%08x.",
5202 		    dcode[0], dcode[1], dcode[2], dcode[3]);
5203 		return (ISP_FUNCTION_FAILED);
5204 	} else {
5205 		for (i = 0; i < 4; i++)
5206 			fcp->fw_flashrev[i] = be32toh(dcode[4 + i]);
5207 		snprintf(fcp->fw_version_flash, sizeof(fcp->fw_version_flash),
5208 		    "%u.%u.%u", fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5209 		    fcp->fw_flashrev[2]);
5210 		isp_prt(isp, ISP_LOGCONFIG,
5211 		    "Firmware revision (flash) %u.%u.%u (%x).",
5212 		    fcp->fw_flashrev[0], fcp->fw_flashrev[1],
5213 		    fcp->fw_flashrev[2], fcp->fw_flashrev[3]);
5214 
5215 		/* If ispfw(4) is loaded compare versions and use the newest */
5216 		if (isp->isp_osinfo.ispfw != NULL) {
5217 			if (ISP_FW_NEWER_THANX(fcp->fw_ispfwrev, fcp->fw_flashrev)) {
5218 				isp_prt(isp, ISP_LOGCONFIG,
5219 				    "Loading RISC with newer ispfw(4) firmware");
5220 				return (ISP_ABORTED);
5221 			}
5222 			isp_prt(isp, ISP_LOGCONFIG,
5223 			    "Loading RISC with newer flash firmware");
5224 		}
5225 	}
5226 
5227 	dcode = isp->isp_rquest;
5228 	segments = ISP_RISC_CODE_SEGMENTS;
5229 	for (j = 0; j < segments; j++) {
5230 		isp_prt(isp, ISP_LOGDEBUG0, "Loading segment %u", j);
5231 		isp_read_flash_data(isp, dcode, faddr, 10);
5232 		risc_addr = be32toh(dcode[2]);
5233 		risc_size = be32toh(dcode[3]);
5234 
5235 		dlen = min(risc_size, ISP_QUEUE_SIZE(RQUEST_QUEUE_LEN(isp)) / 4);
5236 		for (fragment = 0; risc_size; fragment++) {
5237 			if (dlen > risc_size)
5238 				dlen = risc_size;
5239 
5240 			isp_prt(isp, ISP_LOGDEBUG0,
5241 			    "Loading fragment %u: 0x%x <- 0x%x (0x%lx dwords)",
5242 			    fragment, risc_addr, faddr, dlen);
5243 			isp_read_flash_data(isp, dcode, faddr, dlen);
5244 			for (i = 0; i < dlen; i++) {
5245 				dcode[i] = bswap32(dcode[i]);
5246 			}
5247 
5248 			rval = isp_load_ram(isp, dcode, risc_addr, dlen);
5249 			if (rval) {
5250 				isp_prt(isp, ISP_LOGERR,
5251 				    "Failed to load firmware fragment %u.",
5252 				    fragment);
5253 				return (ISP_FUNCTION_FAILED);
5254 			}
5255 
5256 			faddr += dlen;
5257 			risc_addr += dlen;
5258 			risc_size -= dlen;
5259 		}
5260 	}
5261 
5262 	return (rval);
5263 }
5264 
5265 static int
5266 isp_load_risc(ispsoftc_t *isp, uint32_t *srisc_addr)
5267 {
5268 	fcparam *fcp = FCPARAM(isp, 0);
5269 	int rval = ISP_SUCCESS;
5270 	struct active_regions active_regions = { };
5271 
5272 	/*
5273 	 * Starting with 27xx there is a primary and secondary firmware region
5274 	 * in flash. All older controllers just have one firmware region.
5275 	 */
5276 	if (!IS_27XX(isp))
5277 		goto try_primary_fw;
5278 
5279 	isp_get_active_image(isp, &active_regions);
5280 
5281 	if (active_regions.global != ISP27XX_SECONDARY_IMAGE)
5282 		goto try_primary_fw;
5283 
5284 	isp_prt(isp, ISP_LOGCONFIG,
5285 	    "Loading secondary firmware image.");
5286 	rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw_sec);
5287 	return (rval);
5288 
5289 try_primary_fw:
5290 	isp_prt(isp, ISP_LOGCONFIG,
5291 	    "Loading primary firmware image.");
5292 	rval = isp_load_risc_flash(isp, srisc_addr, fcp->flt_region_fw);
5293 	return (rval);
5294 }
5295 
5296 static int
5297 isp_read_nvram(ispsoftc_t *isp)
5298 {
5299 	fcparam *fcp = FCPARAM(isp, 0);
5300 	int retval = 0;
5301 	uint32_t addr, csum, lwrds, *dptr;
5302 	uint8_t nvram_data[ISP2400_NVRAM_SIZE];
5303 	struct active_regions active_regions = { };
5304 
5305 	if (IS_27XX(isp))
5306 		isp_get_aux_images(isp, &active_regions);
5307 
5308 	addr = fcp->flt_region_nvram;
5309 
5310 	if (IS_28XX(isp)) {
5311 		if (active_regions.aux.vpd_nvram == ISP27XX_SECONDARY_IMAGE)
5312 			addr = fcp->flt_region_nvram_sec;
5313 
5314 		isp_prt(isp, ISP_LOGCONFIG, "Loading %s NVRAM image",
5315 		    active_regions.aux.vpd_nvram == ISP27XX_PRIMARY_IMAGE ?
5316 		    "primary" : "secondary");
5317 	}
5318 
5319 	dptr = (uint32_t *) nvram_data;
5320 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5321 		isp_rd_2xxx_flash(isp, addr++, dptr++);
5322 	}
5323 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
5324 	    nvram_data[2] != 'P') {
5325 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
5326 		    nvram_data[0], nvram_data[1], nvram_data[2]);
5327 		retval = -1;
5328 		goto out;
5329 	}
5330 	dptr = (uint32_t *) nvram_data;
5331 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
5332 		uint32_t tmp;
5333 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
5334 		csum += tmp;
5335 	}
5336 	if (csum != 0) {
5337 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
5338 		retval = -1;
5339 		goto out;
5340 	}
5341 	isp_parse_nvram_2400(isp, nvram_data);
5342 out:
5343 	return (retval);
5344 }
5345 
5346 static void
5347 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
5348 {
5349 	fcparam *fcp = FCPARAM(isp, 0);
5350 	uint64_t wwn;
5351 
5352 	isp_prt(isp, ISP_LOGDEBUG0,
5353 	    "NVRAM 0x%08x%08x 0x%08x%08x maxframelen %d",
5354 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
5355 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
5356 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
5357 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
5358 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
5359 	isp_prt(isp, ISP_LOGDEBUG0,
5360 	    "NVRAM loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
5361 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
5362 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
5363 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
5364 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
5365 
5366 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
5367 	fcp->isp_wwpn_nvram = wwn;
5368 
5369 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
5370 	if (wwn) {
5371 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
5372 			wwn = 0;
5373 		}
5374 	}
5375 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
5376 		wwn = fcp->isp_wwpn_nvram;
5377 		wwn &= ~((uint64_t) 0xfff << 48);
5378 	}
5379 	fcp->isp_wwnn_nvram = wwn;
5380 
5381 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
5382 		DEFAULT_FRAMESIZE(isp) =
5383 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
5384 	}
5385 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
5386 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
5387 	}
5388 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
5389 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
5390 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
5391 }
5392