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