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