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