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