xref: /freebsd/sys/dev/isp/isp.c (revision d8eb75b41884ff1a9e257ae68ccce691e7be4e3c)
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, 500000);
2450 	mbs.param[1] = QENTRY_LEN;
2451 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2452 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2453 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2454 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2455 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
2456 	isp_mboxcmd(isp, &mbs);
2457 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2458 		rval = mbs.param[0];
2459 		goto out;
2460 	}
2461 	MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
2462 	scp += QENTRY_LEN;
2463 	isp_get_plogx(isp, (isp_plogx_t *) scp, plp);
2464 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
2465 		isp_print_bytes(isp, "IOCB LOGX response", QENTRY_LEN, plp);
2466 	}
2467 
2468 	if (plp->plogx_status == PLOGX_STATUS_OK) {
2469 		rval = 0;
2470 		goto out;
2471 	} else if (plp->plogx_status != PLOGX_STATUS_IOCBERR) {
2472 		isp_prt(isp, ISP_LOGWARN,
2473 		    "status 0x%x on port login IOCB channel %d",
2474 		    plp->plogx_status, chan);
2475 		rval = -1;
2476 		goto out;
2477 	}
2478 
2479 	sst = plp->plogx_ioparm[0].lo16 | (plp->plogx_ioparm[0].hi16 << 16);
2480 	parm1 = plp->plogx_ioparm[1].lo16 | (plp->plogx_ioparm[1].hi16 << 16);
2481 
2482 	rval = -1;
2483 	lev = ISP_LOGERR;
2484 	msg = NULL;
2485 
2486 	switch (sst) {
2487 	case PLOGX_IOCBERR_NOLINK:
2488 		msg = "no link";
2489 		break;
2490 	case PLOGX_IOCBERR_NOIOCB:
2491 		msg = "no IOCB buffer";
2492 		break;
2493 	case PLOGX_IOCBERR_NOXGHG:
2494 		msg = "no Exchange Control Block";
2495 		break;
2496 	case PLOGX_IOCBERR_FAILED:
2497 		ISP_SNPRINTF(buf, sizeof (buf), "reason 0x%x (last LOGIN state 0x%x)", parm1 & 0xff, (parm1 >> 8) & 0xff);
2498 		msg = buf;
2499 		break;
2500 	case PLOGX_IOCBERR_NOFABRIC:
2501 		msg = "no fabric";
2502 		break;
2503 	case PLOGX_IOCBERR_NOTREADY:
2504 		msg = "firmware not ready";
2505 		break;
2506 	case PLOGX_IOCBERR_NOLOGIN:
2507 		ISP_SNPRINTF(buf, sizeof (buf), "not logged in (last state 0x%x)", parm1);
2508 		msg = buf;
2509 		rval = MBOX_NOT_LOGGED_IN;
2510 		break;
2511 	case PLOGX_IOCBERR_REJECT:
2512 		ISP_SNPRINTF(buf, sizeof (buf), "LS_RJT = 0x%x", parm1);
2513 		msg = buf;
2514 		break;
2515 	case PLOGX_IOCBERR_NOPCB:
2516 		msg = "no PCB allocated";
2517 		break;
2518 	case PLOGX_IOCBERR_EINVAL:
2519 		ISP_SNPRINTF(buf, sizeof (buf), "invalid parameter at offset 0x%x", parm1);
2520 		msg = buf;
2521 		break;
2522 	case PLOGX_IOCBERR_PORTUSED:
2523 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
2524 		ISP_SNPRINTF(buf, sizeof (buf), "already logged in with N-Port handle 0x%x", parm1);
2525 		msg = buf;
2526 		rval = MBOX_PORT_ID_USED | (parm1 << 16);
2527 		break;
2528 	case PLOGX_IOCBERR_HNDLUSED:
2529 		lev = ISP_LOG_SANCFG|ISP_LOG_WARN1;
2530 		ISP_SNPRINTF(buf, sizeof (buf), "handle already used for PortID 0x%06x", parm1);
2531 		msg = buf;
2532 		rval = MBOX_LOOP_ID_USED;
2533 		break;
2534 	case PLOGX_IOCBERR_NOHANDLE:
2535 		msg = "no handle allocated";
2536 		break;
2537 	case PLOGX_IOCBERR_NOFLOGI:
2538 		msg = "no FLOGI_ACC";
2539 		break;
2540 	default:
2541 		ISP_SNPRINTF(buf, sizeof (buf), "status %x from %x", plp->plogx_status, flags);
2542 		msg = buf;
2543 		break;
2544 	}
2545 	if (msg) {
2546 		isp_prt(isp, ISP_LOGERR, "Chan %d PLOGX PortID 0x%06x to N-Port handle 0x%x: %s", chan, portid, handle, msg);
2547 	}
2548 out:
2549 	if (gs == 0) {
2550 		FC_SCRATCH_RELEASE(isp, chan);
2551 	}
2552 	return (rval);
2553 }
2554 
2555 static int
2556 isp_port_login(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2557 {
2558 	mbreg_t mbs;
2559 
2560 	MBSINIT(&mbs, MBOX_FABRIC_LOGIN, MBLOGNONE, 500000);
2561 	if (ISP_CAP_2KLOGIN(isp)) {
2562 		mbs.param[1] = handle;
2563 		mbs.ibits = (1 << 10);
2564 	} else {
2565 		mbs.param[1] = handle << 8;
2566 	}
2567 	mbs.param[2] = portid >> 16;
2568 	mbs.param[3] = portid;
2569 	mbs.logval = MBLOGNONE;
2570 	mbs.timeout = 500000;
2571 	isp_mboxcmd(isp, &mbs);
2572 
2573 	switch (mbs.param[0]) {
2574 	case MBOX_PORT_ID_USED:
2575 		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]);
2576 		return (MBOX_PORT_ID_USED | (mbs.param[1] << 16));
2577 
2578 	case MBOX_LOOP_ID_USED:
2579 		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);
2580 		return (MBOX_LOOP_ID_USED);
2581 
2582 	case MBOX_COMMAND_COMPLETE:
2583 		return (0);
2584 
2585 	case MBOX_COMMAND_ERROR:
2586 		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);
2587 		return (MBOX_COMMAND_ERROR);
2588 
2589 	case MBOX_ALL_IDS_USED:
2590 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "isp_port_login: all IDs used for fabric login");
2591 		return (MBOX_ALL_IDS_USED);
2592 
2593 	default:
2594 		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);
2595 		return (mbs.param[0]);
2596 	}
2597 }
2598 
2599 /*
2600  * Pre-24XX fabric port logout
2601  *
2602  * Note that portid is not used
2603  */
2604 static int
2605 isp_port_logout(ispsoftc_t *isp, uint16_t handle, uint32_t portid)
2606 {
2607 	mbreg_t mbs;
2608 
2609 	MBSINIT(&mbs, MBOX_FABRIC_LOGOUT, MBLOGNONE, 500000);
2610 	if (ISP_CAP_2KLOGIN(isp)) {
2611 		mbs.param[1] = handle;
2612 		mbs.ibits = (1 << 10);
2613 	} else {
2614 		mbs.param[1] = handle << 8;
2615 	}
2616 	isp_mboxcmd(isp, &mbs);
2617 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE? 0 : mbs.param[0]);
2618 }
2619 
2620 static int
2621 isp_getpdb(ispsoftc_t *isp, int chan, uint16_t id, isp_pdb_t *pdb, int dolock)
2622 {
2623 	fcparam *fcp = FCPARAM(isp, chan);
2624 	mbreg_t mbs;
2625 	union {
2626 		isp_pdb_21xx_t fred;
2627 		isp_pdb_24xx_t bill;
2628 	} un;
2629 
2630 	MBSINIT(&mbs, MBOX_GET_PORT_DB,
2631 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 250000);
2632 	if (IS_24XX(isp)) {
2633 		mbs.ibits = (1 << 9)|(1 << 10);
2634 		mbs.param[1] = id;
2635 		mbs.param[9] = chan;
2636 	} else if (ISP_CAP_2KLOGIN(isp)) {
2637 		mbs.param[1] = id;
2638 	} else {
2639 		mbs.param[1] = id << 8;
2640 	}
2641 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2642 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2643 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2644 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2645 	if (dolock) {
2646 		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2647 			isp_prt(isp, ISP_LOGERR, sacq);
2648 			return (-1);
2649 		}
2650 	}
2651 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, sizeof (un), chan);
2652 	isp_mboxcmd(isp, &mbs);
2653 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2654 		if (dolock) {
2655 			FC_SCRATCH_RELEASE(isp, chan);
2656 		}
2657 		return (mbs.param[0] | (mbs.param[1] << 16));
2658 	}
2659 	if (IS_24XX(isp)) {
2660 		isp_get_pdb_24xx(isp, fcp->isp_scratch, &un.bill);
2661 		pdb->handle = un.bill.pdb_handle;
2662 		pdb->prli_word3 = un.bill.pdb_prli_svc3;
2663 		pdb->portid = BITS2WORD_24XX(un.bill.pdb_portid_bits);
2664 		ISP_MEMCPY(pdb->portname, un.bill.pdb_portname, 8);
2665 		ISP_MEMCPY(pdb->nodename, un.bill.pdb_nodename, 8);
2666 		isp_prt(isp, ISP_LOGDEBUG1,
2667 		    "Chan %d handle 0x%x Port 0x%06x flags 0x%x curstate %x",
2668 		    chan, id, pdb->portid, un.bill.pdb_flags,
2669 		    un.bill.pdb_curstate);
2670 		if (un.bill.pdb_curstate < PDB2400_STATE_PLOGI_DONE || un.bill.pdb_curstate > PDB2400_STATE_LOGGED_IN) {
2671 			mbs.param[0] = MBOX_NOT_LOGGED_IN;
2672 			if (dolock) {
2673 				FC_SCRATCH_RELEASE(isp, chan);
2674 			}
2675 			return (mbs.param[0]);
2676 		}
2677 	} else {
2678 		isp_get_pdb_21xx(isp, fcp->isp_scratch, &un.fred);
2679 		pdb->handle = un.fred.pdb_loopid;
2680 		pdb->prli_word3 = un.fred.pdb_prli_svc3;
2681 		pdb->portid = BITS2WORD(un.fred.pdb_portid_bits);
2682 		ISP_MEMCPY(pdb->portname, un.fred.pdb_portname, 8);
2683 		ISP_MEMCPY(pdb->nodename, un.fred.pdb_nodename, 8);
2684 		isp_prt(isp, ISP_LOGDEBUG1,
2685 		    "Chan %d handle 0x%x Port 0x%06x", chan, id, pdb->portid);
2686 	}
2687 	if (dolock) {
2688 		FC_SCRATCH_RELEASE(isp, chan);
2689 	}
2690 	return (0);
2691 }
2692 
2693 static int
2694 isp_gethandles(ispsoftc_t *isp, int chan, uint16_t *handles, int *num,
2695     int dolock, int loop)
2696 {
2697 	fcparam *fcp = FCPARAM(isp, chan);
2698 	mbreg_t mbs;
2699 	isp_pnhle_21xx_t el1, *elp1;
2700 	isp_pnhle_23xx_t el3, *elp3;
2701 	isp_pnhle_24xx_t el4, *elp4;
2702 	int i, j;
2703 	uint32_t p;
2704 	uint16_t h;
2705 
2706 	MBSINIT(&mbs, MBOX_GET_ID_LIST, MBLOGALL, 250000);
2707 	if (IS_24XX(isp)) {
2708 		mbs.param[2] = DMA_WD1(fcp->isp_scdma);
2709 		mbs.param[3] = DMA_WD0(fcp->isp_scdma);
2710 		mbs.param[6] = DMA_WD3(fcp->isp_scdma);
2711 		mbs.param[7] = DMA_WD2(fcp->isp_scdma);
2712 		mbs.param[8] = ISP_FC_SCRLEN;
2713 		mbs.param[9] = chan;
2714 	} else {
2715 		mbs.ibits = (1 << 1)|(1 << 2)|(1 << 3)|(1 << 6);
2716 		mbs.param[1] = DMA_WD1(fcp->isp_scdma);
2717 		mbs.param[2] = DMA_WD0(fcp->isp_scdma);
2718 		mbs.param[3] = DMA_WD3(fcp->isp_scdma);
2719 		mbs.param[6] = DMA_WD2(fcp->isp_scdma);
2720 	}
2721 	if (dolock) {
2722 		if (FC_SCRATCH_ACQUIRE(isp, chan)) {
2723 			isp_prt(isp, ISP_LOGERR, sacq);
2724 			return (-1);
2725 		}
2726 	}
2727 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, ISP_FC_SCRLEN, chan);
2728 	isp_mboxcmd(isp, &mbs);
2729 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2730 		if (dolock) {
2731 			FC_SCRATCH_RELEASE(isp, chan);
2732 		}
2733 		return (mbs.param[0] | (mbs.param[1] << 16));
2734 	}
2735 	elp1 = fcp->isp_scratch;
2736 	elp3 = fcp->isp_scratch;
2737 	elp4 = fcp->isp_scratch;
2738 	for (i = 0, j = 0; i < mbs.param[1] && j < *num; i++) {
2739 		if (IS_24XX(isp)) {
2740 			isp_get_pnhle_24xx(isp, &elp4[i], &el4);
2741 			p = el4.pnhle_port_id_lo |
2742 			    (el4.pnhle_port_id_hi << 16);
2743 			h = el4.pnhle_handle;
2744 		} else if (IS_23XX(isp)) {
2745 			isp_get_pnhle_23xx(isp, &elp3[i], &el3);
2746 			p = el3.pnhle_port_id_lo |
2747 			    (el3.pnhle_port_id_hi << 16);
2748 			h = el3.pnhle_handle;
2749 		} else { /* 21xx */
2750 			isp_get_pnhle_21xx(isp, &elp1[i], &el1);
2751 			p = el1.pnhle_port_id_lo |
2752 			    ((el1.pnhle_port_id_hi_handle & 0xff) << 16);
2753 			h = el1.pnhle_port_id_hi_handle >> 8;
2754 		}
2755 		if (loop && (p >> 8) != (fcp->isp_portid >> 8))
2756 			continue;
2757 		handles[j++] = h;
2758 	}
2759 	*num = j;
2760 	if (dolock)
2761 		FC_SCRATCH_RELEASE(isp, chan);
2762 	return (0);
2763 }
2764 
2765 static void
2766 isp_dump_chip_portdb(ispsoftc_t *isp, int chan, int dolock)
2767 {
2768 	isp_pdb_t pdb;
2769 	uint16_t lim, nphdl;
2770 
2771 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d chip port dump", chan);
2772 	if (ISP_CAP_2KLOGIN(isp)) {
2773 		lim = NPH_MAX_2K;
2774 	} else {
2775 		lim = NPH_MAX;
2776 	}
2777 	for (nphdl = 0; nphdl != lim; nphdl++) {
2778 		if (isp_getpdb(isp, chan, nphdl, &pdb, dolock)) {
2779 			continue;
2780 		}
2781 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGINFO, "Chan %d Handle 0x%04x "
2782 		    "PortID 0x%06x WWPN 0x%02x%02x%02x%02x%02x%02x%02x%02x",
2783 		    chan, nphdl, pdb.portid, pdb.portname[0], pdb.portname[1],
2784 		    pdb.portname[2], pdb.portname[3], pdb.portname[4],
2785 		    pdb.portname[5], pdb.portname[6], pdb.portname[7]);
2786 	}
2787 }
2788 
2789 static uint64_t
2790 isp_get_wwn(ispsoftc_t *isp, int chan, int nphdl, int nodename)
2791 {
2792 	uint64_t wwn = INI_NONE;
2793 	mbreg_t mbs;
2794 
2795 	MBSINIT(&mbs, MBOX_GET_PORT_NAME,
2796 	    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_PARAM_ERROR), 500000);
2797 	if (ISP_CAP_2KLOGIN(isp)) {
2798 		mbs.param[1] = nphdl;
2799 		if (nodename) {
2800 			mbs.param[10] = 1;
2801 		}
2802 		mbs.param[9] = chan;
2803 	} else {
2804 		mbs.ibitm = 3;
2805 		mbs.param[1] = nphdl << 8;
2806 		if (nodename) {
2807 			mbs.param[1] |= 1;
2808 		}
2809 	}
2810 	isp_mboxcmd(isp, &mbs);
2811 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2812 		return (wwn);
2813 	}
2814 	if (IS_24XX(isp)) {
2815 		wwn =
2816 		    (((uint64_t)(mbs.param[2] >> 8))	<< 56) |
2817 		    (((uint64_t)(mbs.param[2] & 0xff))	<< 48) |
2818 		    (((uint64_t)(mbs.param[3] >> 8))	<< 40) |
2819 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 32) |
2820 		    (((uint64_t)(mbs.param[6] >> 8))	<< 24) |
2821 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 16) |
2822 		    (((uint64_t)(mbs.param[7] >> 8))	<<  8) |
2823 		    (((uint64_t)(mbs.param[7] & 0xff)));
2824 	} else {
2825 		wwn =
2826 		    (((uint64_t)(mbs.param[2] & 0xff))  << 56) |
2827 		    (((uint64_t)(mbs.param[2] >> 8))	<< 48) |
2828 		    (((uint64_t)(mbs.param[3] & 0xff))	<< 40) |
2829 		    (((uint64_t)(mbs.param[3] >> 8))	<< 32) |
2830 		    (((uint64_t)(mbs.param[6] & 0xff))	<< 24) |
2831 		    (((uint64_t)(mbs.param[6] >> 8))	<< 16) |
2832 		    (((uint64_t)(mbs.param[7] & 0xff))	<<  8) |
2833 		    (((uint64_t)(mbs.param[7] >> 8)));
2834 	}
2835 	return (wwn);
2836 }
2837 
2838 /*
2839  * Make sure we have good FC link.
2840  */
2841 
2842 static int
2843 isp_fclink_test(ispsoftc_t *isp, int chan, int usdelay)
2844 {
2845 	mbreg_t mbs;
2846 	int i, r;
2847 	uint16_t nphdl;
2848 	fcparam *fcp;
2849 	isp_pdb_t pdb;
2850 	NANOTIME_T hra, hrb;
2851 
2852 	fcp = FCPARAM(isp, chan);
2853 
2854 	if (fcp->isp_loopstate < LOOP_HAVE_LINK)
2855 		return (-1);
2856 	if (fcp->isp_loopstate >= LOOP_LTEST_DONE)
2857 		return (0);
2858 
2859 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test", chan);
2860 	fcp->isp_loopstate = LOOP_TESTING_LINK;
2861 
2862 	/*
2863 	 * Wait up to N microseconds for F/W to go to a ready state.
2864 	 */
2865 	GET_NANOTIME(&hra);
2866 	while (1) {
2867 		isp_change_fw_state(isp, chan, isp_fw_state(isp, chan));
2868 		if (fcp->isp_fwstate == FW_READY) {
2869 			break;
2870 		}
2871 		if (fcp->isp_loopstate < LOOP_TESTING_LINK)
2872 			goto abort;
2873 		GET_NANOTIME(&hrb);
2874 		if ((NANOTIME_SUB(&hrb, &hra) / 1000 + 1000 >= usdelay))
2875 			break;
2876 		ISP_SLEEP(isp, 1000);
2877 	}
2878 	if (fcp->isp_fwstate != FW_READY) {
2879 		isp_prt(isp, ISP_LOG_SANCFG,
2880 		    "Chan %d Firmware is not ready (%s)",
2881 		    chan, isp_fc_fw_statename(fcp->isp_fwstate));
2882 		return (-1);
2883 	}
2884 
2885 	/*
2886 	 * Get our Loop ID and Port ID.
2887 	 */
2888 	MBSINIT(&mbs, MBOX_GET_LOOP_ID, MBLOGALL, 0);
2889 	mbs.param[9] = chan;
2890 	isp_mboxcmd(isp, &mbs);
2891 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2892 		return (-1);
2893 	}
2894 
2895 	if (IS_2100(isp)) {
2896 		/*
2897 		 * Don't bother with fabric if we are using really old
2898 		 * 2100 firmware. It's just not worth it.
2899 		 */
2900 		if (ISP_FW_NEWER_THAN(isp, 1, 15, 37))
2901 			fcp->isp_topo = TOPO_FL_PORT;
2902 		else
2903 			fcp->isp_topo = TOPO_NL_PORT;
2904 	} else {
2905 		int topo = (int) mbs.param[6];
2906 		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB) {
2907 			topo = TOPO_PTP_STUB;
2908 		}
2909 		fcp->isp_topo = topo;
2910 	}
2911 	fcp->isp_portid = mbs.param[2] | (mbs.param[3] << 16);
2912 
2913 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
2914 		fcp->isp_loopid = mbs.param[1] & 0xff;
2915 	} else if (fcp->isp_topo != TOPO_F_PORT) {
2916 		uint8_t alpa = fcp->isp_portid;
2917 
2918 		for (i = 0; alpa_map[i]; i++) {
2919 			if (alpa_map[i] == alpa)
2920 				break;
2921 		}
2922 		if (alpa_map[i])
2923 			fcp->isp_loopid = i;
2924 	}
2925 
2926 	if (fcp->isp_topo == TOPO_F_PORT || fcp->isp_topo == TOPO_FL_PORT) {
2927 		nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
2928 		r = isp_getpdb(isp, chan, nphdl, &pdb, 1);
2929 		if (r != 0 || pdb.portid == 0) {
2930 			if (IS_2100(isp)) {
2931 				fcp->isp_topo = TOPO_NL_PORT;
2932 			} else {
2933 				isp_prt(isp, ISP_LOGWARN,
2934 				    "fabric topology, but cannot get info about fabric controller (0x%x)", r);
2935 				fcp->isp_topo = TOPO_PTP_STUB;
2936 			}
2937 			goto not_on_fabric;
2938 		}
2939 
2940 		if (IS_24XX(isp)) {
2941 			fcp->isp_fabric_params = mbs.param[7];
2942 			fcp->isp_sns_hdl = NPH_SNS_ID;
2943 			r = isp_register_fc4_type_24xx(isp, chan);
2944 			if (r == 0)
2945 				isp_register_fc4_features_24xx(isp, chan);
2946 		} else {
2947 			fcp->isp_sns_hdl = SNS_ID;
2948 			r = isp_register_fc4_type(isp, chan);
2949 			if (r == 0 && fcp->role == ISP_ROLE_TARGET)
2950 				isp_send_change_request(isp, chan);
2951 		}
2952 		if (r) {
2953 			isp_prt(isp, ISP_LOGWARN|ISP_LOG_SANCFG, "%s: register fc4 type failed", __func__);
2954 			return (-1);
2955 		}
2956 	}
2957 
2958 not_on_fabric:
2959 	/* Get link speed. */
2960 	fcp->isp_gbspeed = 1;
2961 	if (IS_23XX(isp) || IS_24XX(isp)) {
2962 		MBSINIT(&mbs, MBOX_GET_SET_DATA_RATE, MBLOGALL, 3000000);
2963 		mbs.param[1] = MBGSD_GET_RATE;
2964 		/* mbs.param[2] undefined if we're just getting rate */
2965 		isp_mboxcmd(isp, &mbs);
2966 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
2967 			if (mbs.param[1] == MBGSD_10GB)
2968 				fcp->isp_gbspeed = 10;
2969 			else if (mbs.param[1] == MBGSD_16GB)
2970 				fcp->isp_gbspeed = 16;
2971 			else if (mbs.param[1] == MBGSD_8GB)
2972 				fcp->isp_gbspeed = 8;
2973 			else if (mbs.param[1] == MBGSD_4GB)
2974 				fcp->isp_gbspeed = 4;
2975 			else if (mbs.param[1] == MBGSD_2GB)
2976 				fcp->isp_gbspeed = 2;
2977 			else if (mbs.param[1] == MBGSD_1GB)
2978 				fcp->isp_gbspeed = 1;
2979 		}
2980 	}
2981 
2982 	if (fcp->isp_loopstate < LOOP_TESTING_LINK) {
2983 abort:
2984 		isp_prt(isp, ISP_LOG_SANCFG,
2985 		    "Chan %d FC link test aborted", chan);
2986 		return (1);
2987 	}
2988 	fcp->isp_loopstate = LOOP_LTEST_DONE;
2989 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
2990 	    "Chan %d WWPN %016jx WWNN %016jx",
2991 	    chan, (uintmax_t)fcp->isp_wwpn, (uintmax_t)fcp->isp_wwnn);
2992 	isp_prt(isp, ISP_LOG_SANCFG|ISP_LOGCONFIG,
2993 	    "Chan %d %dGb %s PortID 0x%06x LoopID 0x%02x",
2994 	    chan, fcp->isp_gbspeed, isp_fc_toponame(fcp), fcp->isp_portid,
2995 	    fcp->isp_loopid);
2996 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC link test done", chan);
2997 	return (0);
2998 }
2999 
3000 /*
3001  * Complete the synchronization of our Port Database.
3002  *
3003  * At this point, we've scanned the local loop (if any) and the fabric
3004  * and performed fabric logins on all new devices.
3005  *
3006  * Our task here is to go through our port database removing any entities
3007  * that are still marked probational (issuing PLOGO for ones which we had
3008  * PLOGI'd into) or are dead, and notifying upper layers about new/changed
3009  * devices.
3010  */
3011 static int
3012 isp_pdb_sync(ispsoftc_t *isp, int chan)
3013 {
3014 	fcparam *fcp = FCPARAM(isp, chan);
3015 	fcportdb_t *lp;
3016 	uint16_t dbidx;
3017 
3018 	if (fcp->isp_loopstate < LOOP_FSCAN_DONE)
3019 		return (-1);
3020 	if (fcp->isp_loopstate >= LOOP_READY)
3021 		return (0);
3022 
3023 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync", chan);
3024 
3025 	fcp->isp_loopstate = LOOP_SYNCING_PDB;
3026 
3027 	for (dbidx = 0; dbidx < MAX_FC_TARG; dbidx++) {
3028 		lp = &fcp->portdb[dbidx];
3029 
3030 		if (lp->state == FC_PORTDB_STATE_NIL)
3031 			continue;
3032 		if (lp->probational && lp->state != FC_PORTDB_STATE_ZOMBIE)
3033 			lp->state = FC_PORTDB_STATE_DEAD;
3034 		switch (lp->state) {
3035 		case FC_PORTDB_STATE_DEAD:
3036 			lp->state = FC_PORTDB_STATE_NIL;
3037 			isp_async(isp, ISPASYNC_DEV_GONE, chan, lp);
3038 			if (lp->autologin == 0) {
3039 				(void) isp_plogx(isp, chan, lp->handle,
3040 				    lp->portid,
3041 				    PLOGX_FLG_CMD_LOGO |
3042 				    PLOGX_FLG_IMPLICIT |
3043 				    PLOGX_FLG_FREE_NPHDL, 0);
3044 			}
3045 			/*
3046 			 * Note that we might come out of this with our state
3047 			 * set to FC_PORTDB_STATE_ZOMBIE.
3048 			 */
3049 			break;
3050 		case FC_PORTDB_STATE_NEW:
3051 			lp->state = FC_PORTDB_STATE_VALID;
3052 			isp_async(isp, ISPASYNC_DEV_ARRIVED, chan, lp);
3053 			break;
3054 		case FC_PORTDB_STATE_CHANGED:
3055 			lp->state = FC_PORTDB_STATE_VALID;
3056 			isp_async(isp, ISPASYNC_DEV_CHANGED, chan, lp);
3057 			lp->portid = lp->new_portid;
3058 			lp->prli_word3 = lp->new_prli_word3;
3059 			break;
3060 		case FC_PORTDB_STATE_VALID:
3061 			isp_async(isp, ISPASYNC_DEV_STAYED, chan, lp);
3062 			break;
3063 		case FC_PORTDB_STATE_ZOMBIE:
3064 			break;
3065 		default:
3066 			isp_prt(isp, ISP_LOGWARN,
3067 			    "isp_pdb_sync: state %d for idx %d",
3068 			    lp->state, dbidx);
3069 			isp_dump_portdb(isp, chan);
3070 		}
3071 	}
3072 
3073 	if (fcp->isp_loopstate < LOOP_SYNCING_PDB) {
3074 		isp_prt(isp, ISP_LOG_SANCFG,
3075 		    "Chan %d FC PDB sync aborted", chan);
3076 		return (1);
3077 	}
3078 
3079 	fcp->isp_loopstate = LOOP_READY;
3080 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC PDB sync done", chan);
3081 	return (0);
3082 }
3083 
3084 static void
3085 isp_pdb_add_update(ispsoftc_t *isp, int chan, isp_pdb_t *pdb)
3086 {
3087 	fcportdb_t *lp;
3088 	uint64_t wwnn, wwpn;
3089 
3090 	MAKE_WWN_FROM_NODE_NAME(wwnn, pdb->nodename);
3091 	MAKE_WWN_FROM_NODE_NAME(wwpn, pdb->portname);
3092 
3093 	/* Search port database for the same WWPN. */
3094 	if (isp_find_pdb_by_wwpn(isp, chan, wwpn, &lp)) {
3095 		if (!lp->probational) {
3096 			isp_prt(isp, ISP_LOGERR,
3097 			    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
3098 			    chan, lp->portid, lp->handle,
3099 			    FC_PORTDB_TGT(isp, chan, lp), lp->state);
3100 			isp_dump_portdb(isp, chan);
3101 			return;
3102 		}
3103 		lp->probational = 0;
3104 		lp->node_wwn = wwnn;
3105 
3106 		/* Old device, nothing new. */
3107 		if (lp->portid == pdb->portid &&
3108 		    lp->handle == pdb->handle &&
3109 		    lp->prli_word3 == pdb->prli_word3) {
3110 			if (lp->state != FC_PORTDB_STATE_NEW)
3111 				lp->state = FC_PORTDB_STATE_VALID;
3112 			isp_prt(isp, ISP_LOG_SANCFG,
3113 			    "Chan %d Port 0x%06x@0x%04x is valid",
3114 			    chan, pdb->portid, pdb->handle);
3115 			return;
3116 		}
3117 
3118 		/* Something has changed. */
3119 		lp->state = FC_PORTDB_STATE_CHANGED;
3120 		lp->handle = pdb->handle;
3121 		lp->new_portid = pdb->portid;
3122 		lp->new_prli_word3 = pdb->prli_word3;
3123 		isp_prt(isp, ISP_LOG_SANCFG,
3124 		    "Chan %d Port 0x%06x@0x%04x is changed",
3125 		    chan, pdb->portid, pdb->handle);
3126 		return;
3127 	}
3128 
3129 	/* It seems like a new port. Find an empty slot for it. */
3130 	if (!isp_find_pdb_empty(isp, chan, &lp)) {
3131 		isp_prt(isp, ISP_LOGERR, "Chan %d out of portdb entries", chan);
3132 		return;
3133 	}
3134 
3135 	ISP_MEMZERO(lp, sizeof (fcportdb_t));
3136 	lp->autologin = 1;
3137 	lp->probational = 0;
3138 	lp->state = FC_PORTDB_STATE_NEW;
3139 	lp->portid = lp->new_portid = pdb->portid;
3140 	lp->prli_word3 = lp->new_prli_word3 = pdb->prli_word3;
3141 	lp->handle = pdb->handle;
3142 	lp->port_wwn = wwpn;
3143 	lp->node_wwn = wwnn;
3144 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Port 0x%06x@0x%04x is new",
3145 	    chan, pdb->portid, pdb->handle);
3146 }
3147 
3148 /*
3149  * Fix port IDs for logged-in initiators on pre-2400 chips.
3150  * For those chips we are not receiving login events, adding initiators
3151  * based on ATIO requests, but there is no port ID in that structure.
3152  */
3153 static void
3154 isp_fix_portids(ispsoftc_t *isp, int chan)
3155 {
3156 	fcparam *fcp = FCPARAM(isp, chan);
3157 	isp_pdb_t pdb;
3158 	uint64_t wwpn;
3159 	int i, r;
3160 
3161 	for (i = 0; i < MAX_FC_TARG; i++) {
3162 		fcportdb_t *lp = &fcp->portdb[i];
3163 
3164 		if (lp->state == FC_PORTDB_STATE_NIL ||
3165 		    lp->state == FC_PORTDB_STATE_ZOMBIE)
3166 			continue;
3167 		if (VALID_PORT(lp->portid))
3168 			continue;
3169 
3170 		r = isp_getpdb(isp, chan, lp->handle, &pdb, 1);
3171 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3172 			return;
3173 		if (r != 0) {
3174 			isp_prt(isp, ISP_LOGDEBUG1,
3175 			    "Chan %d FC Scan Loop handle %d returned %x",
3176 			    chan, lp->handle, r);
3177 			continue;
3178 		}
3179 
3180 		MAKE_WWN_FROM_NODE_NAME(wwpn, pdb.portname);
3181 		if (lp->port_wwn != wwpn)
3182 			continue;
3183 		lp->portid = lp->new_portid = pdb.portid;
3184 		isp_prt(isp, ISP_LOG_SANCFG,
3185 		    "Chan %d Port 0x%06x@0x%04x is fixed",
3186 		    chan, pdb.portid, pdb.handle);
3187 	}
3188 }
3189 
3190 /*
3191  * Scan local loop for devices.
3192  */
3193 static int
3194 isp_scan_loop(ispsoftc_t *isp, int chan)
3195 {
3196 	fcparam *fcp = FCPARAM(isp, chan);
3197 	int idx, lim, r;
3198 	isp_pdb_t pdb;
3199 	uint16_t handles[LOCAL_LOOP_LIM];
3200 	uint16_t handle;
3201 
3202 	if (fcp->isp_loopstate < LOOP_LTEST_DONE)
3203 		return (-1);
3204 	if (fcp->isp_loopstate >= LOOP_LSCAN_DONE)
3205 		return (0);
3206 
3207 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan", chan);
3208 	fcp->isp_loopstate = LOOP_SCANNING_LOOP;
3209 	if (TOPO_IS_FABRIC(fcp->isp_topo)) {
3210 		if (!IS_24XX(isp)) {
3211 			isp_fix_portids(isp, chan);
3212 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3213 				goto abort;
3214 		}
3215 		isp_prt(isp, ISP_LOG_SANCFG,
3216 		    "Chan %d FC loop scan done (no loop)", chan);
3217 		fcp->isp_loopstate = LOOP_LSCAN_DONE;
3218 		return (0);
3219 	}
3220 
3221 	lim = LOCAL_LOOP_LIM;
3222 	r = isp_gethandles(isp, chan, handles, &lim, 1, 1);
3223 	if (r != 0) {
3224 		isp_prt(isp, ISP_LOG_SANCFG,
3225 		    "Chan %d Getting list of handles failed with %x", chan, r);
3226 		isp_prt(isp, ISP_LOG_SANCFG,
3227 		    "Chan %d FC loop scan done (bad)", chan);
3228 		return (-1);
3229 	}
3230 
3231 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Got %d handles",
3232 	    chan, lim);
3233 
3234 	/*
3235 	 * Run through the list and get the port database info for each one.
3236 	 */
3237 	isp_mark_portdb(isp, chan);
3238 	for (idx = 0; idx < lim; idx++) {
3239 		handle = handles[idx];
3240 
3241 		/*
3242 		 * Don't scan "special" ids.
3243 		 */
3244 		if (ISP_CAP_2KLOGIN(isp)) {
3245 			if (handle >= NPH_RESERVED)
3246 				continue;
3247 		} else {
3248 			if (handle >= FL_ID && handle <= SNS_ID)
3249 				continue;
3250 		}
3251 
3252 		/*
3253 		 * In older cards with older f/w GET_PORT_DATABASE has been
3254 		 * known to hang. This trick gets around that problem.
3255 		 */
3256 		if (IS_2100(isp) || IS_2200(isp)) {
3257 			uint64_t node_wwn = isp_get_wwn(isp, chan, handle, 1);
3258 			if (fcp->isp_loopstate < LOOP_SCANNING_LOOP) {
3259 abort:
3260 				isp_prt(isp, ISP_LOG_SANCFG,
3261 				    "Chan %d FC loop scan aborted", chan);
3262 				return (1);
3263 			}
3264 			if (node_wwn == INI_NONE) {
3265 				continue;
3266 			}
3267 		}
3268 
3269 		/*
3270 		 * Get the port database entity for this index.
3271 		 */
3272 		r = isp_getpdb(isp, chan, handle, &pdb, 1);
3273 		if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3274 			goto abort;
3275 		if (r != 0) {
3276 			isp_prt(isp, ISP_LOGDEBUG1,
3277 			    "Chan %d FC Scan Loop handle %d returned %x",
3278 			    chan, handle, r);
3279 			continue;
3280 		}
3281 
3282 		isp_pdb_add_update(isp, chan, &pdb);
3283 	}
3284 	if (fcp->isp_loopstate < LOOP_SCANNING_LOOP)
3285 		goto abort;
3286 	fcp->isp_loopstate = LOOP_LSCAN_DONE;
3287 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC loop scan done", chan);
3288 	return (0);
3289 }
3290 
3291 /*
3292  * Scan the fabric for devices and add them to our port database.
3293  *
3294  * Use the GID_FT command to get all Port IDs for FC4 SCSI devices it knows.
3295  *
3296  * For 2100-23XX cards, we can use the SNS mailbox command to pass simple
3297  * name server commands to the switch management server via the QLogic f/w.
3298  *
3299  * For the 24XX card, we have to use CT-Pass through run via the Execute IOCB
3300  * mailbox command.
3301  *
3302  * The net result is to leave the list of Port IDs setting untranslated in
3303  * offset IGPOFF of the FC scratch area, whereupon we'll canonicalize it to
3304  * host order at OGPOFF.
3305  */
3306 
3307 /*
3308  * Take half of our scratch area to store Port IDs
3309  */
3310 #define	GIDLEN	(ISP_FC_SCRLEN >> 1)
3311 #define	NGENT	((GIDLEN - 16) >> 2)
3312 
3313 #define	IGPOFF	(0)
3314 #define	OGPOFF	(ISP_FC_SCRLEN >> 1)
3315 #define	XTXOFF	(ISP_FC_SCRLEN - (3 * QENTRY_LEN))	/* CT request */
3316 #define	CTXOFF	(ISP_FC_SCRLEN - (2 * QENTRY_LEN))	/* Request IOCB */
3317 #define	ZTXOFF	(ISP_FC_SCRLEN - (1 * QENTRY_LEN))	/* Response IOCB */
3318 
3319 static int
3320 isp_gid_ft_sns(ispsoftc_t *isp, int chan)
3321 {
3322 	union {
3323 		sns_gid_ft_req_t _x;
3324 		uint8_t _y[SNS_GID_FT_REQ_SIZE];
3325 	} un;
3326 	fcparam *fcp = FCPARAM(isp, chan);
3327 	sns_gid_ft_req_t *rq = &un._x;
3328 	uint8_t *scp = fcp->isp_scratch;
3329 	mbreg_t mbs;
3330 
3331 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d scanning fabric (GID_FT) via SNS", chan);
3332 
3333 	ISP_MEMZERO(rq, SNS_GID_FT_REQ_SIZE);
3334 	rq->snscb_rblen = GIDLEN >> 1;
3335 	rq->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + IGPOFF);
3336 	rq->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + IGPOFF);
3337 	rq->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + IGPOFF);
3338 	rq->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + IGPOFF);
3339 	rq->snscb_sblen = 6;
3340 	rq->snscb_cmd = SNS_GID_FT;
3341 	rq->snscb_mword_div_2 = NGENT;
3342 	rq->snscb_fc4_type = FC4_SCSI;
3343 
3344 	isp_put_gid_ft_request(isp, rq, (sns_gid_ft_req_t *)&scp[CTXOFF]);
3345 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_GID_FT_REQ_SIZE, chan);
3346 
3347 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 10000000);
3348 	mbs.param[0] = MBOX_SEND_SNS;
3349 	mbs.param[1] = SNS_GID_FT_REQ_SIZE >> 1;
3350 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3351 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3352 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3353 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3354 	isp_mboxcmd(isp, &mbs);
3355 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3356 		if (mbs.param[0] == MBOX_INVALID_COMMAND) {
3357 			return (1);
3358 		} else {
3359 			return (-1);
3360 		}
3361 	}
3362 	return (0);
3363 }
3364 
3365 static int
3366 isp_gid_ft_ct_passthru(ispsoftc_t *isp, int chan)
3367 {
3368 	mbreg_t mbs;
3369 	fcparam *fcp = FCPARAM(isp, chan);
3370 	union {
3371 		isp_ct_pt_t plocal;
3372 		ct_hdr_t clocal;
3373 		uint8_t q[QENTRY_LEN];
3374 	} un;
3375 	isp_ct_pt_t *pt;
3376 	ct_hdr_t *ct;
3377 	uint32_t *rp;
3378 	uint8_t *scp = fcp->isp_scratch;
3379 
3380 	isp_prt(isp, ISP_LOGDEBUG0, "Chan %d scanning fabric (GID_FT) via CT", chan);
3381 
3382 	/*
3383 	 * Build a Passthrough IOCB in memory.
3384 	 */
3385 	pt = &un.plocal;
3386 	ISP_MEMZERO(un.q, QENTRY_LEN);
3387 	pt->ctp_header.rqs_entry_count = 1;
3388 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3389 	pt->ctp_handle = 0xffffffff;
3390 	pt->ctp_nphdl = fcp->isp_sns_hdl;
3391 	pt->ctp_cmd_cnt = 1;
3392 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3393 	pt->ctp_time = 30;
3394 	pt->ctp_rsp_cnt = 1;
3395 	pt->ctp_rsp_bcnt = GIDLEN;
3396 	pt->ctp_cmd_bcnt = sizeof (*ct) + sizeof (uint32_t);
3397 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3398 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3399 	pt->ctp_dataseg[0].ds_count = sizeof (*ct) + sizeof (uint32_t);
3400 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3401 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3402 	pt->ctp_dataseg[1].ds_count = GIDLEN;
3403 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3404 		isp_print_bytes(isp, "ct IOCB", QENTRY_LEN, pt);
3405 	}
3406 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3407 
3408 	/*
3409 	 * Build the CT header and command in memory.
3410 	 *
3411 	 * Note that the CT header has to end up as Big Endian format in memory.
3412 	 */
3413 	ct = &un.clocal;
3414 	ISP_MEMZERO(ct, sizeof (*ct));
3415 	ct->ct_revision = CT_REVISION;
3416 	ct->ct_fcs_type = CT_FC_TYPE_FC;
3417 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3418 	ct->ct_cmd_resp = SNS_GID_FT;
3419 	ct->ct_bcnt_resid = (GIDLEN - 16) >> 2;
3420 
3421 	isp_put_ct_hdr(isp, ct, (ct_hdr_t *) &scp[XTXOFF]);
3422 	rp = (uint32_t *) &scp[XTXOFF+sizeof (*ct)];
3423 	ISP_IOZPUT_32(isp, FC4_SCSI, rp);
3424 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3425 		isp_print_bytes(isp, "CT HDR + payload after put",
3426 		    sizeof (*ct) + sizeof (uint32_t), &scp[XTXOFF]);
3427 	}
3428 	ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN);
3429 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 500000);
3430 	mbs.param[1] = QENTRY_LEN;
3431 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3432 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3433 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3434 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3435 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
3436 	isp_mboxcmd(isp, &mbs);
3437 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3438 		return (-1);
3439 	}
3440 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
3441 	pt = &un.plocal;
3442 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3443 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3444 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3445 	}
3446 
3447 	if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) {
3448 		isp_prt(isp, ISP_LOGWARN,
3449 		    "Chan %d ISP GID FT CT Passthrough returned 0x%x",
3450 		    chan, pt->ctp_status);
3451 		return (-1);
3452 	}
3453 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
3454 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3455 		isp_print_bytes(isp, "CT response", GIDLEN, &scp[IGPOFF]);
3456 	}
3457 	return (0);
3458 }
3459 
3460 static int
3461 isp_scan_fabric(ispsoftc_t *isp, int chan)
3462 {
3463 	fcparam *fcp = FCPARAM(isp, chan);
3464 	fcportdb_t *lp;
3465 	uint32_t portid;
3466 	uint16_t nphdl;
3467 	isp_pdb_t pdb;
3468 	int portidx, portlim, r;
3469 	sns_gid_ft_rsp_t *rs0, *rs1;
3470 
3471 	if (fcp->isp_loopstate < LOOP_LSCAN_DONE)
3472 		return (-1);
3473 	if (fcp->isp_loopstate >= LOOP_FSCAN_DONE)
3474 		return (0);
3475 
3476 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan", chan);
3477 	fcp->isp_loopstate = LOOP_SCANNING_FABRIC;
3478 	if (!TOPO_IS_FABRIC(fcp->isp_topo)) {
3479 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3480 		isp_prt(isp, ISP_LOG_SANCFG,
3481 		    "Chan %d FC fabric scan done (no fabric)", chan);
3482 		return (0);
3483 	}
3484 
3485 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3486 		isp_prt(isp, ISP_LOGERR, sacq);
3487 fail:
3488 		isp_prt(isp, ISP_LOG_SANCFG,
3489 		    "Chan %d FC fabric scan done (bad)", chan);
3490 		return (-1);
3491 	}
3492 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC) {
3493 abort:
3494 		FC_SCRATCH_RELEASE(isp, chan);
3495 		isp_prt(isp, ISP_LOG_SANCFG,
3496 		    "Chan %d FC fabric scan aborted", chan);
3497 		return (1);
3498 	}
3499 
3500 	/*
3501 	 * Make sure we still are logged into the fabric controller.
3502 	 */
3503 	nphdl = IS_24XX(isp) ? NPH_FL_ID : FL_ID;
3504 	r = isp_getpdb(isp, chan, nphdl, &pdb, 0);
3505 	if ((r & 0xffff) == MBOX_NOT_LOGGED_IN) {
3506 		isp_dump_chip_portdb(isp, chan, 0);
3507 	}
3508 	if (r) {
3509 		fcp->isp_loopstate = LOOP_LTEST_DONE;
3510 		FC_SCRATCH_RELEASE(isp, chan);
3511 		goto fail;
3512 	}
3513 
3514 	/* Get list of port IDs from SNS. */
3515 	if (IS_24XX(isp))
3516 		r = isp_gid_ft_ct_passthru(isp, chan);
3517 	else
3518 		r = isp_gid_ft_sns(isp, chan);
3519 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3520 		goto abort;
3521 	if (r > 0) {
3522 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3523 		FC_SCRATCH_RELEASE(isp, chan);
3524 		return (-1);
3525 	} else if (r < 0) {
3526 		fcp->isp_loopstate = LOOP_LTEST_DONE;	/* try again */
3527 		FC_SCRATCH_RELEASE(isp, chan);
3528 		return (-1);
3529 	}
3530 
3531 	MEMORYBARRIER(isp, SYNC_SFORCPU, IGPOFF, GIDLEN, chan);
3532 	rs0 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+IGPOFF);
3533 	rs1 = (sns_gid_ft_rsp_t *) ((uint8_t *)fcp->isp_scratch+OGPOFF);
3534 	isp_get_gid_ft_response(isp, rs0, rs1, NGENT);
3535 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3536 		goto abort;
3537 	if (rs1->snscb_cthdr.ct_cmd_resp != LS_ACC) {
3538 		int level;
3539 		if (rs1->snscb_cthdr.ct_reason == 9 && rs1->snscb_cthdr.ct_explanation == 7) {
3540 			level = ISP_LOG_SANCFG;
3541 		} else {
3542 			level = ISP_LOGWARN;
3543 		}
3544 		isp_prt(isp, level, "Chan %d Fabric Nameserver rejected GID_FT"
3545 		    " (Reason=0x%x Expl=0x%x)", chan,
3546 		    rs1->snscb_cthdr.ct_reason,
3547 		    rs1->snscb_cthdr.ct_explanation);
3548 		FC_SCRATCH_RELEASE(isp, chan);
3549 		fcp->isp_loopstate = LOOP_FSCAN_DONE;
3550 		return (-1);
3551 	}
3552 
3553 	/* Check our buffer was big enough to get the full list. */
3554 	for (portidx = 0; portidx < NGENT-1; portidx++) {
3555 		if (rs1->snscb_ports[portidx].control & 0x80)
3556 			break;
3557 	}
3558 	if ((rs1->snscb_ports[portidx].control & 0x80) == 0) {
3559 		isp_prt(isp, ISP_LOGWARN,
3560 		    "fabric too big for scratch area: increase ISP_FC_SCRLEN");
3561 	}
3562 	portlim = portidx + 1;
3563 	isp_prt(isp, ISP_LOG_SANCFG,
3564 	    "Chan %d Got %d ports back from name server", chan, portlim);
3565 
3566 	/* Go through the list and remove duplicate port ids. */
3567 	for (portidx = 0; portidx < portlim; portidx++) {
3568 		int npidx;
3569 
3570 		portid =
3571 		    ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3572 		    ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3573 		    ((rs1->snscb_ports[portidx].portid[2]));
3574 
3575 		for (npidx = portidx + 1; npidx < portlim; npidx++) {
3576 			uint32_t new_portid =
3577 			    ((rs1->snscb_ports[npidx].portid[0]) << 16) |
3578 			    ((rs1->snscb_ports[npidx].portid[1]) << 8) |
3579 			    ((rs1->snscb_ports[npidx].portid[2]));
3580 			if (new_portid == portid) {
3581 				break;
3582 			}
3583 		}
3584 
3585 		if (npidx < portlim) {
3586 			rs1->snscb_ports[npidx].portid[0] = 0;
3587 			rs1->snscb_ports[npidx].portid[1] = 0;
3588 			rs1->snscb_ports[npidx].portid[2] = 0;
3589 			isp_prt(isp, ISP_LOG_SANCFG, "Chan %d removing duplicate PortID 0x%06x entry from list", chan, portid);
3590 		}
3591 	}
3592 
3593 	/*
3594 	 * We now have a list of Port IDs for all FC4 SCSI devices
3595 	 * that the Fabric Name server knows about.
3596 	 *
3597 	 * For each entry on this list go through our port database looking
3598 	 * for probational entries- if we find one, then an old entry is
3599 	 * maybe still this one. We get some information to find out.
3600 	 *
3601 	 * Otherwise, it's a new fabric device, and we log into it
3602 	 * (unconditionally). After searching the entire database
3603 	 * again to make sure that we never ever ever ever have more
3604 	 * than one entry that has the same PortID or the same
3605 	 * WWNN/WWPN duple, we enter the device into our database.
3606 	 */
3607 	isp_mark_portdb(isp, chan);
3608 	for (portidx = 0; portidx < portlim; portidx++) {
3609 		portid = ((rs1->snscb_ports[portidx].portid[0]) << 16) |
3610 			 ((rs1->snscb_ports[portidx].portid[1]) << 8) |
3611 			 ((rs1->snscb_ports[portidx].portid[2]));
3612 		isp_prt(isp, ISP_LOG_SANCFG,
3613 		    "Chan %d Checking fabric port 0x%06x", chan, portid);
3614 		if (portid == 0) {
3615 			isp_prt(isp, ISP_LOG_SANCFG,
3616 			    "Chan %d Port at idx %d is zero",
3617 			    chan, portidx);
3618 			continue;
3619 		}
3620 		if (portid == fcp->isp_portid) {
3621 			isp_prt(isp, ISP_LOG_SANCFG,
3622 			    "Chan %d Port 0x%06x is our", chan, portid);
3623 			continue;
3624 		}
3625 
3626 		/* Now search the entire port database for the same portid. */
3627 		if (isp_find_pdb_by_portid(isp, chan, portid, &lp)) {
3628 			if (!lp->probational) {
3629 				isp_prt(isp, ISP_LOGERR,
3630 				    "Chan %d Port 0x%06x@0x%04x [%d] is not probational (0x%x)",
3631 				    chan, lp->portid, lp->handle,
3632 				    FC_PORTDB_TGT(isp, chan, lp), lp->state);
3633 				FC_SCRATCH_RELEASE(isp, chan);
3634 				isp_dump_portdb(isp, chan);
3635 				goto fail;
3636 			}
3637 
3638 			/*
3639 			 * See if we're still logged into it.
3640 			 *
3641 			 * If we aren't, mark it as a dead device and
3642 			 * leave the new portid in the database entry
3643 			 * for somebody further along to decide what to
3644 			 * do (policy choice).
3645 			 *
3646 			 * If we are, check to see if it's the same
3647 			 * device still (it should be). If for some
3648 			 * reason it isn't, mark it as a changed device
3649 			 * and leave the new portid and role in the
3650 			 * database entry for somebody further along to
3651 			 * decide what to do (policy choice).
3652 			 */
3653 			r = isp_getpdb(isp, chan, lp->handle, &pdb, 0);
3654 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3655 				goto abort;
3656 			if (r != 0) {
3657 				lp->state = FC_PORTDB_STATE_DEAD;
3658 				isp_prt(isp, ISP_LOG_SANCFG,
3659 				    "Chan %d Port 0x%06x handle 0x%x is dead (%d)",
3660 				    chan, portid, lp->handle, r);
3661 				goto relogin;
3662 			}
3663 
3664 			isp_pdb_add_update(isp, chan, &pdb);
3665 			continue;
3666 		}
3667 
3668 relogin:
3669 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
3670 			isp_prt(isp, ISP_LOG_SANCFG,
3671 			    "Chan %d Port 0x%06x is not logged in", chan, portid);
3672 			continue;
3673 		}
3674 
3675 		if (isp_login_device(isp, chan, portid, &pdb,
3676 		    &FCPARAM(isp, 0)->isp_lasthdl)) {
3677 			if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3678 				goto abort;
3679 			continue;
3680 		}
3681 
3682 		isp_pdb_add_update(isp, chan, &pdb);
3683 	}
3684 
3685 	if (fcp->isp_loopstate < LOOP_SCANNING_FABRIC)
3686 		goto abort;
3687 	FC_SCRATCH_RELEASE(isp, chan);
3688 	fcp->isp_loopstate = LOOP_FSCAN_DONE;
3689 	isp_prt(isp, ISP_LOG_SANCFG, "Chan %d FC fabric scan done", chan);
3690 	return (0);
3691 }
3692 
3693 /*
3694  * Find an unused handle and try and use to login to a port.
3695  */
3696 static int
3697 isp_login_device(ispsoftc_t *isp, int chan, uint32_t portid, isp_pdb_t *p, uint16_t *ohp)
3698 {
3699 	int lim, i, r;
3700 	uint16_t handle;
3701 
3702 	if (ISP_CAP_2KLOGIN(isp)) {
3703 		lim = NPH_MAX_2K;
3704 	} else {
3705 		lim = NPH_MAX;
3706 	}
3707 
3708 	handle = isp_next_handle(isp, ohp);
3709 	for (i = 0; i < lim; i++) {
3710 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3711 			return (-1);
3712 
3713 		/* Check if this handle is free. */
3714 		r = isp_getpdb(isp, chan, handle, p, 0);
3715 		if (r == 0) {
3716 			if (p->portid != portid) {
3717 				/* This handle is busy, try next one. */
3718 				handle = isp_next_handle(isp, ohp);
3719 				continue;
3720 			}
3721 			break;
3722 		}
3723 		if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3724 			return (-1);
3725 
3726 		/*
3727 		 * Now try and log into the device
3728 		 */
3729 		r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3730 		if (r == 0) {
3731 			break;
3732 		} else if ((r & 0xffff) == MBOX_PORT_ID_USED) {
3733 			/*
3734 			 * If we get here, then the firmwware still thinks we're logged into this device, but with a different
3735 			 * handle. We need to break that association. We used to try and just substitute the handle, but then
3736 			 * failed to get any data via isp_getpdb (below).
3737 			 */
3738 			if (isp_plogx(isp, chan, r >> 16, portid, PLOGX_FLG_CMD_LOGO | PLOGX_FLG_IMPLICIT | PLOGX_FLG_FREE_NPHDL, 1)) {
3739 				isp_prt(isp, ISP_LOGERR, "baw... logout of %x failed", r >> 16);
3740 			}
3741 			if (FCPARAM(isp, chan)->isp_loopstate != LOOP_SCANNING_FABRIC)
3742 				return (-1);
3743 			r = isp_plogx(isp, chan, handle, portid, PLOGX_FLG_CMD_PLOGI, 1);
3744 			if (r != 0)
3745 				i = lim;
3746 			break;
3747 		} else if ((r & 0xffff) == MBOX_LOOP_ID_USED) {
3748 			/* Try the next handle. */
3749 			handle = isp_next_handle(isp, ohp);
3750 		} else {
3751 			/* Give up. */
3752 			i = lim;
3753 			break;
3754 		}
3755 	}
3756 
3757 	if (i == lim) {
3758 		isp_prt(isp, ISP_LOGWARN, "Chan %d PLOGI 0x%06x failed", chan, portid);
3759 		return (-1);
3760 	}
3761 
3762 	/*
3763 	 * If we successfully logged into it, get the PDB for it
3764 	 * so we can crosscheck that it is still what we think it
3765 	 * is and that we also have the role it plays
3766 	 */
3767 	r = isp_getpdb(isp, chan, handle, p, 0);
3768 	if (r != 0) {
3769 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x disappeared", chan, portid, handle);
3770 		return (-1);
3771 	}
3772 
3773 	if (p->handle != handle || p->portid != portid) {
3774 		isp_prt(isp, ISP_LOGERR, "Chan %d new device 0x%06x@0x%x changed (0x%06x@0x%0x)",
3775 		    chan, portid, handle, p->portid, p->handle);
3776 		return (-1);
3777 	}
3778 	return (0);
3779 }
3780 
3781 static int
3782 isp_send_change_request(ispsoftc_t *isp, int chan)
3783 {
3784 	mbreg_t mbs;
3785 
3786 	MBSINIT(&mbs, MBOX_SEND_CHANGE_REQUEST, MBLOGALL, 500000);
3787 	mbs.param[1] = 0x03;
3788 	mbs.param[9] = chan;
3789 	isp_mboxcmd(isp, &mbs);
3790 	return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : -1);
3791 }
3792 
3793 static int
3794 isp_register_fc4_type(ispsoftc_t *isp, int chan)
3795 {
3796 	fcparam *fcp = FCPARAM(isp, chan);
3797 	uint8_t local[SNS_RFT_ID_REQ_SIZE];
3798 	sns_screq_t *reqp = (sns_screq_t *) local;
3799 	mbreg_t mbs;
3800 
3801 	ISP_MEMZERO((void *) reqp, SNS_RFT_ID_REQ_SIZE);
3802 	reqp->snscb_rblen = SNS_RFT_ID_RESP_SIZE >> 1;
3803 	reqp->snscb_addr[RQRSP_ADDR0015] = DMA_WD0(fcp->isp_scdma + 0x100);
3804 	reqp->snscb_addr[RQRSP_ADDR1631] = DMA_WD1(fcp->isp_scdma + 0x100);
3805 	reqp->snscb_addr[RQRSP_ADDR3247] = DMA_WD2(fcp->isp_scdma + 0x100);
3806 	reqp->snscb_addr[RQRSP_ADDR4863] = DMA_WD3(fcp->isp_scdma + 0x100);
3807 	reqp->snscb_sblen = 22;
3808 	reqp->snscb_data[0] = SNS_RFT_ID;
3809 	reqp->snscb_data[4] = fcp->isp_portid & 0xffff;
3810 	reqp->snscb_data[5] = (fcp->isp_portid >> 16) & 0xff;
3811 	reqp->snscb_data[6] = (1 << FC4_SCSI);
3812 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3813 		isp_prt(isp, ISP_LOGERR, sacq);
3814 		return (-1);
3815 	}
3816 	isp_put_sns_request(isp, reqp, (sns_screq_t *) fcp->isp_scratch);
3817 	MBSINIT(&mbs, MBOX_SEND_SNS, MBLOGALL, 1000000);
3818 	mbs.param[1] = SNS_RFT_ID_REQ_SIZE >> 1;
3819 	mbs.param[2] = DMA_WD1(fcp->isp_scdma);
3820 	mbs.param[3] = DMA_WD0(fcp->isp_scdma);
3821 	mbs.param[6] = DMA_WD3(fcp->isp_scdma);
3822 	mbs.param[7] = DMA_WD2(fcp->isp_scdma);
3823 	MEMORYBARRIER(isp, SYNC_SFORDEV, 0, SNS_RFT_ID_REQ_SIZE, chan);
3824 	isp_mboxcmd(isp, &mbs);
3825 	FC_SCRATCH_RELEASE(isp, chan);
3826 	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
3827 		return (0);
3828 	} else {
3829 		return (-1);
3830 	}
3831 }
3832 
3833 static int
3834 isp_register_fc4_type_24xx(ispsoftc_t *isp, int chan)
3835 {
3836 	mbreg_t mbs;
3837 	fcparam *fcp = FCPARAM(isp, chan);
3838 	union {
3839 		isp_ct_pt_t plocal;
3840 		rft_id_t clocal;
3841 		uint8_t q[QENTRY_LEN];
3842 	} un;
3843 	isp_ct_pt_t *pt;
3844 	ct_hdr_t *ct;
3845 	rft_id_t *rp;
3846 	uint8_t *scp = fcp->isp_scratch;
3847 
3848 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3849 		isp_prt(isp, ISP_LOGERR, sacq);
3850 		return (-1);
3851 	}
3852 
3853 	/*
3854 	 * Build a Passthrough IOCB in memory.
3855 	 */
3856 	ISP_MEMZERO(un.q, QENTRY_LEN);
3857 	pt = &un.plocal;
3858 	pt->ctp_header.rqs_entry_count = 1;
3859 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3860 	pt->ctp_handle = 0xffffffff;
3861 	pt->ctp_nphdl = fcp->isp_sns_hdl;
3862 	pt->ctp_cmd_cnt = 1;
3863 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3864 	pt->ctp_time = 1;
3865 	pt->ctp_rsp_cnt = 1;
3866 	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
3867 	pt->ctp_cmd_bcnt = sizeof (rft_id_t);
3868 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3869 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3870 	pt->ctp_dataseg[0].ds_count = sizeof (rft_id_t);
3871 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3872 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3873 	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
3874 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3875 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3876 		isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
3877 	}
3878 
3879 	/*
3880 	 * Build the CT header and command in memory.
3881 	 *
3882 	 * Note that the CT header has to end up as Big Endian format in memory.
3883 	 */
3884 	ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
3885 	ct = &un.clocal.rftid_hdr;
3886 	ct->ct_revision = CT_REVISION;
3887 	ct->ct_fcs_type = CT_FC_TYPE_FC;
3888 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
3889 	ct->ct_cmd_resp = SNS_RFT_ID;
3890 	ct->ct_bcnt_resid = (sizeof (rft_id_t) - sizeof (ct_hdr_t)) >> 2;
3891 	rp = &un.clocal;
3892 	rp->rftid_portid[0] = fcp->isp_portid >> 16;
3893 	rp->rftid_portid[1] = fcp->isp_portid >> 8;
3894 	rp->rftid_portid[2] = fcp->isp_portid;
3895 	rp->rftid_fc4types[FC4_SCSI >> 5] = 1 << (FC4_SCSI & 0x1f);
3896 	isp_put_rft_id(isp, rp, (rft_id_t *) &scp[XTXOFF]);
3897 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3898 		isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
3899 	}
3900 
3901 	ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
3902 
3903 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
3904 	mbs.param[1] = QENTRY_LEN;
3905 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
3906 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
3907 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
3908 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
3909 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
3910 	isp_mboxcmd(isp, &mbs);
3911 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3912 		FC_SCRATCH_RELEASE(isp, chan);
3913 		return (-1);
3914 	}
3915 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
3916 	pt = &un.plocal;
3917 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
3918 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3919 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
3920 	}
3921 	if (pt->ctp_status) {
3922 		FC_SCRATCH_RELEASE(isp, chan);
3923 		isp_prt(isp, ISP_LOGWARN,
3924 		    "Chan %d Register FC4 Type CT Passthrough returned 0x%x",
3925 		    chan, pt->ctp_status);
3926 		return (1);
3927 	}
3928 
3929 	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
3930 	FC_SCRATCH_RELEASE(isp, chan);
3931 
3932 	if (ct->ct_cmd_resp == LS_RJT) {
3933 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1, "Chan %d Register FC4 Type rejected", chan);
3934 		return (-1);
3935 	} else if (ct->ct_cmd_resp == LS_ACC) {
3936 		isp_prt(isp, ISP_LOG_SANCFG, "Chan %d Register FC4 Type accepted", chan);
3937 		return (0);
3938 	} else {
3939 		isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", chan, ct->ct_cmd_resp);
3940 		return (-1);
3941 	}
3942 }
3943 
3944 static int
3945 isp_register_fc4_features_24xx(ispsoftc_t *isp, int chan)
3946 {
3947 	mbreg_t mbs;
3948 	fcparam *fcp = FCPARAM(isp, chan);
3949 	union {
3950 		isp_ct_pt_t plocal;
3951 		rff_id_t clocal;
3952 		uint8_t q[QENTRY_LEN];
3953 	} un;
3954 	isp_ct_pt_t *pt;
3955 	ct_hdr_t *ct;
3956 	rff_id_t *rp;
3957 	uint8_t *scp = fcp->isp_scratch;
3958 
3959 	if (FC_SCRATCH_ACQUIRE(isp, chan)) {
3960 		isp_prt(isp, ISP_LOGERR, sacq);
3961 		return (-1);
3962 	}
3963 
3964 	/*
3965 	 * Build a Passthrough IOCB in memory.
3966 	 */
3967 	ISP_MEMZERO(un.q, QENTRY_LEN);
3968 	pt = &un.plocal;
3969 	pt->ctp_header.rqs_entry_count = 1;
3970 	pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU;
3971 	pt->ctp_handle = 0xffffffff;
3972 	pt->ctp_nphdl = fcp->isp_sns_hdl;
3973 	pt->ctp_cmd_cnt = 1;
3974 	pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan);
3975 	pt->ctp_time = 1;
3976 	pt->ctp_rsp_cnt = 1;
3977 	pt->ctp_rsp_bcnt = sizeof (ct_hdr_t);
3978 	pt->ctp_cmd_bcnt = sizeof (rff_id_t);
3979 	pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF);
3980 	pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF);
3981 	pt->ctp_dataseg[0].ds_count = sizeof (rff_id_t);
3982 	pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma+IGPOFF);
3983 	pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma+IGPOFF);
3984 	pt->ctp_dataseg[1].ds_count = sizeof (ct_hdr_t);
3985 	isp_put_ct_pt(isp, pt, (isp_ct_pt_t *) &scp[CTXOFF]);
3986 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
3987 		isp_print_bytes(isp, "IOCB CT Request", QENTRY_LEN, pt);
3988 	}
3989 
3990 	/*
3991 	 * Build the CT header and command in memory.
3992 	 *
3993 	 * Note that the CT header has to end up as Big Endian format in memory.
3994 	 */
3995 	ISP_MEMZERO(&un.clocal, sizeof (un.clocal));
3996 	ct = &un.clocal.rffid_hdr;
3997 	ct->ct_revision = CT_REVISION;
3998 	ct->ct_fcs_type = CT_FC_TYPE_FC;
3999 	ct->ct_fcs_subtype = CT_FC_SUBTYPE_NS;
4000 	ct->ct_cmd_resp = SNS_RFF_ID;
4001 	ct->ct_bcnt_resid = (sizeof (rff_id_t) - sizeof (ct_hdr_t)) >> 2;
4002 	rp = &un.clocal;
4003 	rp->rffid_portid[0] = fcp->isp_portid >> 16;
4004 	rp->rffid_portid[1] = fcp->isp_portid >> 8;
4005 	rp->rffid_portid[2] = fcp->isp_portid;
4006 	rp->rffid_fc4features = 0;
4007 	if (fcp->role & ISP_ROLE_TARGET)
4008 		rp->rffid_fc4features |= 1;
4009 	if (fcp->role & ISP_ROLE_INITIATOR)
4010 		rp->rffid_fc4features |= 2;
4011 	rp->rffid_fc4type = FC4_SCSI;
4012 	isp_put_rff_id(isp, rp, (rff_id_t *) &scp[XTXOFF]);
4013 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4014 		isp_print_bytes(isp, "CT Header", QENTRY_LEN, &scp[XTXOFF]);
4015 	}
4016 
4017 	ISP_MEMZERO(&scp[ZTXOFF], sizeof (ct_hdr_t));
4018 
4019 	MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 1000000);
4020 	mbs.param[1] = QENTRY_LEN;
4021 	mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF);
4022 	mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF);
4023 	mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF);
4024 	mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF);
4025 	MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan);
4026 	isp_mboxcmd(isp, &mbs);
4027 	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4028 		FC_SCRATCH_RELEASE(isp, chan);
4029 		return (-1);
4030 	}
4031 	MEMORYBARRIER(isp, SYNC_SFORCPU, ZTXOFF, QENTRY_LEN, chan);
4032 	pt = &un.plocal;
4033 	isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt);
4034 	if (isp->isp_dblev & ISP_LOGDEBUG1) {
4035 		isp_print_bytes(isp, "IOCB response", QENTRY_LEN, pt);
4036 	}
4037 	if (pt->ctp_status) {
4038 		FC_SCRATCH_RELEASE(isp, chan);
4039 		isp_prt(isp, ISP_LOGWARN,
4040 		    "Chan %d Register FC4 Features CT Passthrough returned 0x%x",
4041 		    chan, pt->ctp_status);
4042 		return (1);
4043 	}
4044 
4045 	isp_get_ct_hdr(isp, (ct_hdr_t *) &scp[IGPOFF], ct);
4046 	FC_SCRATCH_RELEASE(isp, chan);
4047 
4048 	if (ct->ct_cmd_resp == LS_RJT) {
4049 		isp_prt(isp, ISP_LOG_SANCFG|ISP_LOG_WARN1,
4050 		    "Chan %d Register FC4 Features rejected", chan);
4051 		return (-1);
4052 	} else if (ct->ct_cmd_resp == LS_ACC) {
4053 		isp_prt(isp, ISP_LOG_SANCFG,
4054 		    "Chan %d Register FC4 Features accepted", chan);
4055 		return (0);
4056 	} else {
4057 		isp_prt(isp, ISP_LOGWARN,
4058 		    "Chan %d Register FC4 Features: 0x%x", chan, ct->ct_cmd_resp);
4059 		return (-1);
4060 	}
4061 }
4062 
4063 static uint16_t
4064 isp_next_handle(ispsoftc_t *isp, uint16_t *ohp)
4065 {
4066 	fcparam *fcp;
4067 	int i, chan, wrap;
4068 	uint16_t handle, minh, maxh;
4069 
4070 	handle = *ohp;
4071 	if (ISP_CAP_2KLOGIN(isp)) {
4072 		minh = 0;
4073 		maxh = NPH_RESERVED - 1;
4074 	} else {
4075 		minh = SNS_ID + 1;
4076 		maxh = NPH_MAX - 1;
4077 	}
4078 	wrap = 0;
4079 
4080 next:
4081 	if (handle == NIL_HANDLE) {
4082 		handle = minh;
4083 	} else {
4084 		handle++;
4085 		if (handle > maxh) {
4086 			if (++wrap >= 2) {
4087 				isp_prt(isp, ISP_LOGERR, "Out of port handles!");
4088 				return (NIL_HANDLE);
4089 			}
4090 			handle = minh;
4091 		}
4092 	}
4093 	for (chan = 0; chan < isp->isp_nchan; chan++) {
4094 		fcp = FCPARAM(isp, chan);
4095 		if (fcp->role == ISP_ROLE_NONE)
4096 			continue;
4097 		for (i = 0; i < MAX_FC_TARG; i++) {
4098 			if (fcp->portdb[i].state != FC_PORTDB_STATE_NIL &&
4099 			    fcp->portdb[i].handle == handle)
4100 				goto next;
4101 		}
4102 	}
4103 	*ohp = handle;
4104 	return (handle);
4105 }
4106 
4107 /*
4108  * Start a command. Locking is assumed done in the caller.
4109  */
4110 
4111 int
4112 isp_start(XS_T *xs)
4113 {
4114 	ispsoftc_t *isp;
4115 	uint32_t handle, cdblen;
4116 	uint8_t local[QENTRY_LEN];
4117 	ispreq_t *reqp;
4118 	void *cdbp, *qep;
4119 	uint16_t *tptr;
4120 	fcportdb_t *lp;
4121 	int target, dmaresult;
4122 
4123 	XS_INITERR(xs);
4124 	isp = XS_ISP(xs);
4125 
4126 	/*
4127 	 * Check command CDB length, etc.. We really are limited to 16 bytes
4128 	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
4129 	 * but probably only if we're running fairly new firmware (we'll
4130 	 * let the old f/w choke on an extended command queue entry).
4131 	 */
4132 
4133 	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
4134 		isp_prt(isp, ISP_LOGERR, "unsupported cdb length (%d, CDB[0]=0x%x)", XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
4135 		XS_SETERR(xs, HBA_BOTCH);
4136 		return (CMD_COMPLETE);
4137 	}
4138 
4139 	/*
4140 	 * Translate the target to device handle as appropriate, checking
4141 	 * for correct device state as well.
4142 	 */
4143 	target = XS_TGT(xs);
4144 	if (IS_FC(isp)) {
4145 		fcparam *fcp = FCPARAM(isp, XS_CHANNEL(xs));
4146 
4147 		if ((fcp->role & ISP_ROLE_INITIATOR) == 0) {
4148 			isp_prt(isp, ISP_LOG_WARN1,
4149 			    "%d.%d.%jx I am not an initiator",
4150 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4151 			XS_SETERR(xs, HBA_SELTIMEOUT);
4152 			return (CMD_COMPLETE);
4153 		}
4154 
4155 		if (isp->isp_state != ISP_RUNSTATE) {
4156 			isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4157 			XS_SETERR(xs, HBA_BOTCH);
4158 			return (CMD_COMPLETE);
4159 		}
4160 
4161 		/*
4162 		 * Try again later.
4163 		 */
4164 		if (fcp->isp_loopstate != LOOP_READY) {
4165 			return (CMD_RQLATER);
4166 		}
4167 
4168 		isp_prt(isp, ISP_LOGDEBUG2, "XS_TGT(xs)=%d", target);
4169 		lp = &fcp->portdb[target];
4170 		if (target < 0 || target >= MAX_FC_TARG ||
4171 		    lp->is_target == 0) {
4172 			XS_SETERR(xs, HBA_SELTIMEOUT);
4173 			return (CMD_COMPLETE);
4174 		}
4175 		if (lp->state == FC_PORTDB_STATE_ZOMBIE) {
4176 			isp_prt(isp, ISP_LOGDEBUG1,
4177 			    "%d.%d.%jx target zombie",
4178 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4179 			return (CMD_RQLATER);
4180 		}
4181 		if (lp->state != FC_PORTDB_STATE_VALID) {
4182 			isp_prt(isp, ISP_LOGDEBUG1,
4183 			    "%d.%d.%jx bad db port state 0x%x",
4184 			    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs), lp->state);
4185 			XS_SETERR(xs, HBA_SELTIMEOUT);
4186 			return (CMD_COMPLETE);
4187 		}
4188 	} else {
4189 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4190 		if (isp->isp_state != ISP_RUNSTATE) {
4191 			isp_prt(isp, ISP_LOGERR, "Adapter not at RUNSTATE");
4192 			XS_SETERR(xs, HBA_BOTCH);
4193 			return (CMD_COMPLETE);
4194 		}
4195 
4196 		if (sdp->update) {
4197 			isp_spi_update(isp, XS_CHANNEL(xs));
4198 		}
4199 		lp = NULL;
4200 	}
4201 
4202  start_again:
4203 
4204 	qep = isp_getrqentry(isp);
4205 	if (qep == NULL) {
4206 		isp_prt(isp, ISP_LOG_WARN1, "Request Queue Overflow");
4207 		XS_SETERR(xs, HBA_BOTCH);
4208 		return (CMD_EAGAIN);
4209 	}
4210 	XS_SETERR(xs, HBA_NOERROR);
4211 
4212 	/*
4213 	 * Now see if we need to synchronize the ISP with respect to anything.
4214 	 * We do dual duty here (cough) for synchronizing for busses other
4215 	 * than which we got here to send a command to.
4216 	 */
4217 	reqp = (ispreq_t *) local;
4218 	ISP_MEMZERO(local, QENTRY_LEN);
4219 	if (ISP_TST_SENDMARKER(isp, XS_CHANNEL(xs))) {
4220 		if (IS_24XX(isp)) {
4221 			isp_marker_24xx_t *m = (isp_marker_24xx_t *) reqp;
4222 			m->mrk_header.rqs_entry_count = 1;
4223 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4224 			m->mrk_modifier = SYNC_ALL;
4225 			m->mrk_vphdl = XS_CHANNEL(xs);
4226 			isp_put_marker_24xx(isp, m, qep);
4227 		} else {
4228 			isp_marker_t *m = (isp_marker_t *) reqp;
4229 			m->mrk_header.rqs_entry_count = 1;
4230 			m->mrk_header.rqs_entry_type = RQSTYPE_MARKER;
4231 			m->mrk_target = (XS_CHANNEL(xs) << 7);	/* bus # */
4232 			m->mrk_modifier = SYNC_ALL;
4233 			isp_put_marker(isp, m, qep);
4234 		}
4235 		ISP_SYNC_REQUEST(isp);
4236 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 0);
4237 		goto start_again;
4238 	}
4239 
4240 	reqp->req_header.rqs_entry_count = 1;
4241 
4242 	/*
4243 	 * Select and install Header Code.
4244 	 * Note that it might be overridden before going out
4245 	 * if we're on a 64 bit platform. The lower level
4246 	 * code (isp_send_cmd) will select the appropriate
4247 	 * 64 bit variant if it needs to.
4248 	 */
4249 	if (IS_24XX(isp)) {
4250 		reqp->req_header.rqs_entry_type = RQSTYPE_T7RQS;
4251 	} else if (IS_FC(isp)) {
4252 		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
4253 	} else {
4254 		if (XS_CDBLEN(xs) > 12) {
4255 			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
4256 		} else {
4257 			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
4258 		}
4259 	}
4260 
4261 	/*
4262 	 * Set task attributes
4263 	 */
4264 	if (IS_24XX(isp)) {
4265 		int ttype;
4266 		if (XS_TAG_P(xs)) {
4267 			ttype = XS_TAG_TYPE(xs);
4268 		} else {
4269 			if (XS_CDBP(xs)[0] == 0x3) {
4270 				ttype = REQFLAG_HTAG;
4271 			} else {
4272 				ttype = REQFLAG_STAG;
4273 			}
4274 		}
4275 		if (ttype == REQFLAG_OTAG) {
4276 			ttype = FCP_CMND_TASK_ATTR_ORDERED;
4277 		} else if (ttype == REQFLAG_HTAG) {
4278 			ttype = FCP_CMND_TASK_ATTR_HEAD;
4279 		} else {
4280 			ttype = FCP_CMND_TASK_ATTR_SIMPLE;
4281 		}
4282 		((ispreqt7_t *)reqp)->req_task_attribute = ttype;
4283 	} else if (IS_FC(isp)) {
4284 		/*
4285 		 * See comment in isp_intr
4286 		 */
4287 		/* XS_SET_RESID(xs, 0); */
4288 
4289 		/*
4290 		 * Fibre Channel always requires some kind of tag.
4291 		 * The Qlogic drivers seem be happy not to use a tag,
4292 		 * but this breaks for some devices (IBM drives).
4293 		 */
4294 		if (XS_TAG_P(xs)) {
4295 			((ispreqt2_t *)reqp)->req_flags = XS_TAG_TYPE(xs);
4296 		} else {
4297 			/*
4298 			 * If we don't know what tag to use, use HEAD OF QUEUE
4299 			 * for Request Sense or Simple.
4300 			 */
4301 			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
4302 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_HTAG;
4303 			else
4304 				((ispreqt2_t *)reqp)->req_flags = REQFLAG_STAG;
4305 		}
4306 	} else {
4307 		sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
4308 		if ((sdp->isp_devparam[target].actv_flags & DPARM_TQING) && XS_TAG_P(xs)) {
4309 			reqp->req_flags = XS_TAG_TYPE(xs);
4310 		}
4311 	}
4312 
4313 	tptr = &reqp->req_time;
4314 
4315 	/*
4316 	 * NB: we do not support long CDBs (yet)
4317 	 */
4318 	cdblen = XS_CDBLEN(xs);
4319 
4320 	if (IS_SCSI(isp)) {
4321 		if (cdblen > sizeof (reqp->req_cdb)) {
4322 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4323 			XS_SETERR(xs, HBA_BOTCH);
4324 			return (CMD_COMPLETE);
4325 		}
4326 		reqp->req_target = target | (XS_CHANNEL(xs) << 7);
4327 		reqp->req_lun_trn = XS_LUN(xs);
4328 		cdbp = reqp->req_cdb;
4329 		reqp->req_cdblen = cdblen;
4330 	} else if (IS_24XX(isp)) {
4331 		ispreqt7_t *t7 = (ispreqt7_t *)local;
4332 
4333 		if (cdblen > sizeof (t7->req_cdb)) {
4334 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4335 			XS_SETERR(xs, HBA_BOTCH);
4336 			return (CMD_COMPLETE);
4337 		}
4338 
4339 		t7->req_nphdl = lp->handle;
4340 		t7->req_tidlo = lp->portid;
4341 		t7->req_tidhi = lp->portid >> 16;
4342 		t7->req_vpidx = ISP_GET_VPIDX(isp, XS_CHANNEL(xs));
4343 #if __FreeBSD_version >= 1000700
4344 		be64enc(t7->req_lun, CAM_EXTLUN_BYTE_SWIZZLE(XS_LUN(xs)));
4345 #else
4346 		if (XS_LUN(xs) >= 256) {
4347 			t7->req_lun[0] = XS_LUN(xs) >> 8;
4348 			t7->req_lun[0] |= 0x40;
4349 		}
4350 		t7->req_lun[1] = XS_LUN(xs);
4351 #endif
4352 		if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
4353 			if (FCP_NEXT_CRN(isp, &t7->req_crn, xs)) {
4354 				isp_prt(isp, ISP_LOG_WARN1,
4355 				    "%d.%d.%jx cannot generate next CRN",
4356 				    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4357 				XS_SETERR(xs, HBA_BOTCH);
4358 				return (CMD_EAGAIN);
4359 			}
4360 		}
4361 		tptr = &t7->req_time;
4362 		cdbp = t7->req_cdb;
4363 	} else {
4364 		ispreqt2_t *t2 = (ispreqt2_t *)local;
4365 
4366 		if (cdblen > sizeof t2->req_cdb) {
4367 			isp_prt(isp, ISP_LOGERR, "Command Length %u too long for this chip", cdblen);
4368 			XS_SETERR(xs, HBA_BOTCH);
4369 			return (CMD_COMPLETE);
4370 		}
4371 		if (FCPARAM(isp, XS_CHANNEL(xs))->fctape_enabled && (lp->prli_word3 & PRLI_WD3_RETRY)) {
4372 			if (FCP_NEXT_CRN(isp, &t2->req_crn, xs)) {
4373 				isp_prt(isp, ISP_LOG_WARN1,
4374 				    "%d.%d.%jx cannot generate next CRN",
4375 				    XS_CHANNEL(xs), target, (uintmax_t)XS_LUN(xs));
4376 				XS_SETERR(xs, HBA_BOTCH);
4377 				return (CMD_EAGAIN);
4378 			}
4379 		}
4380 		if (ISP_CAP_2KLOGIN(isp)) {
4381 			ispreqt2e_t *t2e = (ispreqt2e_t *)local;
4382 			t2e->req_target = lp->handle;
4383 			t2e->req_scclun = XS_LUN(xs);
4384 #if __FreeBSD_version < 1000700
4385 			if (XS_LUN(xs) >= 256)
4386 				t2e->req_scclun |= 0x4000;
4387 #endif
4388 			cdbp = t2e->req_cdb;
4389 		} else if (ISP_CAP_SCCFW(isp)) {
4390 			ispreqt2_t *t2 = (ispreqt2_t *)local;
4391 			t2->req_target = lp->handle;
4392 			t2->req_scclun = XS_LUN(xs);
4393 #if __FreeBSD_version < 1000700
4394 			if (XS_LUN(xs) >= 256)
4395 				t2->req_scclun |= 0x4000;
4396 #endif
4397 			cdbp = t2->req_cdb;
4398 		} else {
4399 			t2->req_target = lp->handle;
4400 			t2->req_lun_trn = XS_LUN(xs);
4401 			cdbp = t2->req_cdb;
4402 		}
4403 	}
4404 	ISP_MEMCPY(cdbp, XS_CDBP(xs), cdblen);
4405 
4406 	*tptr = XS_TIME(xs) / 1000;
4407 	if (*tptr == 0 && XS_TIME(xs)) {
4408 		*tptr = 1;
4409 	}
4410 	if (IS_24XX(isp) && *tptr > 0x1999) {
4411 		*tptr = 0x1999;
4412 	}
4413 
4414 	if (isp_allocate_xs(isp, xs, &handle)) {
4415 		isp_prt(isp, ISP_LOG_WARN1, "out of xflist pointers");
4416 		XS_SETERR(xs, HBA_BOTCH);
4417 		return (CMD_EAGAIN);
4418 	}
4419 	/* Whew. Thankfully the same for type 7 requests */
4420 	reqp->req_handle = handle;
4421 
4422 	/*
4423 	 * Set up DMA and/or do any platform dependent swizzling of the request entry
4424 	 * so that the Qlogic F/W understands what is being asked of it.
4425 	 *
4426 	 * The callee is responsible for adding all requests at this point.
4427 	 */
4428 	dmaresult = ISP_DMASETUP(isp, xs, reqp);
4429 	if (dmaresult != CMD_QUEUED) {
4430 		isp_destroy_handle(isp, handle);
4431 		/*
4432 		 * dmasetup sets actual error in packet, and
4433 		 * return what we were given to return.
4434 		 */
4435 		return (dmaresult);
4436 	}
4437 	isp_xs_prt(isp, xs, ISP_LOGDEBUG0, "START cmd cdb[0]=0x%x datalen %ld", XS_CDBP(xs)[0], (long) XS_XFRLEN(xs));
4438 	isp->isp_nactive++;
4439 	return (CMD_QUEUED);
4440 }
4441 
4442 /*
4443  * isp control
4444  * Locks (ints blocked) assumed held.
4445  */
4446 
4447 int
4448 isp_control(ispsoftc_t *isp, ispctl_t ctl, ...)
4449 {
4450 	XS_T *xs;
4451 	mbreg_t *mbr, mbs;
4452 	int chan, tgt;
4453 	uint32_t handle;
4454 	va_list ap;
4455 
4456 	switch (ctl) {
4457 	case ISPCTL_RESET_BUS:
4458 		/*
4459 		 * Issue a bus reset.
4460 		 */
4461 		if (IS_24XX(isp)) {
4462 			isp_prt(isp, ISP_LOGERR, "BUS RESET NOT IMPLEMENTED");
4463 			break;
4464 		} else if (IS_FC(isp)) {
4465 			mbs.param[1] = 10;
4466 			chan = 0;
4467 		} else {
4468 			va_start(ap, ctl);
4469 			chan = va_arg(ap, int);
4470 			va_end(ap);
4471 			mbs.param[1] = SDPARAM(isp, chan)->isp_bus_reset_delay;
4472 			if (mbs.param[1] < 2) {
4473 				mbs.param[1] = 2;
4474 			}
4475 			mbs.param[2] = chan;
4476 		}
4477 		MBSINIT(&mbs, MBOX_BUS_RESET, MBLOGALL, 0);
4478 		ISP_SET_SENDMARKER(isp, chan, 1);
4479 		isp_mboxcmd(isp, &mbs);
4480 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4481 			break;
4482 		}
4483 		isp_prt(isp, ISP_LOGINFO, "driver initiated bus reset of bus %d", chan);
4484 		return (0);
4485 
4486 	case ISPCTL_RESET_DEV:
4487 		va_start(ap, ctl);
4488 		chan = va_arg(ap, int);
4489 		tgt = va_arg(ap, int);
4490 		va_end(ap);
4491 		if (IS_24XX(isp)) {
4492 			uint8_t local[QENTRY_LEN];
4493 			isp24xx_tmf_t *tmf;
4494 			isp24xx_statusreq_t *sp;
4495 			fcparam *fcp = FCPARAM(isp, chan);
4496 			fcportdb_t *lp;
4497 
4498 			if (tgt < 0 || tgt >= MAX_FC_TARG) {
4499 				isp_prt(isp, ISP_LOGWARN, "Chan %d trying to reset bad target %d", chan, tgt);
4500 				break;
4501 			}
4502 			lp = &fcp->portdb[tgt];
4503 			if (lp->is_target == 0 ||
4504 			    lp->state != FC_PORTDB_STATE_VALID) {
4505 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
4506 				break;
4507 			}
4508 
4509 			tmf = (isp24xx_tmf_t *) local;
4510 			ISP_MEMZERO(tmf, QENTRY_LEN);
4511 			tmf->tmf_header.rqs_entry_type = RQSTYPE_TSK_MGMT;
4512 			tmf->tmf_header.rqs_entry_count = 1;
4513 			tmf->tmf_nphdl = lp->handle;
4514 			tmf->tmf_delay = 2;
4515 			tmf->tmf_timeout = 2;
4516 			tmf->tmf_flags = ISP24XX_TMF_TARGET_RESET;
4517 			tmf->tmf_tidlo = lp->portid;
4518 			tmf->tmf_tidhi = lp->portid >> 16;
4519 			tmf->tmf_vpidx = ISP_GET_VPIDX(isp, chan);
4520 			isp_prt(isp, ISP_LOGALL, "Chan %d Reset N-Port Handle 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4521 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4522 			mbs.param[1] = QENTRY_LEN;
4523 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4524 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4525 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4526 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4527 
4528 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4529 				isp_prt(isp, ISP_LOGERR, sacq);
4530 				break;
4531 			}
4532 			isp_put_24xx_tmf(isp, tmf, fcp->isp_scratch);
4533 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, QENTRY_LEN, chan);
4534 			fcp->sendmarker = 1;
4535 			isp_mboxcmd(isp, &mbs);
4536 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4537 				FC_SCRATCH_RELEASE(isp, chan);
4538 				break;
4539 			}
4540 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
4541 			sp = (isp24xx_statusreq_t *) local;
4542 			isp_get_24xx_response(isp, &((isp24xx_statusreq_t *)fcp->isp_scratch)[1], sp);
4543 			FC_SCRATCH_RELEASE(isp, chan);
4544 			if (sp->req_completion_status == 0) {
4545 				return (0);
4546 			}
4547 			isp_prt(isp, ISP_LOGWARN, "Chan %d reset of target %d returned 0x%x", chan, tgt, sp->req_completion_status);
4548 			break;
4549 		} else if (IS_FC(isp)) {
4550 			if (ISP_CAP_2KLOGIN(isp)) {
4551 				mbs.param[1] = tgt;
4552 				mbs.ibits = (1 << 10);
4553 			} else {
4554 				mbs.param[1] = (tgt << 8);
4555 			}
4556 		} else {
4557 			mbs.param[1] = (chan << 15) | (tgt << 8);
4558 		}
4559 		MBSINIT(&mbs, MBOX_ABORT_TARGET, MBLOGALL, 0);
4560 		mbs.param[2] = 3;	/* 'delay', in seconds */
4561 		isp_mboxcmd(isp, &mbs);
4562 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4563 			break;
4564 		}
4565 		isp_prt(isp, ISP_LOGINFO, "Target %d on Bus %d Reset Succeeded", tgt, chan);
4566 		ISP_SET_SENDMARKER(isp, chan, 1);
4567 		return (0);
4568 
4569 	case ISPCTL_ABORT_CMD:
4570 		va_start(ap, ctl);
4571 		xs = va_arg(ap, XS_T *);
4572 		va_end(ap);
4573 
4574 		tgt = XS_TGT(xs);
4575 		chan = XS_CHANNEL(xs);
4576 
4577 		handle = isp_find_handle(isp, xs);
4578 		if (handle == 0) {
4579 			isp_prt(isp, ISP_LOGWARN, "cannot find handle for command to abort");
4580 			break;
4581 		}
4582 		if (IS_24XX(isp)) {
4583 			isp24xx_abrt_t local, *ab = &local, *ab2;
4584 			fcparam *fcp;
4585 			fcportdb_t *lp;
4586 
4587 			fcp = FCPARAM(isp, chan);
4588 			if (tgt < 0 || tgt >= MAX_FC_TARG) {
4589 				isp_prt(isp, ISP_LOGWARN, "Chan %d trying to abort bad target %d", chan, tgt);
4590 				break;
4591 			}
4592 			lp = &fcp->portdb[tgt];
4593 			if (lp->is_target == 0 ||
4594 			    lp->state != FC_PORTDB_STATE_VALID) {
4595 				isp_prt(isp, ISP_LOGWARN, "Chan %d abort of no longer valid target %d", chan, tgt);
4596 				break;
4597 			}
4598 			isp_prt(isp, ISP_LOGALL, "Chan %d Abort Cmd for N-Port 0x%04x @ Port 0x%06x", chan, lp->handle, lp->portid);
4599 			ISP_MEMZERO(ab, QENTRY_LEN);
4600 			ab->abrt_header.rqs_entry_type = RQSTYPE_ABORT_IO;
4601 			ab->abrt_header.rqs_entry_count = 1;
4602 			ab->abrt_handle = lp->handle;
4603 			ab->abrt_cmd_handle = handle;
4604 			ab->abrt_tidlo = lp->portid;
4605 			ab->abrt_tidhi = lp->portid >> 16;
4606 			ab->abrt_vpidx = ISP_GET_VPIDX(isp, chan);
4607 
4608 			ISP_MEMZERO(&mbs, sizeof (mbs));
4609 			MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, 5000000);
4610 			mbs.param[1] = QENTRY_LEN;
4611 			mbs.param[2] = DMA_WD1(fcp->isp_scdma);
4612 			mbs.param[3] = DMA_WD0(fcp->isp_scdma);
4613 			mbs.param[6] = DMA_WD3(fcp->isp_scdma);
4614 			mbs.param[7] = DMA_WD2(fcp->isp_scdma);
4615 
4616 			if (FC_SCRATCH_ACQUIRE(isp, chan)) {
4617 				isp_prt(isp, ISP_LOGERR, sacq);
4618 				break;
4619 			}
4620 			isp_put_24xx_abrt(isp, ab, fcp->isp_scratch);
4621 			ab2 = (isp24xx_abrt_t *) &((uint8_t *)fcp->isp_scratch)[QENTRY_LEN];
4622 			ab2->abrt_nphdl = 0xdeaf;
4623 			MEMORYBARRIER(isp, SYNC_SFORDEV, 0, 2 * QENTRY_LEN, chan);
4624 			isp_mboxcmd(isp, &mbs);
4625 			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4626 				FC_SCRATCH_RELEASE(isp, chan);
4627 				break;
4628 			}
4629 			MEMORYBARRIER(isp, SYNC_SFORCPU, QENTRY_LEN, QENTRY_LEN, chan);
4630 			isp_get_24xx_abrt(isp, ab2, ab);
4631 			FC_SCRATCH_RELEASE(isp, chan);
4632 			if (ab->abrt_nphdl == ISP24XX_ABRT_OKAY) {
4633 				return (0);
4634 			}
4635 			isp_prt(isp, ISP_LOGWARN, "Chan %d handle %d abort returned 0x%x", chan, tgt, ab->abrt_nphdl);
4636 			break;
4637 		} else if (IS_FC(isp)) {
4638 			if (ISP_CAP_SCCFW(isp)) {
4639 				if (ISP_CAP_2KLOGIN(isp)) {
4640 					mbs.param[1] = tgt;
4641 				} else {
4642 					mbs.param[1] = tgt << 8;
4643 				}
4644 				mbs.param[6] = XS_LUN(xs);
4645 			} else {
4646 				mbs.param[1] = tgt << 8 | XS_LUN(xs);
4647 			}
4648 		} else {
4649 			mbs.param[1] = (chan << 15) | (tgt << 8) | XS_LUN(xs);
4650 		}
4651 		MBSINIT(&mbs, MBOX_ABORT,
4652 		    MBLOGALL & ~MBLOGMASK(MBOX_COMMAND_ERROR), 0);
4653 		mbs.param[2] = handle;
4654 		isp_mboxcmd(isp, &mbs);
4655 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4656 			break;
4657 		}
4658 		return (0);
4659 
4660 	case ISPCTL_UPDATE_PARAMS:
4661 
4662 		va_start(ap, ctl);
4663 		chan = va_arg(ap, int);
4664 		va_end(ap);
4665 		isp_spi_update(isp, chan);
4666 		return (0);
4667 
4668 	case ISPCTL_FCLINK_TEST:
4669 
4670 		if (IS_FC(isp)) {
4671 			int usdelay;
4672 			va_start(ap, ctl);
4673 			chan = va_arg(ap, int);
4674 			usdelay = va_arg(ap, int);
4675 			va_end(ap);
4676 			if (usdelay == 0) {
4677 				usdelay =  250000;
4678 			}
4679 			return (isp_fclink_test(isp, chan, usdelay));
4680 		}
4681 		break;
4682 
4683 	case ISPCTL_SCAN_FABRIC:
4684 
4685 		if (IS_FC(isp)) {
4686 			va_start(ap, ctl);
4687 			chan = va_arg(ap, int);
4688 			va_end(ap);
4689 			return (isp_scan_fabric(isp, chan));
4690 		}
4691 		break;
4692 
4693 	case ISPCTL_SCAN_LOOP:
4694 
4695 		if (IS_FC(isp)) {
4696 			va_start(ap, ctl);
4697 			chan = va_arg(ap, int);
4698 			va_end(ap);
4699 			return (isp_scan_loop(isp, chan));
4700 		}
4701 		break;
4702 
4703 	case ISPCTL_PDB_SYNC:
4704 
4705 		if (IS_FC(isp)) {
4706 			va_start(ap, ctl);
4707 			chan = va_arg(ap, int);
4708 			va_end(ap);
4709 			return (isp_pdb_sync(isp, chan));
4710 		}
4711 		break;
4712 
4713 	case ISPCTL_SEND_LIP:
4714 
4715 		if (IS_FC(isp) && !IS_24XX(isp)) {
4716 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
4717 			if (ISP_CAP_2KLOGIN(isp)) {
4718 				mbs.ibits = (1 << 10);
4719 			}
4720 			isp_mboxcmd(isp, &mbs);
4721 			if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
4722 				return (0);
4723 			}
4724 		}
4725 		break;
4726 
4727 	case ISPCTL_GET_PDB:
4728 		if (IS_FC(isp)) {
4729 			isp_pdb_t *pdb;
4730 			va_start(ap, ctl);
4731 			chan = va_arg(ap, int);
4732 			tgt = va_arg(ap, int);
4733 			pdb = va_arg(ap, isp_pdb_t *);
4734 			va_end(ap);
4735 			return (isp_getpdb(isp, chan, tgt, pdb, 1));
4736 		}
4737 		break;
4738 
4739 	case ISPCTL_GET_NAMES:
4740 	{
4741 		uint64_t *wwnn, *wwnp;
4742 		va_start(ap, ctl);
4743 		chan = va_arg(ap, int);
4744 		tgt = va_arg(ap, int);
4745 		wwnn = va_arg(ap, uint64_t *);
4746 		wwnp = va_arg(ap, uint64_t *);
4747 		va_end(ap);
4748 		if (wwnn == NULL && wwnp == NULL) {
4749 			break;
4750 		}
4751 		if (wwnn) {
4752 			*wwnn = isp_get_wwn(isp, chan, tgt, 1);
4753 			if (*wwnn == INI_NONE) {
4754 				break;
4755 			}
4756 		}
4757 		if (wwnp) {
4758 			*wwnp = isp_get_wwn(isp, chan, tgt, 0);
4759 			if (*wwnp == INI_NONE) {
4760 				break;
4761 			}
4762 		}
4763 		return (0);
4764 	}
4765 	case ISPCTL_RUN_MBOXCMD:
4766 	{
4767 		va_start(ap, ctl);
4768 		mbr = va_arg(ap, mbreg_t *);
4769 		va_end(ap);
4770 		isp_mboxcmd(isp, mbr);
4771 		return (0);
4772 	}
4773 	case ISPCTL_PLOGX:
4774 	{
4775 		isp_plcmd_t *p;
4776 		int r;
4777 
4778 		va_start(ap, ctl);
4779 		p = va_arg(ap, isp_plcmd_t *);
4780 		va_end(ap);
4781 
4782 		if ((p->flags & PLOGX_FLG_CMD_MASK) != PLOGX_FLG_CMD_PLOGI || (p->handle != NIL_HANDLE)) {
4783 			return (isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0));
4784 		}
4785 		do {
4786 			isp_next_handle(isp, &p->handle);
4787 			r = isp_plogx(isp, p->channel, p->handle, p->portid, p->flags, 0);
4788 			if ((r & 0xffff) == MBOX_PORT_ID_USED) {
4789 				p->handle = r >> 16;
4790 				r = 0;
4791 				break;
4792 			}
4793 		} while ((r & 0xffff) == MBOX_LOOP_ID_USED);
4794 		return (r);
4795 	}
4796 	case ISPCTL_CHANGE_ROLE:
4797 		if (IS_FC(isp)) {
4798 			int role, r;
4799 
4800 			va_start(ap, ctl);
4801 			chan = va_arg(ap, int);
4802 			role = va_arg(ap, int);
4803 			va_end(ap);
4804 			r = isp_fc_change_role(isp, chan, role);
4805 			return (r);
4806 		}
4807 		break;
4808 	default:
4809 		isp_prt(isp, ISP_LOGERR, "Unknown Control Opcode 0x%x", ctl);
4810 		break;
4811 
4812 	}
4813 	return (-1);
4814 }
4815 
4816 /*
4817  * Interrupt Service Routine(s).
4818  *
4819  * External (OS) framework has done the appropriate locking,
4820  * and the locking will be held throughout this function.
4821  */
4822 
4823 /*
4824  * Limit our stack depth by sticking with the max likely number
4825  * of completions on a request queue at any one time.
4826  */
4827 #ifndef	MAX_REQUESTQ_COMPLETIONS
4828 #define	MAX_REQUESTQ_COMPLETIONS	32
4829 #endif
4830 
4831 void
4832 isp_intr(ispsoftc_t *isp, uint16_t isr, uint16_t sema, uint16_t info)
4833 {
4834 	XS_T *complist[MAX_REQUESTQ_COMPLETIONS], *xs;
4835 	uint32_t iptr, optr, junk;
4836 	int i, nlooked = 0, ndone = 0, continuations_expected = 0;
4837 	int etype, last_etype = 0;
4838 
4839 again:
4840 	/*
4841 	 * Is this a mailbox related interrupt?
4842 	 * The mailbox semaphore will be nonzero if so.
4843 	 */
4844 	if (sema) {
4845  fmbox:
4846 		if (info & MBOX_COMMAND_COMPLETE) {
4847 			isp->isp_intmboxc++;
4848 			if (isp->isp_mboxbsy) {
4849 				int obits = isp->isp_obits;
4850 				isp->isp_mboxtmp[0] = info;
4851 				for (i = 1; i < ISP_NMBOX(isp); i++) {
4852 					if ((obits & (1 << i)) == 0) {
4853 						continue;
4854 					}
4855 					isp->isp_mboxtmp[i] = ISP_READ(isp, MBOX_OFF(i));
4856 				}
4857 				if (isp->isp_mbxwrk0) {
4858 					if (isp_mbox_continue(isp) == 0) {
4859 						return;
4860 					}
4861 				}
4862 				MBOX_NOTIFY_COMPLETE(isp);
4863 			} else {
4864 				isp_prt(isp, ISP_LOGWARN, "mailbox cmd (0x%x) with no waiters", info);
4865 			}
4866 		} else {
4867 			i = IS_FC(isp)? isp_parse_async_fc(isp, info) : isp_parse_async(isp, info);
4868 			if (i < 0) {
4869 				return;
4870 			}
4871 		}
4872 		if ((IS_FC(isp) && info != ASYNC_RIOZIO_STALL) || isp->isp_state != ISP_RUNSTATE) {
4873 			goto out;
4874 		}
4875 	}
4876 
4877 	/*
4878 	 * We can't be getting this now.
4879 	 */
4880 	if (isp->isp_state != ISP_RUNSTATE) {
4881 		/*
4882 		 * This seems to happen to 23XX and 24XX cards- don't know why.
4883 		 */
4884 		 if (isp->isp_mboxbsy && isp->isp_lastmbxcmd == MBOX_ABOUT_FIRMWARE) {
4885 			goto fmbox;
4886 		}
4887 		isp_prt(isp, ISP_LOGINFO, "interrupt (ISR=%x SEMA=%x INFO=%x) "
4888 		    "when not ready", isr, sema, info);
4889 		/*
4890 		 * Thank you very much!  *Burrrp*!
4891 		 */
4892 		isp->isp_residx = ISP_READ(isp, isp->isp_respinrp);
4893 		isp->isp_resodx = isp->isp_residx;
4894 		ISP_WRITE(isp, isp->isp_respoutrp, isp->isp_resodx);
4895 		if (IS_24XX(isp)) {
4896 			ISP_DISABLE_INTS(isp);
4897 		}
4898 		goto out;
4899 	}
4900 
4901 #ifdef	ISP_TARGET_MODE
4902 	/*
4903 	 * Check for ATIO Queue entries.
4904 	 */
4905 	if (IS_24XX(isp) &&
4906 	    (isr == ISPR2HST_ATIO_UPDATE || isr == ISPR2HST_ATIO_RSPQ_UPDATE ||
4907 	     isr == ISPR2HST_ATIO_UPDATE2)) {
4908 		iptr = ISP_READ(isp, BIU2400_ATIO_RSPINP);
4909 		optr = isp->isp_atioodx;
4910 
4911 		while (optr != iptr) {
4912 			uint8_t qe[QENTRY_LEN];
4913 			isphdr_t *hp;
4914 			uint32_t oop;
4915 			void *addr;
4916 
4917 			oop = optr;
4918 			MEMORYBARRIER(isp, SYNC_ATIOQ, oop, QENTRY_LEN, -1);
4919 			addr = ISP_QUEUE_ENTRY(isp->isp_atioq, oop);
4920 			isp_get_hdr(isp, addr, (isphdr_t *)qe);
4921 			hp = (isphdr_t *)qe;
4922 			switch (hp->rqs_entry_type) {
4923 			case RQSTYPE_NOTIFY:
4924 			case RQSTYPE_ATIO:
4925 				(void) isp_target_notify(isp, addr, &oop);
4926 				break;
4927 			default:
4928 				isp_print_qentry(isp, "?ATIOQ entry?", oop, addr);
4929 				break;
4930 			}
4931 			optr = ISP_NXT_QENTRY(oop, RESULT_QUEUE_LEN(isp));
4932 		}
4933 		if (isp->isp_atioodx != optr) {
4934 			ISP_WRITE(isp, BIU2400_ATIO_RSPOUTP, optr);
4935 			isp->isp_atioodx = optr;
4936 		}
4937 	}
4938 #endif
4939 
4940 	/*
4941 	 * You *must* read the Response Queue In Pointer
4942 	 * prior to clearing the RISC interrupt.
4943 	 *
4944 	 * Debounce the 2300 if revision less than 2.
4945 	 */
4946 	if (IS_2100(isp) || (IS_2300(isp) && isp->isp_revision < 2)) {
4947 		i = 0;
4948 		do {
4949 			iptr = ISP_READ(isp, isp->isp_respinrp);
4950 			junk = ISP_READ(isp, isp->isp_respinrp);
4951 		} while (junk != iptr && ++i < 1000);
4952 
4953 		if (iptr != junk) {
4954 			isp_prt(isp, ISP_LOGWARN, "Response Queue Out Pointer Unstable (%x, %x)", iptr, junk);
4955 			goto out;
4956 		}
4957 	} else {
4958 		iptr = ISP_READ(isp, isp->isp_respinrp);
4959 	}
4960 
4961 	optr = isp->isp_resodx;
4962 	if (optr == iptr && sema == 0) {
4963 		/*
4964 		 * There are a lot of these- reasons unknown- mostly on
4965 		 * faster Alpha machines.
4966 		 *
4967 		 * I tried delaying after writing HCCR_CMD_CLEAR_RISC_INT to
4968 		 * make sure the old interrupt went away (to avoid 'ringing'
4969 		 * effects), but that didn't stop this from occurring.
4970 		 */
4971 		if (IS_24XX(isp)) {
4972 			junk = 0;
4973 		} else if (IS_23XX(isp)) {
4974 			ISP_DELAY(100);
4975 			iptr = ISP_READ(isp, isp->isp_respinrp);
4976 			junk = ISP_READ(isp, BIU_R2HSTSLO);
4977 		} else {
4978 			junk = ISP_READ(isp, BIU_ISR);
4979 		}
4980 		if (optr == iptr) {
4981 			if (IS_23XX(isp) || IS_24XX(isp)) {
4982 				;
4983 			} else {
4984 				sema = ISP_READ(isp, BIU_SEMA);
4985 				info = ISP_READ(isp, OUTMAILBOX0);
4986 				if ((sema & 0x3) && (info & 0x8000)) {
4987 					goto again;
4988 				}
4989 			}
4990 			isp->isp_intbogus++;
4991 			isp_prt(isp, ISP_LOGDEBUG1, "bogus intr- isr %x (%x) iptr %x optr %x", isr, junk, iptr, optr);
4992 		}
4993 	}
4994 	isp->isp_residx = iptr;
4995 
4996 	while (optr != iptr) {
4997 		uint8_t qe[QENTRY_LEN];
4998 		ispstatusreq_t *sp = (ispstatusreq_t *) qe;
4999 		isphdr_t *hp;
5000 		int buddaboom, scsi_status, completion_status;
5001 		int req_status_flags, req_state_flags;
5002 		uint8_t *snsp, *resp;
5003 		uint32_t rlen, slen, totslen;
5004 		long resid;
5005 		uint16_t oop;
5006 
5007 		hp = (isphdr_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
5008 		oop = optr;
5009 		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN(isp));
5010 		nlooked++;
5011  read_again:
5012 		buddaboom = req_status_flags = req_state_flags = 0;
5013 		resid = 0L;
5014 
5015 		/*
5016 		 * Synchronize our view of this response queue entry.
5017 		 */
5018 		MEMORYBARRIER(isp, SYNC_RESULT, oop, QENTRY_LEN, -1);
5019 		isp_get_hdr(isp, hp, &sp->req_header);
5020 		etype = sp->req_header.rqs_entry_type;
5021 
5022 		if (IS_24XX(isp) && etype == RQSTYPE_RESPONSE) {
5023 			isp24xx_statusreq_t *sp2 = (isp24xx_statusreq_t *)qe;
5024 			isp_get_24xx_response(isp, (isp24xx_statusreq_t *)hp, sp2);
5025 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5026 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp2);
5027 			}
5028 			scsi_status = sp2->req_scsi_status;
5029 			completion_status = sp2->req_completion_status;
5030 			if ((scsi_status & 0xff) != 0)
5031 				req_state_flags = RQSF_GOT_STATUS;
5032 			else
5033 				req_state_flags = 0;
5034 			resid = sp2->req_resid;
5035 		} else if (etype == RQSTYPE_RESPONSE) {
5036 			isp_get_response(isp, (ispstatusreq_t *) hp, sp);
5037 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5038 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, sp);
5039 			}
5040 			scsi_status = sp->req_scsi_status;
5041 			completion_status = sp->req_completion_status;
5042 			req_status_flags = sp->req_status_flags;
5043 			req_state_flags = sp->req_state_flags;
5044 			resid = sp->req_resid;
5045 		} else if (etype == RQSTYPE_RIO1) {
5046 			isp_rio1_t *rio = (isp_rio1_t *) qe;
5047 			isp_get_rio1(isp, (isp_rio1_t *) hp, rio);
5048 			if (isp->isp_dblev & ISP_LOGDEBUG1) {
5049 				isp_print_bytes(isp, "Response Queue Entry", QENTRY_LEN, rio);
5050 			}
5051 			for (i = 0; i < rio->req_header.rqs_seqno; i++) {
5052 				isp_fastpost_complete(isp, rio->req_handles[i]);
5053 			}
5054 			if (isp->isp_fpcchiwater < rio->req_header.rqs_seqno) {
5055 				isp->isp_fpcchiwater = rio->req_header.rqs_seqno;
5056 			}
5057 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5058 			last_etype = etype;
5059 			continue;
5060 		} else if (etype == RQSTYPE_RIO2) {
5061 			isp_prt(isp, ISP_LOGERR, "dropping RIO2 response");
5062 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5063 			last_etype = etype;
5064 			continue;
5065 		} else if (etype == RQSTYPE_STATUS_CONT) {
5066 			isp_get_cont_response(isp, (ispstatus_cont_t *) hp, (ispstatus_cont_t *) sp);
5067 			if (last_etype == RQSTYPE_RESPONSE && continuations_expected && ndone > 0 && (xs = complist[ndone-1]) != NULL) {
5068 				ispstatus_cont_t *scp = (ispstatus_cont_t *) sp;
5069 				XS_SENSE_APPEND(xs, scp->req_sense_data, sizeof (scp->req_sense_data));
5070 				isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, "%d more Status Continuations expected", --continuations_expected);
5071 			} else {
5072 				isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
5073 			}
5074 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5075 			continue;
5076 		} else {
5077 			/*
5078 			 * Somebody reachable via isp_handle_other_response
5079 			 * may have updated the response queue pointers for
5080 			 * us, so we reload our goal index.
5081 			 */
5082 			int r;
5083 			uint32_t tsto = oop;
5084 			r = isp_handle_other_response(isp, etype, hp, &tsto);
5085 			if (r < 0) {
5086 				goto read_again;
5087 			}
5088 			/*
5089 			 * If somebody updated the output pointer, then reset
5090 			 * optr to be one more than the updated amount.
5091 			 */
5092 			while (tsto != oop) {
5093 				optr = ISP_NXT_QENTRY(tsto, RESULT_QUEUE_LEN(isp));
5094 			}
5095 			if (r > 0) {
5096 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5097 				last_etype = etype;
5098 				continue;
5099 			}
5100 
5101 			/*
5102 			 * After this point, we'll just look at the header as
5103 			 * we don't know how to deal with the rest of the
5104 			 * response.
5105 			 */
5106 
5107 			/*
5108 			 * It really has to be a bounced request just copied
5109 			 * from the request queue to the response queue. If
5110 			 * not, something bad has happened.
5111 			 */
5112 			if (etype != RQSTYPE_REQUEST) {
5113 				isp_prt(isp, ISP_LOGERR, notresp, etype, oop, optr, nlooked);
5114 				isp_print_bytes(isp, "Request Queue Entry", QENTRY_LEN, sp);
5115 				ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5116 				last_etype = etype;
5117 				continue;
5118 			}
5119 			buddaboom = 1;
5120 			scsi_status = sp->req_scsi_status;
5121 			completion_status = sp->req_completion_status;
5122 			req_status_flags = sp->req_status_flags;
5123 			req_state_flags = sp->req_state_flags;
5124 			resid = sp->req_resid;
5125 		}
5126 
5127 		if (sp->req_header.rqs_flags & RQSFLAG_MASK) {
5128 			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
5129 				isp_print_bytes(isp, "unexpected continuation segment", QENTRY_LEN, sp);
5130 				last_etype = etype;
5131 				continue;
5132 			}
5133 			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
5134 				isp_prt(isp, ISP_LOG_WARN1, "internal queues full");
5135 				/*
5136 				 * We'll synthesize a QUEUE FULL message below.
5137 				 */
5138 			}
5139 			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
5140 				isp_print_bytes(isp, "bad header flag", QENTRY_LEN, sp);
5141 				buddaboom++;
5142 			}
5143 			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
5144 				isp_print_bytes(isp, "bad request packet", QENTRY_LEN, sp);
5145 				buddaboom++;
5146 			}
5147 			if (sp->req_header.rqs_flags & RQSFLAG_BADCOUNT) {
5148 				isp_print_bytes(isp, "invalid entry count", QENTRY_LEN, sp);
5149 				buddaboom++;
5150 			}
5151 			if (sp->req_header.rqs_flags & RQSFLAG_BADORDER) {
5152 				isp_print_bytes(isp, "invalid IOCB ordering", QENTRY_LEN, sp);
5153 				last_etype = etype;
5154 				continue;
5155 			}
5156 		}
5157 
5158 		if (!ISP_VALID_HANDLE(isp, sp->req_handle)) {
5159 			isp_prt(isp, ISP_LOGERR, "bad request handle 0x%x (iocb type 0x%x)", sp->req_handle, etype);
5160 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5161 			last_etype = etype;
5162 			continue;
5163 		}
5164 		xs = isp_find_xs(isp, sp->req_handle);
5165 		if (xs == NULL) {
5166 			uint8_t ts = completion_status & 0xff;
5167 			/*
5168 			 * Only whine if this isn't the expected fallout of
5169 			 * aborting the command or resetting the target.
5170 			 */
5171 			if (etype != RQSTYPE_RESPONSE) {
5172 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (type 0x%x)", sp->req_handle, etype);
5173 			} else if (ts != RQCS_ABORTED && ts != RQCS_RESET_OCCURRED) {
5174 				isp_prt(isp, ISP_LOGERR, "cannot find handle 0x%x (status 0x%x)", sp->req_handle, ts);
5175 			}
5176 			ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5177 			last_etype = etype;
5178 			continue;
5179 		}
5180 		if (req_status_flags & RQSTF_BUS_RESET) {
5181 			isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%jx bus was reset",
5182 			    XS_CHANNEL(xs), XS_TGT(xs), (uintmax_t)XS_LUN(xs));
5183 			XS_SETERR(xs, HBA_BUSRESET);
5184 			ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
5185 		}
5186 		if (buddaboom) {
5187 			isp_prt(isp, ISP_LOG_WARN1, "%d.%d.%jx buddaboom",
5188 			    XS_CHANNEL(xs), XS_TGT(xs), (uintmax_t)XS_LUN(xs));
5189 			XS_SETERR(xs, HBA_BOTCH);
5190 		}
5191 
5192 		resp = NULL;
5193 		rlen = 0;
5194 		snsp = NULL;
5195 		totslen = slen = 0;
5196 		if (IS_24XX(isp) && (scsi_status & (RQCS_RV|RQCS_SV)) != 0) {
5197 			resp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5198 			rlen = ((isp24xx_statusreq_t *)sp)->req_response_len;
5199 		} else if (IS_FC(isp) && (scsi_status & RQCS_RV) != 0) {
5200 			resp = sp->req_response;
5201 			rlen = sp->req_response_len;
5202 		}
5203 		if (IS_FC(isp) && (scsi_status & RQCS_SV) != 0) {
5204 			/*
5205 			 * Fibre Channel F/W doesn't say we got status
5206 			 * if there's Sense Data instead. I guess they
5207 			 * think it goes w/o saying.
5208 			 */
5209 			req_state_flags |= RQSF_GOT_STATUS|RQSF_GOT_SENSE;
5210 			if (IS_24XX(isp)) {
5211 				snsp = ((isp24xx_statusreq_t *)sp)->req_rsp_sense;
5212 				snsp += rlen;
5213 				totslen = ((isp24xx_statusreq_t *)sp)->req_sense_len;
5214 				slen = (sizeof (((isp24xx_statusreq_t *)sp)->req_rsp_sense)) - rlen;
5215 				if (totslen < slen)
5216 					slen = totslen;
5217 			} else {
5218 				snsp = sp->req_sense_data;
5219 				totslen = sp->req_sense_len;
5220 				slen = sizeof (sp->req_sense_data);
5221 				if (totslen < slen)
5222 					slen = totslen;
5223 			}
5224 		} else if (IS_SCSI(isp) && (req_state_flags & RQSF_GOT_SENSE)) {
5225 			snsp = sp->req_sense_data;
5226 			totslen = sp->req_sense_len;
5227 			slen = sizeof (sp->req_sense_data);
5228 			if (totslen < slen)
5229 				slen = totslen;
5230 		}
5231 		if (req_state_flags & RQSF_GOT_STATUS) {
5232 			*XS_STSP(xs) = scsi_status & 0xff;
5233 		}
5234 
5235 		switch (etype) {
5236 		case RQSTYPE_RESPONSE:
5237 			if (resp && rlen >= 4 && resp[FCP_RSPNS_CODE_OFFSET] != 0) {
5238 				const char *ptr;
5239 				char lb[64];
5240 				const char *rnames[10] = {
5241 				    "Task Management function complete",
5242 				    "FCP_DATA length different than FCP_BURST_LEN",
5243 				    "FCP_CMND fields invalid",
5244 				    "FCP_DATA parameter mismatch with FCP_DATA_RO",
5245 				    "Task Management function rejected",
5246 				    "Task Management function failed",
5247 				    NULL,
5248 				    NULL,
5249 				    "Task Management function succeeded",
5250 				    "Task Management function incorrect logical unit number",
5251 				};
5252 				uint8_t code = resp[FCP_RSPNS_CODE_OFFSET];
5253 				if (code >= 10 || rnames[code] == NULL) {
5254 					ISP_SNPRINTF(lb, sizeof(lb),
5255 					    "Unknown FCP Response Code 0x%x",
5256 					    code);
5257 					ptr = lb;
5258 				} else {
5259 					ptr = rnames[code];
5260 				}
5261 				isp_xs_prt(isp, xs, ISP_LOGWARN,
5262 				    "FCP RESPONSE, LENGTH %u: %s CDB0=0x%02x",
5263 				    rlen, ptr, XS_CDBP(xs)[0] & 0xff);
5264 				if (code != 0 && code != 8)
5265 					XS_SETERR(xs, HBA_BOTCH);
5266 			}
5267 			if (IS_24XX(isp)) {
5268 				isp_parse_status_24xx(isp, (isp24xx_statusreq_t *)sp, xs, &resid);
5269 			} else {
5270 				isp_parse_status(isp, (void *)sp, xs, &resid);
5271 			}
5272 			if ((XS_NOERR(xs) || XS_ERR(xs) == HBA_NOERROR) && (*XS_STSP(xs) == SCSI_BUSY)) {
5273 				XS_SETERR(xs, HBA_TGTBSY);
5274 			}
5275 			if (IS_SCSI(isp)) {
5276 				XS_SET_RESID(xs, resid);
5277 				/*
5278 				 * A new synchronous rate was negotiated for
5279 				 * this target. Mark state such that we'll go
5280 				 * look up that which has changed later.
5281 				 */
5282 				if (req_status_flags & RQSTF_NEGOTIATION) {
5283 					int t = XS_TGT(xs);
5284 					sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
5285 					sdp->isp_devparam[t].dev_refresh = 1;
5286 					sdp->update = 1;
5287 				}
5288 			} else {
5289 				if (req_status_flags & RQSF_XFER_COMPLETE) {
5290 					XS_SET_RESID(xs, 0);
5291 				} else if (scsi_status & RQCS_RESID) {
5292 					XS_SET_RESID(xs, resid);
5293 				} else {
5294 					XS_SET_RESID(xs, 0);
5295 				}
5296 			}
5297 			if (snsp && slen) {
5298 				if (totslen > slen) {
5299 					continuations_expected += ((totslen - slen + QENTRY_LEN - 5) / (QENTRY_LEN - 4));
5300 					if (ndone > (MAX_REQUESTQ_COMPLETIONS - continuations_expected - 1)) {
5301 						/* we'll lose some stats, but that's a small price to pay */
5302 						for (i = 0; i < ndone; i++) {
5303 							if (complist[i]) {
5304 								isp->isp_rsltccmplt++;
5305 								isp_done(complist[i]);
5306 							}
5307 						}
5308 						ndone = 0;
5309 					}
5310 					isp_prt(isp, ISP_LOGDEBUG0|ISP_LOG_CWARN, "Expecting %d more Status Continuations for total sense length of %u",
5311 					    continuations_expected, totslen);
5312 				}
5313 				XS_SAVE_SENSE(xs, snsp, totslen, slen);
5314 			} else if ((req_status_flags & RQSF_GOT_STATUS) && (scsi_status & 0xff) == SCSI_CHECK && IS_FC(isp)) {
5315 				isp_prt(isp, ISP_LOGWARN, "CHECK CONDITION w/o sense data for CDB=0x%x", XS_CDBP(xs)[0] & 0xff);
5316 				isp_print_bytes(isp, "CC with no Sense", QENTRY_LEN, qe);
5317 			}
5318 			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));
5319 			break;
5320 		case RQSTYPE_REQUEST:
5321 		case RQSTYPE_A64:
5322 		case RQSTYPE_T2RQS:
5323 		case RQSTYPE_T3RQS:
5324 		case RQSTYPE_T7RQS:
5325 			if (!IS_24XX(isp) && (sp->req_header.rqs_flags & RQSFLAG_FULL)) {
5326 				/*
5327 				 * Force Queue Full status.
5328 				 */
5329 				*XS_STSP(xs) = SCSI_QFULL;
5330 				XS_SETERR(xs, HBA_NOERROR);
5331 			} else if (XS_NOERR(xs)) {
5332 				isp_prt(isp, ISP_LOG_WARN1,
5333 				    "%d.%d.%jx badness at %s:%u",
5334 				    XS_CHANNEL(xs), XS_TGT(xs),
5335 				    (uintmax_t)XS_LUN(xs),
5336 				    __func__, __LINE__);
5337 				XS_SETERR(xs, HBA_BOTCH);
5338 			}
5339 			XS_SET_RESID(xs, XS_XFRLEN(xs));
5340 			break;
5341 		default:
5342 			isp_print_bytes(isp, "Unhandled Response Type", QENTRY_LEN, qe);
5343 			if (XS_NOERR(xs)) {
5344 				XS_SETERR(xs, HBA_BOTCH);
5345 			}
5346 			break;
5347 		}
5348 
5349 		/*
5350 		 * Free any DMA resources. As a side effect, this may
5351 		 * also do any cache flushing necessary for data coherence.
5352 		 */
5353 		if (XS_XFRLEN(xs)) {
5354 			ISP_DMAFREE(isp, xs, sp->req_handle);
5355 		}
5356 		isp_destroy_handle(isp, sp->req_handle);
5357 
5358 		if (isp->isp_nactive > 0) {
5359 		    isp->isp_nactive--;
5360 		}
5361 		complist[ndone++] = xs;	/* defer completion call until later */
5362 		ISP_MEMZERO(hp, QENTRY_LEN);	/* PERF */
5363 		last_etype = etype;
5364 		if (ndone == MAX_REQUESTQ_COMPLETIONS) {
5365 			break;
5366 		}
5367 	}
5368 
5369 	/*
5370 	 * If we looked at any commands, then it's valid to find out
5371 	 * what the outpointer is. It also is a trigger to update the
5372 	 * ISP's notion of what we've seen so far.
5373 	 */
5374 	if (nlooked) {
5375 		ISP_WRITE(isp, isp->isp_respoutrp, optr);
5376 		isp->isp_resodx = optr;
5377 		if (isp->isp_rscchiwater < ndone)
5378 			isp->isp_rscchiwater = ndone;
5379 	}
5380 
5381 out:
5382 
5383 	if (IS_24XX(isp)) {
5384 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
5385 	} else {
5386 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
5387 		ISP_WRITE(isp, BIU_SEMA, 0);
5388 	}
5389 
5390 	for (i = 0; i < ndone; i++) {
5391 		xs = complist[i];
5392 		if (xs) {
5393 			if (((isp->isp_dblev & (ISP_LOGDEBUG1|ISP_LOGDEBUG2|ISP_LOGDEBUG3))) ||
5394 			    ((isp->isp_dblev & (ISP_LOGDEBUG0|ISP_LOG_CWARN) && ((!XS_NOERR(xs)) || (*XS_STSP(xs) != SCSI_GOOD))))) {
5395 				isp_prt_endcmd(isp, xs);
5396 			}
5397 			isp->isp_rsltccmplt++;
5398 			isp_done(xs);
5399 		}
5400 	}
5401 }
5402 
5403 /*
5404  * Support routines.
5405  */
5406 
5407 void
5408 isp_prt_endcmd(ispsoftc_t *isp, XS_T *xs)
5409 {
5410 	char cdbstr[16 * 5 + 1];
5411 	int i, lim;
5412 
5413 	lim = XS_CDBLEN(xs) > 16? 16 : XS_CDBLEN(xs);
5414 	ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "0x%02x ", XS_CDBP(xs)[0]);
5415 	for (i = 1; i < lim; i++) {
5416 		ISP_SNPRINTF(cdbstr, sizeof (cdbstr), "%s0x%02x ", cdbstr, XS_CDBP(xs)[i]);
5417 	}
5418 	if (XS_SENSE_VALID(xs)) {
5419 		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",
5420 		    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));
5421 	} else {
5422 		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));
5423 	}
5424 }
5425 
5426 /*
5427  * Parse an ASYNC mailbox complete
5428  *
5429  * Return non-zero if the event has been acknowledged.
5430  */
5431 static int
5432 isp_parse_async(ispsoftc_t *isp, uint16_t mbox)
5433 {
5434 	int acked = 0;
5435 	uint32_t h1 = 0, h2 = 0;
5436 	uint16_t chan = 0;
5437 
5438 	/*
5439 	 * Pick up the channel, but not if this is a ASYNC_RIO32_2,
5440 	 * where Mailboxes 6/7 have the second handle.
5441 	 */
5442 	if (mbox != ASYNC_RIO32_2) {
5443 		if (IS_DUALBUS(isp)) {
5444 			chan = ISP_READ(isp, OUTMAILBOX6);
5445 		}
5446 	}
5447 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5448 
5449 	switch (mbox) {
5450 	case ASYNC_BUS_RESET:
5451 		ISP_SET_SENDMARKER(isp, chan, 1);
5452 #ifdef	ISP_TARGET_MODE
5453 		if (isp_target_async(isp, chan, mbox)) {
5454 			acked = 1;
5455 		}
5456 #endif
5457 		isp_async(isp, ISPASYNC_BUS_RESET, chan);
5458 		break;
5459 	case ASYNC_SYSTEM_ERROR:
5460 		isp->isp_dead = 1;
5461 		isp->isp_state = ISP_CRASHED;
5462 		/*
5463 		 * Were we waiting for a mailbox command to complete?
5464 		 * If so, it's dead, so wake up the waiter.
5465 		 */
5466 		if (isp->isp_mboxbsy) {
5467 			isp->isp_obits = 1;
5468 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5469 			MBOX_NOTIFY_COMPLETE(isp);
5470 		}
5471 		/*
5472 		 * It's up to the handler for isp_async to reinit stuff and
5473 		 * restart the firmware
5474 		 */
5475 		isp_async(isp, ISPASYNC_FW_CRASH);
5476 		acked = 1;
5477 		break;
5478 
5479 	case ASYNC_RQS_XFER_ERR:
5480 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5481 		break;
5482 
5483 	case ASYNC_RSP_XFER_ERR:
5484 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5485 		break;
5486 
5487 	case ASYNC_QWAKEUP:
5488 		/*
5489 		 * We've just been notified that the Queue has woken up.
5490 		 * We don't need to be chatty about this- just unlatch things
5491 		 * and move on.
5492 		 */
5493 		mbox = ISP_READ(isp, isp->isp_rqstoutrp);
5494 		break;
5495 
5496 	case ASYNC_TIMEOUT_RESET:
5497 		isp_prt(isp, ISP_LOGWARN, "timeout initiated SCSI bus reset of chan %d", chan);
5498 		ISP_SET_SENDMARKER(isp, chan, 1);
5499 #ifdef	ISP_TARGET_MODE
5500 		if (isp_target_async(isp, chan, mbox)) {
5501 			acked = 1;
5502 		}
5503 #endif
5504 		break;
5505 
5506 	case ASYNC_DEVICE_RESET:
5507 		isp_prt(isp, ISP_LOGINFO, "device reset on chan %d", chan);
5508 		ISP_SET_SENDMARKER(isp, chan, 1);
5509 #ifdef	ISP_TARGET_MODE
5510 		if (isp_target_async(isp, chan, mbox)) {
5511 			acked = 1;
5512 		}
5513 #endif
5514 		break;
5515 
5516 	case ASYNC_EXTMSG_UNDERRUN:
5517 		isp_prt(isp, ISP_LOGWARN, "extended message underrun");
5518 		break;
5519 
5520 	case ASYNC_SCAM_INT:
5521 		isp_prt(isp, ISP_LOGINFO, "SCAM interrupt");
5522 		break;
5523 
5524 	case ASYNC_HUNG_SCSI:
5525 		isp_prt(isp, ISP_LOGERR, "stalled SCSI Bus after DATA Overrun");
5526 		/* XXX: Need to issue SCSI reset at this point */
5527 		break;
5528 
5529 	case ASYNC_KILLED_BUS:
5530 		isp_prt(isp, ISP_LOGERR, "SCSI Bus reset after DATA Overrun");
5531 		break;
5532 
5533 	case ASYNC_BUS_TRANSIT:
5534 		mbox = ISP_READ(isp, OUTMAILBOX2);
5535 		switch (mbox & SXP_PINS_MODE_MASK) {
5536 		case SXP_PINS_LVD_MODE:
5537 			isp_prt(isp, ISP_LOGINFO, "Transition to LVD mode");
5538 			SDPARAM(isp, chan)->isp_diffmode = 0;
5539 			SDPARAM(isp, chan)->isp_ultramode = 0;
5540 			SDPARAM(isp, chan)->isp_lvdmode = 1;
5541 			break;
5542 		case SXP_PINS_HVD_MODE:
5543 			isp_prt(isp, ISP_LOGINFO,
5544 			    "Transition to Differential mode");
5545 			SDPARAM(isp, chan)->isp_diffmode = 1;
5546 			SDPARAM(isp, chan)->isp_ultramode = 0;
5547 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5548 			break;
5549 		case SXP_PINS_SE_MODE:
5550 			isp_prt(isp, ISP_LOGINFO,
5551 			    "Transition to Single Ended mode");
5552 			SDPARAM(isp, chan)->isp_diffmode = 0;
5553 			SDPARAM(isp, chan)->isp_ultramode = 1;
5554 			SDPARAM(isp, chan)->isp_lvdmode = 0;
5555 			break;
5556 		default:
5557 			isp_prt(isp, ISP_LOGWARN,
5558 			    "Transition to Unknown Mode 0x%x", mbox);
5559 			break;
5560 		}
5561 		/*
5562 		 * XXX: Set up to renegotiate again!
5563 		 */
5564 		/* Can only be for a 1080... */
5565 		ISP_SET_SENDMARKER(isp, chan, 1);
5566 		break;
5567 
5568 	case ASYNC_CMD_CMPLT:
5569 	case ASYNC_RIO32_1:
5570 		if (!IS_ULTRA3(isp)) {
5571 			isp_prt(isp, ISP_LOGERR, "unexpected fast posting completion");
5572 			break;
5573 		}
5574 		/* FALLTHROUGH */
5575 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5576 		break;
5577 
5578 	case ASYNC_RIO32_2:
5579 		h1 = (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1);
5580 		h2 = (ISP_READ(isp, OUTMAILBOX7) << 16) | ISP_READ(isp, OUTMAILBOX6);
5581 		break;
5582 
5583 	case ASYNC_RIO16_5:
5584 	case ASYNC_RIO16_4:
5585 	case ASYNC_RIO16_3:
5586 	case ASYNC_RIO16_2:
5587 	case ASYNC_RIO16_1:
5588 		isp_prt(isp, ISP_LOGERR, "unexpected 16 bit RIO handle");
5589 		break;
5590 	default:
5591 		isp_prt(isp, ISP_LOGWARN, "%s: unhandled async code 0x%x", __func__, mbox);
5592 		break;
5593 	}
5594 
5595 	if (h1 || h2) {
5596 		isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h1);
5597 		isp_fastpost_complete(isp, h1);
5598 		if (h2) {
5599 			isp_prt(isp, ISP_LOGDEBUG3, "fast post/rio completion of 0x%08x", h2);
5600 			isp_fastpost_complete(isp, h2);
5601 			if (isp->isp_fpcchiwater < 2) {
5602 				isp->isp_fpcchiwater = 2;
5603 			}
5604 		} else {
5605 			if (isp->isp_fpcchiwater < 1) {
5606 				isp->isp_fpcchiwater = 1;
5607 			}
5608 		}
5609 	} else {
5610 		isp->isp_intoasync++;
5611 	}
5612 	return (acked);
5613 }
5614 
5615 static int
5616 isp_parse_async_fc(ispsoftc_t *isp, uint16_t mbox)
5617 {
5618 	fcparam *fcp;
5619 	int acked = 0;
5620 	uint16_t chan;
5621 
5622 	if (IS_DUALBUS(isp)) {
5623 		chan = ISP_READ(isp, OUTMAILBOX6);
5624 	} else {
5625 		chan = 0;
5626 	}
5627 	isp_prt(isp, ISP_LOGDEBUG2, "Async Mbox 0x%x", mbox);
5628 
5629 	switch (mbox) {
5630 	case ASYNC_SYSTEM_ERROR:
5631 		isp->isp_dead = 1;
5632 		isp->isp_state = ISP_CRASHED;
5633 		FCPARAM(isp, chan)->isp_loopstate = LOOP_NIL;
5634 		isp_change_fw_state(isp, chan, FW_CONFIG_WAIT);
5635 		/*
5636 		 * Were we waiting for a mailbox command to complete?
5637 		 * If so, it's dead, so wake up the waiter.
5638 		 */
5639 		if (isp->isp_mboxbsy) {
5640 			isp->isp_obits = 1;
5641 			isp->isp_mboxtmp[0] = MBOX_HOST_INTERFACE_ERROR;
5642 			MBOX_NOTIFY_COMPLETE(isp);
5643 		}
5644 		/*
5645 		 * It's up to the handler for isp_async to reinit stuff and
5646 		 * restart the firmware
5647 		 */
5648 		isp_async(isp, ISPASYNC_FW_CRASH);
5649 		acked = 1;
5650 		break;
5651 
5652 	case ASYNC_RQS_XFER_ERR:
5653 		isp_prt(isp, ISP_LOGERR, "Request Queue Transfer Error");
5654 		break;
5655 
5656 	case ASYNC_RSP_XFER_ERR:
5657 		isp_prt(isp, ISP_LOGERR, "Response Queue Transfer Error");
5658 		break;
5659 
5660 	case ASYNC_QWAKEUP:
5661 #ifdef	ISP_TARGET_MODE
5662 		if (IS_24XX(isp)) {
5663 			isp_prt(isp, ISP_LOGERR, "ATIO Queue Transfer Error");
5664 			break;
5665 		}
5666 #endif
5667 		isp_prt(isp, ISP_LOGERR, "%s: unexpected ASYNC_QWAKEUP code", __func__);
5668 		break;
5669 
5670 	case ASYNC_CMD_CMPLT:
5671 		isp_fastpost_complete(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1));
5672 		if (isp->isp_fpcchiwater < 1) {
5673 			isp->isp_fpcchiwater = 1;
5674 		}
5675 		break;
5676 
5677 	case ASYNC_RIOZIO_STALL:
5678 		break;
5679 
5680 	case ASYNC_CTIO_DONE:
5681 #ifdef	ISP_TARGET_MODE
5682 		if (isp_target_async(isp, (ISP_READ(isp, OUTMAILBOX2) << 16) | ISP_READ(isp, OUTMAILBOX1), mbox)) {
5683 			acked = 1;
5684 		} else {
5685 			isp->isp_fphccmplt++;
5686 		}
5687 #else
5688 		isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC CTIO done");
5689 #endif
5690 		break;
5691 	case ASYNC_LIP_ERROR:
5692 	case ASYNC_LIP_NOS_OLS_RECV:
5693 	case ASYNC_LIP_OCCURRED:
5694 	case ASYNC_PTPMODE:
5695 		/*
5696 		 * These are broadcast events that have to be sent across
5697 		 * all active channels.
5698 		 */
5699 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5700 			fcp = FCPARAM(isp, chan);
5701 			int topo = fcp->isp_topo;
5702 
5703 			if (fcp->role == ISP_ROLE_NONE)
5704 				continue;
5705 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
5706 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5707 			ISP_SET_SENDMARKER(isp, chan, 1);
5708 			isp_async(isp, ISPASYNC_LIP, chan);
5709 #ifdef	ISP_TARGET_MODE
5710 			if (isp_target_async(isp, chan, mbox)) {
5711 				acked = 1;
5712 			}
5713 #endif
5714 			/*
5715 			 * We've had problems with data corruption occuring on
5716 			 * commands that complete (with no apparent error) after
5717 			 * we receive a LIP. This has been observed mostly on
5718 			 * Local Loop topologies. To be safe, let's just mark
5719 			 * all active initiator commands as dead.
5720 			 */
5721 			if (topo == TOPO_NL_PORT || topo == TOPO_FL_PORT) {
5722 				int i, j;
5723 				for (i = j = 0; i < isp->isp_maxcmds; i++) {
5724 					XS_T *xs;
5725 					isp_hdl_t *hdp;
5726 
5727 					hdp = &isp->isp_xflist[i];
5728 					if (ISP_H2HT(hdp->handle) != ISP_HANDLE_INITIATOR) {
5729 						continue;
5730 					}
5731 					xs = hdp->cmd;
5732 					if (XS_CHANNEL(xs) != chan) {
5733 						continue;
5734 					}
5735 					j++;
5736 					isp_prt(isp, ISP_LOG_WARN1,
5737 					    "%d.%d.%jx bus reset set at %s:%u",
5738 					    XS_CHANNEL(xs), XS_TGT(xs),
5739 					    (uintmax_t)XS_LUN(xs),
5740 					    __func__, __LINE__);
5741 					XS_SETERR(xs, HBA_BUSRESET);
5742 				}
5743 				if (j) {
5744 					isp_prt(isp, ISP_LOGERR, lipd, chan, j);
5745 				}
5746 			}
5747 		}
5748 		break;
5749 
5750 	case ASYNC_LOOP_UP:
5751 		/*
5752 		 * This is a broadcast event that has to be sent across
5753 		 * all active channels.
5754 		 */
5755 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5756 			fcp = FCPARAM(isp, chan);
5757 			if (fcp->role == ISP_ROLE_NONE)
5758 				continue;
5759 			fcp->isp_linkstate = 1;
5760 			if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5761 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5762 			ISP_SET_SENDMARKER(isp, chan, 1);
5763 			isp_async(isp, ISPASYNC_LOOP_UP, chan);
5764 #ifdef	ISP_TARGET_MODE
5765 			if (isp_target_async(isp, chan, mbox)) {
5766 				acked = 1;
5767 			}
5768 #endif
5769 		}
5770 		break;
5771 
5772 	case ASYNC_LOOP_DOWN:
5773 		/*
5774 		 * This is a broadcast event that has to be sent across
5775 		 * all active channels.
5776 		 */
5777 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5778 			fcp = FCPARAM(isp, chan);
5779 			if (fcp->role == ISP_ROLE_NONE)
5780 				continue;
5781 			ISP_SET_SENDMARKER(isp, chan, 1);
5782 			fcp->isp_linkstate = 0;
5783 			fcp->isp_loopstate = LOOP_NIL;
5784 			isp_async(isp, ISPASYNC_LOOP_DOWN, chan);
5785 #ifdef	ISP_TARGET_MODE
5786 			if (isp_target_async(isp, chan, mbox)) {
5787 				acked = 1;
5788 			}
5789 #endif
5790 		}
5791 		break;
5792 
5793 	case ASYNC_LOOP_RESET:
5794 		/*
5795 		 * This is a broadcast event that has to be sent across
5796 		 * all active channels.
5797 		 */
5798 		for (chan = 0; chan < isp->isp_nchan; chan++) {
5799 			fcp = FCPARAM(isp, chan);
5800 			if (fcp->role == ISP_ROLE_NONE)
5801 				continue;
5802 			ISP_SET_SENDMARKER(isp, chan, 1);
5803 			if (fcp->isp_loopstate > LOOP_HAVE_LINK)
5804 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5805 			isp_async(isp, ISPASYNC_LOOP_RESET, chan);
5806 #ifdef	ISP_TARGET_MODE
5807 			if (isp_target_async(isp, chan, mbox)) {
5808 				acked = 1;
5809 			}
5810 #endif
5811 		}
5812 		break;
5813 
5814 	case ASYNC_PDB_CHANGED:
5815 	{
5816 		int echan, nphdl, nlstate, reason;
5817 
5818 		if (IS_23XX(isp) || IS_24XX(isp)) {
5819 			nphdl = ISP_READ(isp, OUTMAILBOX1);
5820 			nlstate = ISP_READ(isp, OUTMAILBOX2);
5821 		} else {
5822 			nphdl = nlstate = 0xffff;
5823 		}
5824 		if (IS_24XX(isp))
5825 			reason = ISP_READ(isp, OUTMAILBOX3) >> 8;
5826 		else
5827 			reason = 0xff;
5828 		if (ISP_CAP_MULTI_ID(isp)) {
5829 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
5830 			if (chan == 0xff || nphdl == NIL_HANDLE) {
5831 				chan = 0;
5832 				echan = isp->isp_nchan - 1;
5833 			} else if (chan >= isp->isp_nchan) {
5834 				break;
5835 			} else {
5836 				echan = chan;
5837 			}
5838 		} else {
5839 			chan = echan = 0;
5840 		}
5841 		for (; chan <= echan; chan++) {
5842 			fcp = FCPARAM(isp, chan);
5843 			if (fcp->role == ISP_ROLE_NONE)
5844 				continue;
5845 			if (fcp->isp_loopstate > LOOP_LTEST_DONE)
5846 				fcp->isp_loopstate = LOOP_LTEST_DONE;
5847 			else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5848 				fcp->isp_loopstate = LOOP_HAVE_LINK;
5849 			isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5850 			    ISPASYNC_CHANGE_PDB, nphdl, nlstate, reason);
5851 		}
5852 		break;
5853 	}
5854 	case ASYNC_CHANGE_NOTIFY:
5855 	{
5856 		int portid;
5857 
5858 		portid = ((ISP_READ(isp, OUTMAILBOX1) & 0xff) << 16) |
5859 		    ISP_READ(isp, OUTMAILBOX2);
5860 		if (ISP_CAP_MULTI_ID(isp)) {
5861 			chan = ISP_READ(isp, OUTMAILBOX3) & 0xff;
5862 			if (chan >= isp->isp_nchan)
5863 				break;
5864 		} else {
5865 			chan = 0;
5866 		}
5867 		fcp = FCPARAM(isp, chan);
5868 		if (fcp->role == ISP_ROLE_NONE)
5869 			break;
5870 		if (fcp->isp_loopstate > LOOP_LTEST_DONE)
5871 			fcp->isp_loopstate = LOOP_LTEST_DONE;
5872 		else if (fcp->isp_loopstate < LOOP_HAVE_LINK)
5873 			fcp->isp_loopstate = LOOP_HAVE_LINK;
5874 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan,
5875 		    ISPASYNC_CHANGE_SNS, portid);
5876 		break;
5877 	}
5878 	case ASYNC_ERR_LOGGING_DISABLED:
5879 		isp_prt(isp, ISP_LOGWARN, "Error logging disabled (reason 0x%x)",
5880 		    ISP_READ(isp, OUTMAILBOX1));
5881 		break;
5882 	case ASYNC_CONNMODE:
5883 		/*
5884 		 * This only applies to 2100 amd 2200 cards
5885 		 */
5886 		if (!IS_2200(isp) && !IS_2100(isp)) {
5887 			isp_prt(isp, ISP_LOGWARN, "bad card for ASYNC_CONNMODE event");
5888 			break;
5889 		}
5890 		chan = 0;
5891 		mbox = ISP_READ(isp, OUTMAILBOX1);
5892 		switch (mbox) {
5893 		case ISP_CONN_LOOP:
5894 			isp_prt(isp, ISP_LOGINFO,
5895 			    "Point-to-Point -> Loop mode");
5896 			break;
5897 		case ISP_CONN_PTP:
5898 			isp_prt(isp, ISP_LOGINFO,
5899 			    "Loop -> Point-to-Point mode");
5900 			break;
5901 		case ISP_CONN_BADLIP:
5902 			isp_prt(isp, ISP_LOGWARN,
5903 			    "Point-to-Point -> Loop mode (BAD LIP)");
5904 			break;
5905 		case ISP_CONN_FATAL:
5906 			isp->isp_dead = 1;
5907 			isp->isp_state = ISP_CRASHED;
5908 			isp_prt(isp, ISP_LOGERR, "FATAL CONNECTION ERROR");
5909 			isp_async(isp, ISPASYNC_FW_CRASH);
5910 			return (-1);
5911 		case ISP_CONN_LOOPBACK:
5912 			isp_prt(isp, ISP_LOGWARN,
5913 			    "Looped Back in Point-to-Point mode");
5914 			break;
5915 		default:
5916 			isp_prt(isp, ISP_LOGWARN,
5917 			    "Unknown connection mode (0x%x)", mbox);
5918 			break;
5919 		}
5920 		ISP_SET_SENDMARKER(isp, chan, 1);
5921 		FCPARAM(isp, chan)->isp_loopstate = LOOP_HAVE_LINK;
5922 		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, chan, ISPASYNC_CHANGE_OTHER);
5923 		break;
5924 	case ASYNC_P2P_INIT_ERR:
5925 		isp_prt(isp, ISP_LOGWARN, "P2P init error (reason 0x%x)",
5926 		    ISP_READ(isp, OUTMAILBOX1));
5927 		break;
5928 	case ASYNC_RCV_ERR:
5929 		if (IS_24XX(isp)) {
5930 			isp_prt(isp, ISP_LOGWARN, "Receive Error");
5931 		} else {
5932 			isp_prt(isp, ISP_LOGWARN, "unexpected ASYNC_RCV_ERR");
5933 		}
5934 		break;
5935 	case ASYNC_RJT_SENT:	/* same as ASYNC_QFULL_SENT */
5936 		if (IS_24XX(isp)) {
5937 			isp_prt(isp, ISP_LOGTDEBUG0, "LS_RJT sent");
5938 			break;
5939 		} else {
5940 			isp_prt(isp, ISP_LOGTDEBUG0, "QFULL sent");
5941 			break;
5942 		}
5943 	case ASYNC_FW_RESTART_COMPLETE:
5944 		isp_prt(isp, ISP_LOGDEBUG0, "FW restart complete");
5945 		break;
5946 	case ASYNC_TEMPERATURE_ALERT:
5947 		isp_prt(isp, ISP_LOGERR, "Temperature alert (subcode 0x%x)",
5948 		    ISP_READ(isp, OUTMAILBOX1));
5949 		break;
5950 	case ASYNC_AUTOLOAD_FW_COMPLETE:
5951 		isp_prt(isp, ISP_LOGDEBUG0, "Autoload FW init complete");
5952 		break;
5953 	case ASYNC_AUTOLOAD_FW_FAILURE:
5954 		isp_prt(isp, ISP_LOGERR, "Autoload FW init failure");
5955 		break;
5956 	default:
5957 		isp_prt(isp, ISP_LOGWARN, "Unknown Async Code 0x%x", mbox);
5958 		break;
5959 	}
5960 	if (mbox != ASYNC_CTIO_DONE && mbox != ASYNC_CMD_CMPLT) {
5961 		isp->isp_intoasync++;
5962 	}
5963 	return (acked);
5964 }
5965 
5966 /*
5967  * Handle other response entries. A pointer to the request queue output
5968  * index is here in case we want to eat several entries at once, although
5969  * this is not used currently.
5970  */
5971 
5972 static int
5973 isp_handle_other_response(ispsoftc_t *isp, int type, isphdr_t *hp, uint32_t *optrp)
5974 {
5975 	isp_ridacq_t rid;
5976 	int chan, c;
5977 
5978 	switch (type) {
5979 	case RQSTYPE_STATUS_CONT:
5980 		isp_prt(isp, ISP_LOG_WARN1, "Ignored Continuation Response");
5981 		return (1);
5982 	case RQSTYPE_MARKER:
5983 		isp_prt(isp, ISP_LOG_WARN1, "Marker Response");
5984 		return (1);
5985 	case RQSTYPE_RPT_ID_ACQ:
5986 		isp_get_ridacq(isp, (isp_ridacq_t *)hp, &rid);
5987 		if (rid.ridacq_format == 0) {
5988 			for (chan = 0; chan < isp->isp_nchan; chan++) {
5989 				fcparam *fcp = FCPARAM(isp, chan);
5990 				if (fcp->role == ISP_ROLE_NONE)
5991 					continue;
5992 				c = (chan == 0) ? 127 : (chan - 1);
5993 				if (rid.ridacq_map[c / 16] & (1 << (c % 16)) ||
5994 				    chan == 0) {
5995 					fcp->isp_loopstate = LOOP_HAVE_LINK;
5996 					isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
5997 					    chan, ISPASYNC_CHANGE_OTHER);
5998 				} else {
5999 					fcp->isp_loopstate = LOOP_NIL;
6000 					isp_async(isp, ISPASYNC_LOOP_DOWN,
6001 					    chan);
6002 				}
6003 			}
6004 		} else {
6005 			fcparam *fcp = FCPARAM(isp, rid.ridacq_vp_index);
6006 			if (rid.ridacq_vp_status == RIDACQ_STS_COMPLETE ||
6007 			    rid.ridacq_vp_status == RIDACQ_STS_CHANGED) {
6008 				fcp->isp_loopstate = LOOP_HAVE_LINK;
6009 				isp_async(isp, ISPASYNC_CHANGE_NOTIFY,
6010 				    rid.ridacq_vp_index, ISPASYNC_CHANGE_OTHER);
6011 			} else {
6012 				fcp->isp_loopstate = LOOP_NIL;
6013 				isp_async(isp, ISPASYNC_LOOP_DOWN,
6014 				    rid.ridacq_vp_index);
6015 			}
6016 		}
6017 		return (1);
6018 	case RQSTYPE_ATIO:
6019 	case RQSTYPE_CTIO:
6020 	case RQSTYPE_ENABLE_LUN:
6021 	case RQSTYPE_MODIFY_LUN:
6022 	case RQSTYPE_NOTIFY:
6023 	case RQSTYPE_NOTIFY_ACK:
6024 	case RQSTYPE_CTIO1:
6025 	case RQSTYPE_ATIO2:
6026 	case RQSTYPE_CTIO2:
6027 	case RQSTYPE_CTIO3:
6028 	case RQSTYPE_CTIO7:
6029 	case RQSTYPE_ABTS_RCVD:
6030 	case RQSTYPE_ABTS_RSP:
6031 		isp->isp_rsltccmplt++;	/* count as a response completion */
6032 #ifdef	ISP_TARGET_MODE
6033 		if (isp_target_notify(isp, (ispstatusreq_t *) hp, optrp)) {
6034 			return (1);
6035 		}
6036 #endif
6037 		/* FALLTHROUGH */
6038 	case RQSTYPE_REQUEST:
6039 	default:
6040 		ISP_DELAY(100);
6041 		if (type != isp_get_response_type(isp, hp)) {
6042 			/*
6043 			 * This is questionable- we're just papering over
6044 			 * something we've seen on SMP linux in target
6045 			 * mode- we don't really know what's happening
6046 			 * here that causes us to think we've gotten
6047 			 * an entry, but that either the entry isn't
6048 			 * filled out yet or our CPU read data is stale.
6049 			 */
6050 			isp_prt(isp, ISP_LOGINFO,
6051 				"unstable type in response queue");
6052 			return (-1);
6053 		}
6054 		isp_prt(isp, ISP_LOGWARN, "Unhandled Response Type 0x%x",
6055 		    isp_get_response_type(isp, hp));
6056 		return (0);
6057 	}
6058 }
6059 
6060 static void
6061 isp_parse_status(ispsoftc_t *isp, ispstatusreq_t *sp, XS_T *xs, long *rp)
6062 {
6063 	switch (sp->req_completion_status & 0xff) {
6064 	case RQCS_COMPLETE:
6065 		if (XS_NOERR(xs)) {
6066 			XS_SETERR(xs, HBA_NOERROR);
6067 		}
6068 		return;
6069 
6070 	case RQCS_INCOMPLETE:
6071 		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
6072 			isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Selection Timeout @ %s:%d", __func__, __LINE__);
6073 			if (XS_NOERR(xs)) {
6074 				XS_SETERR(xs, HBA_SELTIMEOUT);
6075 				*rp = XS_XFRLEN(xs);
6076 			}
6077 			return;
6078 		}
6079 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Incomplete, state 0x%x", sp->req_state_flags);
6080 		break;
6081 
6082 	case RQCS_DMA_ERROR:
6083 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA Error");
6084 		*rp = XS_XFRLEN(xs);
6085 		break;
6086 
6087 	case RQCS_TRANSPORT_ERROR:
6088 	{
6089 		char buf[172];
6090 		ISP_SNPRINTF(buf, sizeof (buf), "states=>");
6091 		if (sp->req_state_flags & RQSF_GOT_BUS) {
6092 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_BUS", buf);
6093 		}
6094 		if (sp->req_state_flags & RQSF_GOT_TARGET) {
6095 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_TGT", buf);
6096 		}
6097 		if (sp->req_state_flags & RQSF_SENT_CDB) {
6098 			ISP_SNPRINTF(buf, sizeof (buf), "%s SENT_CDB", buf);
6099 		}
6100 		if (sp->req_state_flags & RQSF_XFRD_DATA) {
6101 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFRD_DATA", buf);
6102 		}
6103 		if (sp->req_state_flags & RQSF_GOT_STATUS) {
6104 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_STS", buf);
6105 		}
6106 		if (sp->req_state_flags & RQSF_GOT_SENSE) {
6107 			ISP_SNPRINTF(buf, sizeof (buf), "%s GOT_SNS", buf);
6108 		}
6109 		if (sp->req_state_flags & RQSF_XFER_COMPLETE) {
6110 			ISP_SNPRINTF(buf, sizeof (buf), "%s XFR_CMPLT", buf);
6111 		}
6112 		ISP_SNPRINTF(buf, sizeof (buf), "%s\nstatus=>", buf);
6113 		if (sp->req_status_flags & RQSTF_DISCONNECT) {
6114 			ISP_SNPRINTF(buf, sizeof (buf), "%s Disconnect", buf);
6115 		}
6116 		if (sp->req_status_flags & RQSTF_SYNCHRONOUS) {
6117 			ISP_SNPRINTF(buf, sizeof (buf), "%s Sync_xfr", buf);
6118 		}
6119 		if (sp->req_status_flags & RQSTF_PARITY_ERROR) {
6120 			ISP_SNPRINTF(buf, sizeof (buf), "%s Parity", buf);
6121 		}
6122 		if (sp->req_status_flags & RQSTF_BUS_RESET) {
6123 			ISP_SNPRINTF(buf, sizeof (buf), "%s Bus_Reset", buf);
6124 		}
6125 		if (sp->req_status_flags & RQSTF_DEVICE_RESET) {
6126 			ISP_SNPRINTF(buf, sizeof (buf), "%s Device_Reset", buf);
6127 		}
6128 		if (sp->req_status_flags & RQSTF_ABORTED) {
6129 			ISP_SNPRINTF(buf, sizeof (buf), "%s Aborted", buf);
6130 		}
6131 		if (sp->req_status_flags & RQSTF_TIMEOUT) {
6132 			ISP_SNPRINTF(buf, sizeof (buf), "%s Timeout", buf);
6133 		}
6134 		if (sp->req_status_flags & RQSTF_NEGOTIATION) {
6135 			ISP_SNPRINTF(buf, sizeof (buf), "%s Negotiation", buf);
6136 		}
6137 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error: %s", buf);
6138 		*rp = XS_XFRLEN(xs);
6139 		break;
6140 	}
6141 	case RQCS_RESET_OCCURRED:
6142 	{
6143 		int chan;
6144 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Bus Reset destroyed command");
6145 		for (chan = 0; chan < isp->isp_nchan; chan++) {
6146 			FCPARAM(isp, chan)->sendmarker = 1;
6147 		}
6148 		if (XS_NOERR(xs)) {
6149 			XS_SETERR(xs, HBA_BUSRESET);
6150 		}
6151 		*rp = XS_XFRLEN(xs);
6152 		return;
6153 	}
6154 	case RQCS_ABORTED:
6155 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6156 		ISP_SET_SENDMARKER(isp, XS_CHANNEL(xs), 1);
6157 		if (XS_NOERR(xs)) {
6158 			XS_SETERR(xs, HBA_ABORTED);
6159 		}
6160 		return;
6161 
6162 	case RQCS_TIMEOUT:
6163 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command timed out");
6164 		/*
6165 	 	 * XXX: Check to see if we logged out of the device.
6166 		 */
6167 		if (XS_NOERR(xs)) {
6168 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6169 		}
6170 		return;
6171 
6172 	case RQCS_DATA_OVERRUN:
6173 		XS_SET_RESID(xs, sp->req_resid);
6174 		isp_xs_prt(isp, xs, ISP_LOGERR, "data overrun (%ld)", (long) XS_GET_RESID(xs));
6175 		if (XS_NOERR(xs)) {
6176 			XS_SETERR(xs, HBA_DATAOVR);
6177 		}
6178 		return;
6179 
6180 	case RQCS_COMMAND_OVERRUN:
6181 		isp_xs_prt(isp, xs, ISP_LOGERR, "command overrun");
6182 		break;
6183 
6184 	case RQCS_STATUS_OVERRUN:
6185 		isp_xs_prt(isp, xs, ISP_LOGERR, "status overrun");
6186 		break;
6187 
6188 	case RQCS_BAD_MESSAGE:
6189 		isp_xs_prt(isp, xs, ISP_LOGERR, "msg not COMMAND COMPLETE after status");
6190 		break;
6191 
6192 	case RQCS_NO_MESSAGE_OUT:
6193 		isp_xs_prt(isp, xs, ISP_LOGERR, "No MESSAGE OUT phase after selection");
6194 		break;
6195 
6196 	case RQCS_EXT_ID_FAILED:
6197 		isp_xs_prt(isp, xs, ISP_LOGERR, "EXTENDED IDENTIFY failed");
6198 		break;
6199 
6200 	case RQCS_IDE_MSG_FAILED:
6201 		isp_xs_prt(isp, xs, ISP_LOGERR, "INITIATOR DETECTED ERROR rejected");
6202 		break;
6203 
6204 	case RQCS_ABORT_MSG_FAILED:
6205 		isp_xs_prt(isp, xs, ISP_LOGERR, "ABORT OPERATION rejected");
6206 		break;
6207 
6208 	case RQCS_REJECT_MSG_FAILED:
6209 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE REJECT rejected");
6210 		break;
6211 
6212 	case RQCS_NOP_MSG_FAILED:
6213 		isp_xs_prt(isp, xs, ISP_LOGERR, "NOP rejected");
6214 		break;
6215 
6216 	case RQCS_PARITY_ERROR_MSG_FAILED:
6217 		isp_xs_prt(isp, xs, ISP_LOGERR, "MESSAGE PARITY ERROR rejected");
6218 		break;
6219 
6220 	case RQCS_DEVICE_RESET_MSG_FAILED:
6221 		isp_xs_prt(isp, xs, ISP_LOGWARN, "BUS DEVICE RESET rejected");
6222 		break;
6223 
6224 	case RQCS_ID_MSG_FAILED:
6225 		isp_xs_prt(isp, xs, ISP_LOGERR, "IDENTIFY rejected");
6226 		break;
6227 
6228 	case RQCS_UNEXP_BUS_FREE:
6229 		isp_xs_prt(isp, xs, ISP_LOGERR, "Unexpected Bus Free");
6230 		break;
6231 
6232 	case RQCS_DATA_UNDERRUN:
6233 	{
6234 		if (IS_FC(isp)) {
6235 			int ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6236 			if (!ru_marked || sp->req_resid > XS_XFRLEN(xs)) {
6237 				isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6238 				if (XS_NOERR(xs)) {
6239 					XS_SETERR(xs, HBA_BOTCH);
6240 				}
6241 				return;
6242 			}
6243 		}
6244 		XS_SET_RESID(xs, sp->req_resid);
6245 		if (XS_NOERR(xs)) {
6246 			XS_SETERR(xs, HBA_NOERROR);
6247 		}
6248 		return;
6249 	}
6250 
6251 	case RQCS_XACT_ERR1:
6252 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued transaction with disconnect not set");
6253 		break;
6254 
6255 	case RQCS_XACT_ERR2:
6256 		isp_xs_prt(isp, xs, ISP_LOGERR,
6257 		    "HBA attempted queued transaction to target routine %jx",
6258 		    (uintmax_t)XS_LUN(xs));
6259 		break;
6260 
6261 	case RQCS_XACT_ERR3:
6262 		isp_xs_prt(isp, xs, ISP_LOGERR, "HBA attempted queued cmd when queueing disabled");
6263 		break;
6264 
6265 	case RQCS_BAD_ENTRY:
6266 		isp_prt(isp, ISP_LOGERR, "Invalid IOCB entry type detected");
6267 		break;
6268 
6269 	case RQCS_QUEUE_FULL:
6270 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "internal queues full status 0x%x", *XS_STSP(xs));
6271 
6272 		/*
6273 		 * If QFULL or some other status byte is set, then this
6274 		 * isn't an error, per se.
6275 		 *
6276 		 * Unfortunately, some QLogic f/w writers have, in
6277 		 * some cases, ommitted to *set* status to QFULL.
6278 		 */
6279 #if	0
6280 		if (*XS_STSP(xs) != SCSI_GOOD && XS_NOERR(xs)) {
6281 			XS_SETERR(xs, HBA_NOERROR);
6282 			return;
6283 		}
6284 
6285 #endif
6286 		*XS_STSP(xs) = SCSI_QFULL;
6287 		XS_SETERR(xs, HBA_NOERROR);
6288 		return;
6289 
6290 	case RQCS_PHASE_SKIPPED:
6291 		isp_xs_prt(isp, xs, ISP_LOGERR, "SCSI phase skipped");
6292 		break;
6293 
6294 	case RQCS_ARQS_FAILED:
6295 		isp_xs_prt(isp, xs, ISP_LOGERR, "Auto Request Sense Failed");
6296 		if (XS_NOERR(xs)) {
6297 			XS_SETERR(xs, HBA_ARQFAIL);
6298 		}
6299 		return;
6300 
6301 	case RQCS_WIDE_FAILED:
6302 		isp_xs_prt(isp, xs, ISP_LOGERR, "Wide Negotiation Failed");
6303 		if (IS_SCSI(isp)) {
6304 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6305 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_WIDE;
6306 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6307 			sdp->update = 1;
6308 		}
6309 		if (XS_NOERR(xs)) {
6310 			XS_SETERR(xs, HBA_NOERROR);
6311 		}
6312 		return;
6313 
6314 	case RQCS_SYNCXFER_FAILED:
6315 		isp_xs_prt(isp, xs, ISP_LOGERR, "SDTR Message Failed");
6316 		if (IS_SCSI(isp)) {
6317 			sdparam *sdp = SDPARAM(isp, XS_CHANNEL(xs));
6318 			sdp += XS_CHANNEL(xs);
6319 			sdp->isp_devparam[XS_TGT(xs)].goal_flags &= ~DPARM_SYNC;
6320 			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
6321 			sdp->update = 1;
6322 		}
6323 		break;
6324 
6325 	case RQCS_LVD_BUSERR:
6326 		isp_xs_prt(isp, xs, ISP_LOGERR, "Bad LVD condition");
6327 		break;
6328 
6329 	case RQCS_PORT_UNAVAILABLE:
6330 		/*
6331 		 * No such port on the loop. Moral equivalent of SELTIMEO
6332 		 */
6333 	case RQCS_PORT_LOGGED_OUT:
6334 	{
6335 		const char *reason;
6336 		uint8_t sts = sp->req_completion_status & 0xff;
6337 
6338 		/*
6339 		 * It was there (maybe)- treat as a selection timeout.
6340 		 */
6341 		if (sts == RQCS_PORT_UNAVAILABLE) {
6342 			reason = "unavailable";
6343 		} else {
6344 			reason = "logout";
6345 		}
6346 
6347 		isp_prt(isp, ISP_LOGINFO, "port %s for target %d", reason, XS_TGT(xs));
6348 
6349 		/*
6350 		 * If we're on a local loop, force a LIP (which is overkill)
6351 		 * to force a re-login of this unit. If we're on fabric,
6352 		 * then we'll have to log in again as a matter of course.
6353 		 */
6354 		if (FCPARAM(isp, 0)->isp_topo == TOPO_NL_PORT ||
6355 		    FCPARAM(isp, 0)->isp_topo == TOPO_FL_PORT) {
6356 			mbreg_t mbs;
6357 			MBSINIT(&mbs, MBOX_INIT_LIP, MBLOGALL, 0);
6358 			if (ISP_CAP_2KLOGIN(isp)) {
6359 				mbs.ibits = (1 << 10);
6360 			}
6361 			isp_mboxcmd_qnw(isp, &mbs, 1);
6362 		}
6363 		if (XS_NOERR(xs)) {
6364 			XS_SETERR(xs, HBA_SELTIMEOUT);
6365 		}
6366 		return;
6367 	}
6368 	case RQCS_PORT_CHANGED:
6369 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d", XS_TGT(xs));
6370 		if (XS_NOERR(xs)) {
6371 			XS_SETERR(xs, HBA_SELTIMEOUT);
6372 		}
6373 		return;
6374 
6375 	case RQCS_PORT_BUSY:
6376 		isp_prt(isp, ISP_LOGWARN, "port busy for target %d", XS_TGT(xs));
6377 		if (XS_NOERR(xs)) {
6378 			XS_SETERR(xs, HBA_TGTBSY);
6379 		}
6380 		return;
6381 
6382 	default:
6383 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x", sp->req_completion_status);
6384 		break;
6385 	}
6386 	if (XS_NOERR(xs)) {
6387 		XS_SETERR(xs, HBA_BOTCH);
6388 	}
6389 }
6390 
6391 static void
6392 isp_parse_status_24xx(ispsoftc_t *isp, isp24xx_statusreq_t *sp, XS_T *xs, long *rp)
6393 {
6394 	int ru_marked, sv_marked;
6395 	int chan = XS_CHANNEL(xs);
6396 
6397 	switch (sp->req_completion_status) {
6398 	case RQCS_COMPLETE:
6399 		if (XS_NOERR(xs)) {
6400 			XS_SETERR(xs, HBA_NOERROR);
6401 		}
6402 		return;
6403 
6404 	case RQCS_DMA_ERROR:
6405 		isp_xs_prt(isp, xs, ISP_LOGERR, "DMA error");
6406 		break;
6407 
6408 	case RQCS_TRANSPORT_ERROR:
6409 		isp_xs_prt(isp, xs,  ISP_LOGERR, "Transport Error");
6410 		break;
6411 
6412 	case RQCS_RESET_OCCURRED:
6413 		isp_xs_prt(isp, xs, ISP_LOGWARN, "reset destroyed command");
6414 		FCPARAM(isp, chan)->sendmarker = 1;
6415 		if (XS_NOERR(xs)) {
6416 			XS_SETERR(xs, HBA_BUSRESET);
6417 		}
6418 		return;
6419 
6420 	case RQCS_ABORTED:
6421 		isp_xs_prt(isp, xs, ISP_LOGERR, "Command Aborted");
6422 		FCPARAM(isp, chan)->sendmarker = 1;
6423 		if (XS_NOERR(xs)) {
6424 			XS_SETERR(xs, HBA_ABORTED);
6425 		}
6426 		return;
6427 
6428 	case RQCS_TIMEOUT:
6429 		isp_xs_prt(isp, xs, ISP_LOGWARN, "Command Timed Out");
6430 		if (XS_NOERR(xs)) {
6431 			XS_SETERR(xs, HBA_CMDTIMEOUT);
6432 		}
6433 		return;
6434 
6435 	case RQCS_DATA_OVERRUN:
6436 		XS_SET_RESID(xs, sp->req_resid);
6437 		isp_xs_prt(isp, xs, ISP_LOGERR, "Data Overrun");
6438 		if (XS_NOERR(xs)) {
6439 			XS_SETERR(xs, HBA_DATAOVR);
6440 		}
6441 		return;
6442 
6443 	case RQCS_24XX_DRE:	/* data reassembly error */
6444 		isp_prt(isp, ISP_LOGERR, "Chan %d data reassembly error for target %d", chan, XS_TGT(xs));
6445 		if (XS_NOERR(xs)) {
6446 			XS_SETERR(xs, HBA_ABORTED);
6447 		}
6448 		*rp = XS_XFRLEN(xs);
6449 		return;
6450 
6451 	case RQCS_24XX_TABORT:	/* aborted by target */
6452 		isp_prt(isp, ISP_LOGERR, "Chan %d target %d sent ABTS", chan, XS_TGT(xs));
6453 		if (XS_NOERR(xs)) {
6454 			XS_SETERR(xs, HBA_ABORTED);
6455 		}
6456 		return;
6457 
6458 	case RQCS_DATA_UNDERRUN:
6459 		ru_marked = (sp->req_scsi_status & RQCS_RU) != 0;
6460 		/*
6461 		 * We can get an underrun w/o things being marked
6462 		 * if we got a non-zero status.
6463 		 */
6464 		sv_marked = (sp->req_scsi_status & (RQCS_SV|RQCS_RV)) != 0;
6465 		if ((ru_marked == 0 && sv_marked == 0) ||
6466 		    (sp->req_resid > XS_XFRLEN(xs))) {
6467 			isp_xs_prt(isp, xs, ISP_LOGWARN, bun, XS_XFRLEN(xs), sp->req_resid, (ru_marked)? "marked" : "not marked");
6468 			if (XS_NOERR(xs)) {
6469 				XS_SETERR(xs, HBA_BOTCH);
6470 			}
6471 			return;
6472 		}
6473 		XS_SET_RESID(xs, sp->req_resid);
6474 		isp_xs_prt(isp, xs, ISP_LOG_WARN1, "Data Underrun (%d) for command 0x%x", sp->req_resid, XS_CDBP(xs)[0] & 0xff);
6475 		if (XS_NOERR(xs)) {
6476 			XS_SETERR(xs, HBA_NOERROR);
6477 		}
6478 		return;
6479 
6480 	case RQCS_PORT_UNAVAILABLE:
6481 		/*
6482 		 * No such port on the loop. Moral equivalent of SELTIMEO
6483 		 */
6484 	case RQCS_PORT_LOGGED_OUT:
6485 	{
6486 		const char *reason;
6487 		uint8_t sts = sp->req_completion_status & 0xff;
6488 
6489 		/*
6490 		 * It was there (maybe)- treat as a selection timeout.
6491 		 */
6492 		if (sts == RQCS_PORT_UNAVAILABLE) {
6493 			reason = "unavailable";
6494 		} else {
6495 			reason = "logout";
6496 		}
6497 
6498 		isp_prt(isp, ISP_LOGINFO, "Chan %d port %s for target %d",
6499 		    chan, reason, XS_TGT(xs));
6500 
6501 		/*
6502 		 * There is no MBOX_INIT_LIP for the 24XX.
6503 		 */
6504 		if (XS_NOERR(xs)) {
6505 			XS_SETERR(xs, HBA_SELTIMEOUT);
6506 		}
6507 		return;
6508 	}
6509 	case RQCS_PORT_CHANGED:
6510 		isp_prt(isp, ISP_LOGWARN, "port changed for target %d chan %d", XS_TGT(xs), chan);
6511 		if (XS_NOERR(xs)) {
6512 			XS_SETERR(xs, HBA_SELTIMEOUT);
6513 		}
6514 		return;
6515 
6516 
6517 	case RQCS_24XX_ENOMEM:	/* f/w resource unavailable */
6518 		isp_prt(isp, ISP_LOGWARN, "f/w resource unavailable for target %d chan %d", XS_TGT(xs), chan);
6519 		if (XS_NOERR(xs)) {
6520 			*XS_STSP(xs) = SCSI_BUSY;
6521 			XS_SETERR(xs, HBA_TGTBSY);
6522 		}
6523 		return;
6524 
6525 	case RQCS_24XX_TMO:	/* task management overrun */
6526 		isp_prt(isp, ISP_LOGWARN, "command for target %d overlapped task management for chan %d", XS_TGT(xs), chan);
6527 		if (XS_NOERR(xs)) {
6528 			*XS_STSP(xs) = SCSI_BUSY;
6529 			XS_SETERR(xs, HBA_TGTBSY);
6530 		}
6531 		return;
6532 
6533 	default:
6534 		isp_prt(isp, ISP_LOGERR, "Unknown Completion Status 0x%x on chan %d", sp->req_completion_status, chan);
6535 		break;
6536 	}
6537 	if (XS_NOERR(xs)) {
6538 		XS_SETERR(xs, HBA_BOTCH);
6539 	}
6540 }
6541 
6542 static void
6543 isp_fastpost_complete(ispsoftc_t *isp, uint32_t fph)
6544 {
6545 	XS_T *xs;
6546 
6547 	if (fph == 0) {
6548 		return;
6549 	}
6550 	xs = isp_find_xs(isp, fph);
6551 	if (xs == NULL) {
6552 		isp_prt(isp, ISP_LOGWARN,
6553 		    "Command for fast post handle 0x%x not found", fph);
6554 		return;
6555 	}
6556 	isp_destroy_handle(isp, fph);
6557 
6558 	/*
6559 	 * Since we don't have a result queue entry item,
6560 	 * we must believe that SCSI status is zero and
6561 	 * that all data transferred.
6562 	 */
6563 	XS_SET_RESID(xs, 0);
6564 	*XS_STSP(xs) = SCSI_GOOD;
6565 	if (XS_XFRLEN(xs)) {
6566 		ISP_DMAFREE(isp, xs, fph);
6567 	}
6568 	if (isp->isp_nactive) {
6569 		isp->isp_nactive--;
6570 	}
6571 	isp->isp_fphccmplt++;
6572 	isp_done(xs);
6573 }
6574 
6575 static int
6576 isp_mbox_continue(ispsoftc_t *isp)
6577 {
6578 	mbreg_t mbs;
6579 	uint16_t *ptr;
6580 	uint32_t offset;
6581 
6582 	switch (isp->isp_lastmbxcmd) {
6583 	case MBOX_WRITE_RAM_WORD:
6584 	case MBOX_READ_RAM_WORD:
6585 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6586 	case MBOX_READ_RAM_WORD_EXTENDED:
6587 		break;
6588 	default:
6589 		return (1);
6590 	}
6591 	if (isp->isp_mboxtmp[0] != MBOX_COMMAND_COMPLETE) {
6592 		isp->isp_mbxwrk0 = 0;
6593 		return (-1);
6594 	}
6595 
6596 	/*
6597 	 * Clear the previous interrupt.
6598 	 */
6599 	if (IS_24XX(isp)) {
6600 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_CLEAR_RISC_INT);
6601 	} else {
6602 		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
6603 		ISP_WRITE(isp, BIU_SEMA, 0);
6604 	}
6605 
6606 	/*
6607 	 * Continue with next word.
6608 	 */
6609 	ISP_MEMZERO(&mbs, sizeof (mbs));
6610 	ptr = isp->isp_mbxworkp;
6611 	switch (isp->isp_lastmbxcmd) {
6612 	case MBOX_WRITE_RAM_WORD:
6613 		mbs.param[1] = isp->isp_mbxwrk1++;
6614 		mbs.param[2] = *ptr++;
6615 		break;
6616 	case MBOX_READ_RAM_WORD:
6617 		*ptr++ = isp->isp_mboxtmp[2];
6618 		mbs.param[1] = isp->isp_mbxwrk1++;
6619 		break;
6620 	case MBOX_WRITE_RAM_WORD_EXTENDED:
6621 		if (IS_24XX(isp)) {
6622 			uint32_t *lptr = (uint32_t *)ptr;
6623 			mbs.param[2] = lptr[0];
6624 			mbs.param[3] = lptr[0] >> 16;
6625 			lptr++;
6626 			ptr = (uint16_t *)lptr;
6627 		} else {
6628 			mbs.param[2] = *ptr++;
6629 		}
6630 		offset = isp->isp_mbxwrk1;
6631 		offset |= isp->isp_mbxwrk8 << 16;
6632 		mbs.param[1] = offset;
6633 		mbs.param[8] = offset >> 16;
6634 		offset++;
6635 		isp->isp_mbxwrk1 = offset;
6636 		isp->isp_mbxwrk8 = offset >> 16;
6637 		break;
6638 	case MBOX_READ_RAM_WORD_EXTENDED:
6639 		if (IS_24XX(isp)) {
6640 			uint32_t *lptr = (uint32_t *)ptr;
6641 			uint32_t val = isp->isp_mboxtmp[2];
6642 			val |= (isp->isp_mboxtmp[3]) << 16;
6643 			*lptr++ = val;
6644 			ptr = (uint16_t *)lptr;
6645 		} else {
6646 			*ptr++ = isp->isp_mboxtmp[2];
6647 		}
6648 		offset = isp->isp_mbxwrk1;
6649 		offset |= isp->isp_mbxwrk8 << 16;
6650 		mbs.param[1] = offset;
6651 		mbs.param[8] = offset >> 16;
6652 		offset++;
6653 		isp->isp_mbxwrk1 = offset;
6654 		isp->isp_mbxwrk8 = offset >> 16;
6655 		break;
6656 	}
6657 	isp->isp_mbxworkp = ptr;
6658 	isp->isp_mbxwrk0--;
6659 	mbs.param[0] = isp->isp_lastmbxcmd;
6660 	mbs.logval = MBLOGALL;
6661 	isp_mboxcmd_qnw(isp, &mbs, 0);
6662 	return (0);
6663 }
6664 
6665 #define	ISP_SCSI_IBITS(op)		(mbpscsi[((op)<<1)])
6666 #define	ISP_SCSI_OBITS(op)		(mbpscsi[((op)<<1) + 1])
6667 #define	ISP_SCSI_OPMAP(in, out)		in, out
6668 static const uint8_t mbpscsi[] = {
6669 	ISP_SCSI_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6670 	ISP_SCSI_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6671 	ISP_SCSI_OPMAP(0x03, 0x01),	/* 0x02: MBOX_EXEC_FIRMWARE */
6672 	ISP_SCSI_OPMAP(0x1f, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6673 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6674 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6675 	ISP_SCSI_OPMAP(0x3f, 0x3f),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6676 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6677 	ISP_SCSI_OPMAP(0x01, 0x0f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6678 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x09: */
6679 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0a: */
6680 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0b: */
6681 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0c: */
6682 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0d: */
6683 	ISP_SCSI_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6684 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x0f: */
6685 	ISP_SCSI_OPMAP(0x1f, 0x1f),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6686 	ISP_SCSI_OPMAP(0x3f, 0x3f),	/* 0x11: MBOX_INIT_RES_QUEUE */
6687 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x12: MBOX_EXECUTE_IOCB */
6688 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6689 	ISP_SCSI_OPMAP(0x01, 0x3f),	/* 0x14: MBOX_STOP_FIRMWARE */
6690 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x15: MBOX_ABORT */
6691 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x16: MBOX_ABORT_DEVICE */
6692 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x17: MBOX_ABORT_TARGET */
6693 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x18: MBOX_BUS_RESET */
6694 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x19: MBOX_STOP_QUEUE */
6695 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1a: MBOX_START_QUEUE */
6696 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6697 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x1c: MBOX_ABORT_QUEUE */
6698 	ISP_SCSI_OPMAP(0x03, 0x4f),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6699 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x1e: */
6700 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6701 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x20: MBOX_GET_INIT_SCSI_ID */
6702 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
6703 	ISP_SCSI_OPMAP(0x01, 0xc7),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6704 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
6705 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x24: MBOX_GET_CLOCK_RATE */
6706 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
6707 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
6708 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x27: MBOX_GET_PCI_PARAMS */
6709 	ISP_SCSI_OPMAP(0x03, 0x4f),	/* 0x28: MBOX_GET_TARGET_PARAMS */
6710 	ISP_SCSI_OPMAP(0x03, 0x0f),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
6711 	ISP_SCSI_OPMAP(0x01, 0x07),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
6712 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2b: */
6713 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2c: */
6714 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2d: */
6715 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2e: */
6716 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x2f: */
6717 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
6718 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
6719 	ISP_SCSI_OPMAP(0xc7, 0xc7),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6720 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
6721 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x34: MBOX_SET_CLOCK_RATE */
6722 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
6723 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
6724 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
6725 	ISP_SCSI_OPMAP(0x4f, 0x4f),	/* 0x38: MBOX_SET_TARGET_PARAMS */
6726 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
6727 	ISP_SCSI_OPMAP(0x07, 0x07),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
6728 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3b: */
6729 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3c: */
6730 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3d: */
6731 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3e: */
6732 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x3f: */
6733 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
6734 	ISP_SCSI_OPMAP(0x3f, 0x01),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
6735 	ISP_SCSI_OPMAP(0x03, 0x07),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
6736 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x43: */
6737 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x44: */
6738 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x45: SET SYSTEM PARAMETER */
6739 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x46: GET SYSTEM PARAMETER */
6740 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x47: */
6741 	ISP_SCSI_OPMAP(0x01, 0xcf),	/* 0x48: GET SCAM CONFIGURATION */
6742 	ISP_SCSI_OPMAP(0xcf, 0xcf),	/* 0x49: SET SCAM CONFIGURATION */
6743 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
6744 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
6745 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4c: */
6746 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4d: */
6747 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4e: */
6748 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x4f: */
6749 	ISP_SCSI_OPMAP(0xdf, 0xdf),	/* 0x50: LOAD RAM A64 */
6750 	ISP_SCSI_OPMAP(0xdf, 0xdf),	/* 0x51: DUMP RAM A64 */
6751 	ISP_SCSI_OPMAP(0xdf, 0xff),	/* 0x52: INITIALIZE REQUEST QUEUE A64 */
6752 	ISP_SCSI_OPMAP(0xef, 0xff),	/* 0x53: INITIALIZE RESPONSE QUEUE A64 */
6753 	ISP_SCSI_OPMAP(0xcf, 0x01),	/* 0x54: EXECUCUTE COMMAND IOCB A64 */
6754 	ISP_SCSI_OPMAP(0x07, 0x01),	/* 0x55: ENABLE TARGET MODE */
6755 	ISP_SCSI_OPMAP(0x03, 0x0f),	/* 0x56: GET TARGET STATUS */
6756 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x57: */
6757 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x58: */
6758 	ISP_SCSI_OPMAP(0x00, 0x00),	/* 0x59: */
6759 	ISP_SCSI_OPMAP(0x03, 0x03),	/* 0x5a: SET DATA OVERRUN RECOVERY MODE */
6760 	ISP_SCSI_OPMAP(0x01, 0x03),	/* 0x5b: GET DATA OVERRUN RECOVERY MODE */
6761 	ISP_SCSI_OPMAP(0x0f, 0x0f),	/* 0x5c: SET HOST DATA */
6762 	ISP_SCSI_OPMAP(0x01, 0x01)	/* 0x5d: GET NOST DATA */
6763 };
6764 #define	MAX_SCSI_OPCODE	0x5d
6765 
6766 static const char *scsi_mbcmd_names[] = {
6767 	"NO-OP",
6768 	"LOAD RAM",
6769 	"EXEC FIRMWARE",
6770 	"DUMP RAM",
6771 	"WRITE RAM WORD",
6772 	"READ RAM WORD",
6773 	"MAILBOX REG TEST",
6774 	"VERIFY CHECKSUM",
6775 	"ABOUT FIRMWARE",
6776 	NULL,
6777 	NULL,
6778 	NULL,
6779 	NULL,
6780 	NULL,
6781 	"CHECK FIRMWARE",
6782 	NULL,
6783 	"INIT REQUEST QUEUE",
6784 	"INIT RESULT QUEUE",
6785 	"EXECUTE IOCB",
6786 	"WAKE UP",
6787 	"STOP FIRMWARE",
6788 	"ABORT",
6789 	"ABORT DEVICE",
6790 	"ABORT TARGET",
6791 	"BUS RESET",
6792 	"STOP QUEUE",
6793 	"START QUEUE",
6794 	"SINGLE STEP QUEUE",
6795 	"ABORT QUEUE",
6796 	"GET DEV QUEUE STATUS",
6797 	NULL,
6798 	"GET FIRMWARE STATUS",
6799 	"GET INIT SCSI ID",
6800 	"GET SELECT TIMEOUT",
6801 	"GET RETRY COUNT",
6802 	"GET TAG AGE LIMIT",
6803 	"GET CLOCK RATE",
6804 	"GET ACT NEG STATE",
6805 	"GET ASYNC DATA SETUP TIME",
6806 	"GET PCI PARAMS",
6807 	"GET TARGET PARAMS",
6808 	"GET DEV QUEUE PARAMS",
6809 	"GET RESET DELAY PARAMS",
6810 	NULL,
6811 	NULL,
6812 	NULL,
6813 	NULL,
6814 	NULL,
6815 	"SET INIT SCSI ID",
6816 	"SET SELECT TIMEOUT",
6817 	"SET RETRY COUNT",
6818 	"SET TAG AGE LIMIT",
6819 	"SET CLOCK RATE",
6820 	"SET ACT NEG STATE",
6821 	"SET ASYNC DATA SETUP TIME",
6822 	"SET PCI CONTROL PARAMS",
6823 	"SET TARGET PARAMS",
6824 	"SET DEV QUEUE PARAMS",
6825 	"SET RESET DELAY PARAMS",
6826 	NULL,
6827 	NULL,
6828 	NULL,
6829 	NULL,
6830 	NULL,
6831 	"RETURN BIOS BLOCK ADDR",
6832 	"WRITE FOUR RAM WORDS",
6833 	"EXEC BIOS IOCB",
6834 	NULL,
6835 	NULL,
6836 	"SET SYSTEM PARAMETER",
6837 	"GET SYSTEM PARAMETER",
6838 	NULL,
6839 	"GET SCAM CONFIGURATION",
6840 	"SET SCAM CONFIGURATION",
6841 	"SET FIRMWARE FEATURES",
6842 	"GET FIRMWARE FEATURES",
6843 	NULL,
6844 	NULL,
6845 	NULL,
6846 	NULL,
6847 	"LOAD RAM A64",
6848 	"DUMP RAM A64",
6849 	"INITIALIZE REQUEST QUEUE A64",
6850 	"INITIALIZE RESPONSE QUEUE A64",
6851 	"EXECUTE IOCB A64",
6852 	"ENABLE TARGET MODE",
6853 	"GET TARGET MODE STATE",
6854 	NULL,
6855 	NULL,
6856 	NULL,
6857 	"SET DATA OVERRUN RECOVERY MODE",
6858 	"GET DATA OVERRUN RECOVERY MODE",
6859 	"SET HOST DATA",
6860 	"GET NOST DATA",
6861 };
6862 
6863 #define	ISP_FC_IBITS(op)	((mbpfc[((op)<<3) + 0] << 24) | (mbpfc[((op)<<3) + 1] << 16) | (mbpfc[((op)<<3) + 2] << 8) | (mbpfc[((op)<<3) + 3]))
6864 #define	ISP_FC_OBITS(op)	((mbpfc[((op)<<3) + 4] << 24) | (mbpfc[((op)<<3) + 5] << 16) | (mbpfc[((op)<<3) + 6] << 8) | (mbpfc[((op)<<3) + 7]))
6865 
6866 #define	ISP_FC_OPMAP(in0, out0)							  0,   0,   0, in0,    0,    0,    0, out0
6867 #define	ISP_FC_OPMAP_HALF(in1, in0, out1, out0)					  0,   0, in1, in0,    0,    0, out1, out0
6868 #define	ISP_FC_OPMAP_FULL(in3, in2, in1, in0, out3, out2, out1, out0)		in3, in2, in1, in0, out3, out2, out1, out0
6869 static const uint32_t mbpfc[] = {
6870 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x00: MBOX_NO_OP */
6871 	ISP_FC_OPMAP(0x1f, 0x01),	/* 0x01: MBOX_LOAD_RAM */
6872 	ISP_FC_OPMAP_HALF(0x07, 0xff, 0x00, 0x03),	/* 0x02: MBOX_EXEC_FIRMWARE */
6873 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x03: MBOX_DUMP_RAM */
6874 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x04: MBOX_WRITE_RAM_WORD */
6875 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x05: MBOX_READ_RAM_WORD */
6876 	ISP_FC_OPMAP_FULL(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff),	/* 0x06: MBOX_MAILBOX_REG_TEST */
6877 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
6878 	ISP_FC_OPMAP_FULL(0x0, 0x0, 0x0, 0x01, 0x0, 0x3, 0x80, 0x7f),	/* 0x08: MBOX_ABOUT_FIRMWARE */
6879 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x09: MBOX_LOAD_RISC_RAM_2100 */
6880 	ISP_FC_OPMAP(0xdf, 0x01),	/* 0x0a: DUMP RAM */
6881 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x01),	/* 0x0b: MBOX_LOAD_RISC_RAM */
6882 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x0c: */
6883 	ISP_FC_OPMAP_HALF(0x1, 0x0f, 0x0, 0x01),	/* 0x0d: MBOX_WRITE_RAM_WORD_EXTENDED */
6884 	ISP_FC_OPMAP(0x01, 0x05),	/* 0x0e: MBOX_CHECK_FIRMWARE */
6885 	ISP_FC_OPMAP_HALF(0x1, 0x03, 0x0, 0x0d),	/* 0x0f: MBOX_READ_RAM_WORD_EXTENDED */
6886 	ISP_FC_OPMAP(0x1f, 0x11),	/* 0x10: MBOX_INIT_REQ_QUEUE */
6887 	ISP_FC_OPMAP(0x2f, 0x21),	/* 0x11: MBOX_INIT_RES_QUEUE */
6888 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x12: MBOX_EXECUTE_IOCB */
6889 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x13: MBOX_WAKE_UP	*/
6890 	ISP_FC_OPMAP_HALF(0x1, 0xff, 0x0, 0x03),	/* 0x14: MBOX_STOP_FIRMWARE */
6891 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x15: MBOX_ABORT */
6892 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x16: MBOX_ABORT_DEVICE */
6893 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x17: MBOX_ABORT_TARGET */
6894 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x18: MBOX_BUS_RESET */
6895 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x19: MBOX_STOP_QUEUE */
6896 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1a: MBOX_START_QUEUE */
6897 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
6898 	ISP_FC_OPMAP(0x07, 0x05),	/* 0x1c: MBOX_ABORT_QUEUE */
6899 	ISP_FC_OPMAP(0x07, 0x03),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
6900 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x1e: */
6901 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
6902 	ISP_FC_OPMAP_HALF(0x2, 0x01, 0x7e, 0xcf),	/* 0x20: MBOX_GET_LOOP_ID */
6903 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x21: */
6904 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
6905 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x23: */
6906 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x24: */
6907 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x25: */
6908 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x26: */
6909 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x27: */
6910 	ISP_FC_OPMAP(0x01, 0x03),	/* 0x28: MBOX_GET_FIRMWARE_OPTIONS */
6911 	ISP_FC_OPMAP(0x03, 0x07),	/* 0x29: MBOX_GET_PORT_QUEUE_PARAMS */
6912 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2a: */
6913 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2b: */
6914 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2c: */
6915 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2d: */
6916 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2e: */
6917 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x2f: */
6918 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x30: */
6919 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x31: */
6920 	ISP_FC_OPMAP(0x07, 0x07),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
6921 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x33: */
6922 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x34: */
6923 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x35: */
6924 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x36: */
6925 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x37: */
6926 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x38: MBOX_SET_FIRMWARE_OPTIONS */
6927 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x39: MBOX_SET_PORT_QUEUE_PARAMS */
6928 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3a: */
6929 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3b: */
6930 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3c: */
6931 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3d: */
6932 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3e: */
6933 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x3f: */
6934 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x40: MBOX_LOOP_PORT_BYPASS */
6935 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x41: MBOX_LOOP_PORT_ENABLE */
6936 	ISP_FC_OPMAP_HALF(0x0, 0x01, 0x3, 0xcf),	/* 0x42: MBOX_GET_RESOURCE_COUNT */
6937 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x43: MBOX_REQUEST_OFFLINE_MODE */
6938 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x44: */
6939 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x45: */
6940 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x46: */
6941 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x47: GET PORT_DATABASE ENHANCED */
6942 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x48: MBOX_INIT_FIRMWARE_MULTI_ID */
6943 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x49: MBOX_GET_VP_DATABASE */
6944 	ISP_FC_OPMAP_HALF(0x2, 0xcd, 0x0, 0x01),	/* 0x4a: MBOX_GET_VP_DATABASE_ENTRY */
6945 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4b: */
6946 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4c: */
6947 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4d: */
6948 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4e: */
6949 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x4f: */
6950 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x50: */
6951 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x51: */
6952 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x52: */
6953 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x53: */
6954 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x54: EXECUTE IOCB A64 */
6955 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x55: */
6956 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x56: */
6957 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x57: */
6958 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x58: */
6959 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x59: */
6960 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5a: */
6961 	ISP_FC_OPMAP(0x03, 0x01),	/* 0x5b: MBOX_DRIVER_HEARTBEAT */
6962 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x5c: MBOX_FW_HEARTBEAT */
6963 	ISP_FC_OPMAP(0x07, 0x1f),	/* 0x5d: MBOX_GET_SET_DATA_RATE */
6964 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5e: */
6965 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x5f: */
6966 	ISP_FC_OPMAP(0xcf, 0x0f),	/* 0x60: MBOX_INIT_FIRMWARE */
6967 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x61: */
6968 	ISP_FC_OPMAP(0x01, 0x01),	/* 0x62: MBOX_INIT_LIP */
6969 	ISP_FC_OPMAP(0xcd, 0x03),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
6970 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x64: MBOX_GET_PORT_DB */
6971 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x65: MBOX_CLEAR_ACA */
6972 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x66: MBOX_TARGET_RESET */
6973 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x67: MBOX_CLEAR_TASK_SET */
6974 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x68: MBOX_ABORT_TASK_SET */
6975 	ISP_FC_OPMAP(0x01, 0x07),	/* 0x69: MBOX_GET_FW_STATE */
6976 	ISP_FC_OPMAP_HALF(0x6, 0x03, 0x0, 0xcf),	/* 0x6a: MBOX_GET_PORT_NAME */
6977 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x6b: MBOX_GET_LINK_STATUS */
6978 	ISP_FC_OPMAP(0x0f, 0x01),	/* 0x6c: MBOX_INIT_LIP_RESET */
6979 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x6d: */
6980 	ISP_FC_OPMAP(0xcf, 0x03),	/* 0x6e: MBOX_SEND_SNS */
6981 	ISP_FC_OPMAP(0x0f, 0x07),	/* 0x6f: MBOX_FABRIC_LOGIN */
6982 	ISP_FC_OPMAP_HALF(0x02, 0x03, 0x00, 0x03),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
6983 	ISP_FC_OPMAP(0x03, 0x03),	/* 0x71: MBOX_FABRIC_LOGOUT */
6984 	ISP_FC_OPMAP(0x0f, 0x0f),	/* 0x72: MBOX_INIT_LIP_LOGIN */
6985 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x73: */
6986 	ISP_FC_OPMAP(0x07, 0x01),	/* 0x74: LOGIN LOOP PORT */
6987 	ISP_FC_OPMAP_HALF(0x03, 0xcf, 0x00, 0x07),	/* 0x75: GET PORT/NODE NAME LIST */
6988 	ISP_FC_OPMAP(0x4f, 0x01),	/* 0x76: SET VENDOR ID */
6989 	ISP_FC_OPMAP(0xcd, 0x01),	/* 0x77: INITIALIZE IP MAILBOX */
6990 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x78: */
6991 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x79: */
6992 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7a: */
6993 	ISP_FC_OPMAP(0x00, 0x00),	/* 0x7b: */
6994 	ISP_FC_OPMAP_HALF(0x03, 0x4f, 0x00, 0x07),	/* 0x7c: Get ID List */
6995 	ISP_FC_OPMAP(0xcf, 0x01),	/* 0x7d: SEND LFA */
6996 	ISP_FC_OPMAP(0x0f, 0x01)	/* 0x7e: LUN RESET */
6997 };
6998 #define	MAX_FC_OPCODE	0x7e
6999 /*
7000  * Footnotes
7001  *
7002  * (1): this sets bits 21..16 in mailbox register #8, which we nominally
7003  *	do not access at this time in the core driver. The caller is
7004  *	responsible for setting this register first (Gross!). The assumption
7005  *	is that we won't overflow.
7006  */
7007 
7008 static const char *fc_mbcmd_names[] = {
7009 	"NO-OP",			/* 00h */
7010 	"LOAD RAM",
7011 	"EXEC FIRMWARE",
7012 	"DUMP RAM",
7013 	"WRITE RAM WORD",
7014 	"READ RAM WORD",
7015 	"MAILBOX REG TEST",
7016 	"VERIFY CHECKSUM",
7017 	"ABOUT FIRMWARE",
7018 	"LOAD RAM (2100)",
7019 	"DUMP RAM",
7020 	"LOAD RISC RAM",
7021 	"DUMP RISC RAM",
7022 	"WRITE RAM WORD EXTENDED",
7023 	"CHECK FIRMWARE",
7024 	"READ RAM WORD EXTENDED",
7025 	"INIT REQUEST QUEUE",		/* 10h */
7026 	"INIT RESULT QUEUE",
7027 	"EXECUTE IOCB",
7028 	"WAKE UP",
7029 	"STOP FIRMWARE",
7030 	"ABORT",
7031 	"ABORT DEVICE",
7032 	"ABORT TARGET",
7033 	"BUS RESET",
7034 	"STOP QUEUE",
7035 	"START QUEUE",
7036 	"SINGLE STEP QUEUE",
7037 	"ABORT QUEUE",
7038 	"GET DEV QUEUE STATUS",
7039 	NULL,
7040 	"GET FIRMWARE STATUS",
7041 	"GET LOOP ID",			/* 20h */
7042 	NULL,
7043 	"GET TIMEOUT PARAMS",
7044 	NULL,
7045 	NULL,
7046 	NULL,
7047 	NULL,
7048 	NULL,
7049 	"GET FIRMWARE OPTIONS",
7050 	"GET PORT QUEUE PARAMS",
7051 	"GENERATE SYSTEM ERROR",
7052 	NULL,
7053 	NULL,
7054 	NULL,
7055 	NULL,
7056 	NULL,
7057 	"WRITE SFP",			/* 30h */
7058 	"READ SFP",
7059 	"SET TIMEOUT PARAMS",
7060 	NULL,
7061 	NULL,
7062 	NULL,
7063 	NULL,
7064 	NULL,
7065 	"SET FIRMWARE OPTIONS",
7066 	"SET PORT QUEUE PARAMS",
7067 	NULL,
7068 	"SET FC LED CONF",
7069 	NULL,
7070 	"RESTART NIC FIRMWARE",
7071 	"ACCESS CONTROL",
7072 	NULL,
7073 	"LOOP PORT BYPASS",		/* 40h */
7074 	"LOOP PORT ENABLE",
7075 	"GET RESOURCE COUNT",
7076 	"REQUEST NON PARTICIPATING MODE",
7077 	"DIAGNOSTIC ECHO TEST",
7078 	"DIAGNOSTIC LOOPBACK",
7079 	NULL,
7080 	"GET PORT DATABASE ENHANCED",
7081 	"INIT FIRMWARE MULTI ID",
7082 	"GET VP DATABASE",
7083 	"GET VP DATABASE ENTRY",
7084 	NULL,
7085 	NULL,
7086 	NULL,
7087 	NULL,
7088 	NULL,
7089 	"GET FCF LIST",			/* 50h */
7090 	"GET DCBX PARAMETERS",
7091 	NULL,
7092 	"HOST MEMORY COPY",
7093 	"EXECUTE IOCB A64",
7094 	NULL,
7095 	NULL,
7096 	"SEND RNID",
7097 	NULL,
7098 	"SET PARAMETERS",
7099 	"GET PARAMETERS",
7100 	"DRIVER HEARTBEAT",
7101 	"FIRMWARE HEARTBEAT",
7102 	"GET/SET DATA RATE",
7103 	"SEND RNFT",
7104 	NULL,
7105 	"INIT FIRMWARE",		/* 60h */
7106 	"GET INIT CONTROL BLOCK",
7107 	"INIT LIP",
7108 	"GET FC-AL POSITION MAP",
7109 	"GET PORT DATABASE",
7110 	"CLEAR ACA",
7111 	"TARGET RESET",
7112 	"CLEAR TASK SET",
7113 	"ABORT TASK SET",
7114 	"GET FW STATE",
7115 	"GET PORT NAME",
7116 	"GET LINK STATUS",
7117 	"INIT LIP RESET",
7118 	"GET LINK STATS & PRIVATE DATA CNTS",
7119 	"SEND SNS",
7120 	"FABRIC LOGIN",
7121 	"SEND CHANGE REQUEST",		/* 70h */
7122 	"FABRIC LOGOUT",
7123 	"INIT LIP LOGIN",
7124 	NULL,
7125 	"LOGIN LOOP PORT",
7126 	"GET PORT/NODE NAME LIST",
7127 	"SET VENDOR ID",
7128 	"INITIALIZE IP MAILBOX",
7129 	NULL,
7130 	NULL,
7131 	"GET XGMAC STATS",
7132 	NULL,
7133 	"GET ID LIST",
7134 	"SEND LFA",
7135 	"LUN RESET"
7136 };
7137 
7138 static void
7139 isp_mboxcmd_qnw(ispsoftc_t *isp, mbreg_t *mbp, int nodelay)
7140 {
7141 	unsigned int ibits, obits, box, opcode;
7142 
7143 	opcode = mbp->param[0];
7144 	if (IS_FC(isp)) {
7145 		ibits = ISP_FC_IBITS(opcode);
7146 		obits = ISP_FC_OBITS(opcode);
7147 	} else {
7148 		ibits = ISP_SCSI_IBITS(opcode);
7149 		obits = ISP_SCSI_OBITS(opcode);
7150 	}
7151 	ibits |= mbp->ibits;
7152 	obits |= mbp->obits;
7153 	for (box = 0; box < ISP_NMBOX(isp); box++) {
7154 		if (ibits & (1 << box)) {
7155 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7156 		}
7157 		if (nodelay == 0) {
7158 			isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7159 		}
7160 	}
7161 	if (nodelay == 0) {
7162 		isp->isp_lastmbxcmd = opcode;
7163 		isp->isp_obits = obits;
7164 		isp->isp_mboxbsy = 1;
7165 	}
7166 	if (IS_24XX(isp)) {
7167 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7168 	} else {
7169 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7170 	}
7171 	/*
7172 	 * Oddly enough, if we're not delaying for an answer,
7173 	 * delay a bit to give the f/w a chance to pick up the
7174 	 * command.
7175 	 */
7176 	if (nodelay) {
7177 		ISP_DELAY(1000);
7178 	}
7179 }
7180 
7181 static void
7182 isp_mboxcmd(ispsoftc_t *isp, mbreg_t *mbp)
7183 {
7184 	const char *cname, *xname, *sname;
7185 	char tname[16], mname[16];
7186 	unsigned int ibits, obits, box, opcode;
7187 
7188 	opcode = mbp->param[0];
7189 	if (IS_FC(isp)) {
7190 		if (opcode > MAX_FC_OPCODE) {
7191 			mbp->param[0] = MBOX_INVALID_COMMAND;
7192 			isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7193 			return;
7194 		}
7195 		cname = fc_mbcmd_names[opcode];
7196 		ibits = ISP_FC_IBITS(opcode);
7197 		obits = ISP_FC_OBITS(opcode);
7198 	} else {
7199 		if (opcode > MAX_SCSI_OPCODE) {
7200 			mbp->param[0] = MBOX_INVALID_COMMAND;
7201 			isp_prt(isp, ISP_LOGERR, "Unknown Command 0x%x", opcode);
7202 			return;
7203 		}
7204 		cname = scsi_mbcmd_names[opcode];
7205 		ibits = ISP_SCSI_IBITS(opcode);
7206 		obits = ISP_SCSI_OBITS(opcode);
7207 	}
7208 	if (cname == NULL) {
7209 		cname = tname;
7210 		ISP_SNPRINTF(tname, sizeof tname, "opcode %x", opcode);
7211 	}
7212 	isp_prt(isp, ISP_LOGDEBUG3, "Mailbox Command '%s'", cname);
7213 
7214 	/*
7215 	 * Pick up any additional bits that the caller might have set.
7216 	 */
7217 	ibits |= mbp->ibits;
7218 	obits |= mbp->obits;
7219 
7220 	/*
7221 	 * Mask any bits that the caller wants us to mask
7222 	 */
7223 	ibits &= mbp->ibitm;
7224 	obits &= mbp->obitm;
7225 
7226 
7227 	if (ibits == 0 && obits == 0) {
7228 		mbp->param[0] = MBOX_COMMAND_PARAM_ERROR;
7229 		isp_prt(isp, ISP_LOGERR, "no parameters for 0x%x", opcode);
7230 		return;
7231 	}
7232 
7233 	/*
7234 	 * Get exclusive usage of mailbox registers.
7235 	 */
7236 	if (MBOX_ACQUIRE(isp)) {
7237 		mbp->param[0] = MBOX_REGS_BUSY;
7238 		goto out;
7239 	}
7240 
7241 	for (box = 0; box < ISP_NMBOX(isp); box++) {
7242 		if (ibits & (1 << box)) {
7243 			isp_prt(isp, ISP_LOGDEBUG3, "IN mbox %d = 0x%04x", box,
7244 			    mbp->param[box]);
7245 			ISP_WRITE(isp, MBOX_OFF(box), mbp->param[box]);
7246 		}
7247 		isp->isp_mboxtmp[box] = mbp->param[box] = 0;
7248 	}
7249 
7250 	isp->isp_lastmbxcmd = opcode;
7251 
7252 	/*
7253 	 * We assume that we can't overwrite a previous command.
7254 	 */
7255 	isp->isp_obits = obits;
7256 	isp->isp_mboxbsy = 1;
7257 
7258 	/*
7259 	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
7260 	 */
7261 	if (IS_24XX(isp)) {
7262 		ISP_WRITE(isp, BIU2400_HCCR, HCCR_2400_CMD_SET_HOST_INT);
7263 	} else {
7264 		ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
7265 	}
7266 
7267 	/*
7268 	 * While we haven't finished the command, spin our wheels here.
7269 	 */
7270 	MBOX_WAIT_COMPLETE(isp, mbp);
7271 
7272 	/*
7273 	 * Did the command time out?
7274 	 */
7275 	if (mbp->param[0] == MBOX_TIMEOUT) {
7276 		isp->isp_mboxbsy = 0;
7277 		MBOX_RELEASE(isp);
7278 		goto out;
7279 	}
7280 
7281 	/*
7282 	 * Copy back output registers.
7283 	 */
7284 	for (box = 0; box < ISP_NMBOX(isp); box++) {
7285 		if (obits & (1 << box)) {
7286 			mbp->param[box] = isp->isp_mboxtmp[box];
7287 			isp_prt(isp, ISP_LOGDEBUG3, "OUT mbox %d = 0x%04x", box,
7288 			    mbp->param[box]);
7289 		}
7290 	}
7291 
7292 	isp->isp_mboxbsy = 0;
7293 	MBOX_RELEASE(isp);
7294 out:
7295 	if (mbp->logval == 0 || mbp->param[0] == MBOX_COMMAND_COMPLETE)
7296 		return;
7297 
7298 	if ((mbp->param[0] & 0xbfe0) == 0 &&
7299 	    (mbp->logval & MBLOGMASK(mbp->param[0])) == 0)
7300 		return;
7301 
7302 	xname = NULL;
7303 	sname = "";
7304 	switch (mbp->param[0]) {
7305 	case MBOX_INVALID_COMMAND:
7306 		xname = "INVALID COMMAND";
7307 		break;
7308 	case MBOX_HOST_INTERFACE_ERROR:
7309 		xname = "HOST INTERFACE ERROR";
7310 		break;
7311 	case MBOX_TEST_FAILED:
7312 		xname = "TEST FAILED";
7313 		break;
7314 	case MBOX_COMMAND_ERROR:
7315 		xname = "COMMAND ERROR";
7316 		ISP_SNPRINTF(mname, sizeof(mname), " subcode 0x%x",
7317 		    mbp->param[1]);
7318 		sname = mname;
7319 		break;
7320 	case MBOX_COMMAND_PARAM_ERROR:
7321 		xname = "COMMAND PARAMETER ERROR";
7322 		break;
7323 	case MBOX_PORT_ID_USED:
7324 		xname = "PORT ID ALREADY IN USE";
7325 		break;
7326 	case MBOX_LOOP_ID_USED:
7327 		xname = "LOOP ID ALREADY IN USE";
7328 		break;
7329 	case MBOX_ALL_IDS_USED:
7330 		xname = "ALL LOOP IDS IN USE";
7331 		break;
7332 	case MBOX_NOT_LOGGED_IN:
7333 		xname = "NOT LOGGED IN";
7334 		break;
7335 	case MBOX_LINK_DOWN_ERROR:
7336 		xname = "LINK DOWN ERROR";
7337 		break;
7338 	case MBOX_LOOPBACK_ERROR:
7339 		xname = "LOOPBACK ERROR";
7340 		break;
7341 	case MBOX_CHECKSUM_ERROR:
7342 		xname = "CHECKSUM ERROR";
7343 		break;
7344 	case MBOX_INVALID_PRODUCT_KEY:
7345 		xname = "INVALID PRODUCT KEY";
7346 		break;
7347 	case MBOX_REGS_BUSY:
7348 		xname = "REGISTERS BUSY";
7349 		break;
7350 	case MBOX_TIMEOUT:
7351 		xname = "TIMEOUT";
7352 		break;
7353 	default:
7354 		ISP_SNPRINTF(mname, sizeof mname, "error 0x%x", mbp->param[0]);
7355 		xname = mname;
7356 		break;
7357 	}
7358 	if (xname) {
7359 		isp_prt(isp, ISP_LOGALL, "Mailbox Command '%s' failed (%s%s)",
7360 		    cname, xname, sname);
7361 	}
7362 }
7363 
7364 static int
7365 isp_fw_state(ispsoftc_t *isp, int chan)
7366 {
7367 	if (IS_FC(isp)) {
7368 		mbreg_t mbs;
7369 
7370 		MBSINIT(&mbs, MBOX_GET_FW_STATE, MBLOGALL, 0);
7371 		isp_mboxcmd(isp, &mbs);
7372 		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
7373 			return (mbs.param[1]);
7374 		}
7375 	}
7376 	return (FW_ERROR);
7377 }
7378 
7379 static void
7380 isp_spi_update(ispsoftc_t *isp, int chan)
7381 {
7382 	int tgt;
7383 	mbreg_t mbs;
7384 	sdparam *sdp;
7385 
7386 	if (IS_FC(isp)) {
7387 		/*
7388 		 * There are no 'per-bus' settings for Fibre Channel.
7389 		 */
7390 		return;
7391 	}
7392 	sdp = SDPARAM(isp, chan);
7393 	sdp->update = 0;
7394 
7395 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7396 		uint16_t flags, period, offset;
7397 		int get;
7398 
7399 		if (sdp->isp_devparam[tgt].dev_enable == 0) {
7400 			sdp->isp_devparam[tgt].dev_update = 0;
7401 			sdp->isp_devparam[tgt].dev_refresh = 0;
7402 			isp_prt(isp, ISP_LOGDEBUG0, "skipping target %d bus %d update", tgt, chan);
7403 			continue;
7404 		}
7405 		/*
7406 		 * If the goal is to update the status of the device,
7407 		 * take what's in goal_flags and try and set the device
7408 		 * toward that. Otherwise, if we're just refreshing the
7409 		 * current device state, get the current parameters.
7410 		 */
7411 
7412 		MBSINIT(&mbs, 0, MBLOGALL, 0);
7413 
7414 		/*
7415 		 * Refresh overrides set
7416 		 */
7417 		if (sdp->isp_devparam[tgt].dev_refresh) {
7418 			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
7419 			get = 1;
7420 		} else if (sdp->isp_devparam[tgt].dev_update) {
7421 			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
7422 
7423 			/*
7424 			 * Make sure goal_flags has "Renegotiate on Error"
7425 			 * on and "Freeze Queue on Error" off.
7426 			 */
7427 			sdp->isp_devparam[tgt].goal_flags |= DPARM_RENEG;
7428 			sdp->isp_devparam[tgt].goal_flags &= ~DPARM_QFRZ;
7429 			mbs.param[2] = sdp->isp_devparam[tgt].goal_flags;
7430 
7431 			/*
7432 			 * Insist that PARITY must be enabled
7433 			 * if SYNC or WIDE is enabled.
7434 			 */
7435 			if ((mbs.param[2] & (DPARM_SYNC|DPARM_WIDE)) != 0) {
7436 				mbs.param[2] |= DPARM_PARITY;
7437 			}
7438 
7439 			if (mbs.param[2] & DPARM_SYNC) {
7440 				mbs.param[3] =
7441 				    (sdp->isp_devparam[tgt].goal_offset << 8) |
7442 				    (sdp->isp_devparam[tgt].goal_period);
7443 			}
7444 			/*
7445 			 * A command completion later that has
7446 			 * RQSTF_NEGOTIATION set can cause
7447 			 * the dev_refresh/announce cycle also.
7448 			 *
7449 			 * Note: It is really important to update our current
7450 			 * flags with at least the state of TAG capabilities-
7451 			 * otherwise we might try and send a tagged command
7452 			 * when we have it all turned off. So change it here
7453 			 * to say that current already matches goal.
7454 			 */
7455 			sdp->isp_devparam[tgt].actv_flags &= ~DPARM_TQING;
7456 			sdp->isp_devparam[tgt].actv_flags |=
7457 			    (sdp->isp_devparam[tgt].goal_flags & DPARM_TQING);
7458 			isp_prt(isp, ISP_LOGDEBUG0, "bus %d set tgt %d flags 0x%x off 0x%x period 0x%x",
7459 			    chan, tgt, mbs.param[2], mbs.param[3] >> 8, mbs.param[3] & 0xff);
7460 			get = 0;
7461 		} else {
7462 			continue;
7463 		}
7464 		mbs.param[1] = (chan << 15) | (tgt << 8);
7465 		isp_mboxcmd(isp, &mbs);
7466 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7467 			continue;
7468 		}
7469 		if (get == 0) {
7470 			sdp->sendmarker = 1;
7471 			sdp->isp_devparam[tgt].dev_update = 0;
7472 			sdp->isp_devparam[tgt].dev_refresh = 1;
7473 		} else {
7474 			sdp->isp_devparam[tgt].dev_refresh = 0;
7475 			flags = mbs.param[2];
7476 			period = mbs.param[3] & 0xff;
7477 			offset = mbs.param[3] >> 8;
7478 			sdp->isp_devparam[tgt].actv_flags = flags;
7479 			sdp->isp_devparam[tgt].actv_period = period;
7480 			sdp->isp_devparam[tgt].actv_offset = offset;
7481 			isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, chan, tgt);
7482 		}
7483 	}
7484 
7485 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7486 		if (sdp->isp_devparam[tgt].dev_update ||
7487 		    sdp->isp_devparam[tgt].dev_refresh) {
7488 			sdp->update = 1;
7489 			break;
7490 		}
7491 	}
7492 }
7493 
7494 static void
7495 isp_setdfltsdparm(ispsoftc_t *isp)
7496 {
7497 	int tgt;
7498 	sdparam *sdp, *sdp1;
7499 
7500 	sdp = SDPARAM(isp, 0);
7501 	if (IS_DUALBUS(isp))
7502 		sdp1 = sdp + 1;
7503 	else
7504 		sdp1 = NULL;
7505 
7506 	/*
7507 	 * Establish some default parameters.
7508 	 */
7509 	sdp->isp_cmd_dma_burst_enable = 0;
7510 	sdp->isp_data_dma_burst_enabl = 1;
7511 	sdp->isp_fifo_threshold = 0;
7512 	sdp->isp_initiator_id = DEFAULT_IID(isp, 0);
7513 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7514 		sdp->isp_async_data_setup = 9;
7515 	} else {
7516 		sdp->isp_async_data_setup = 6;
7517 	}
7518 	sdp->isp_selection_timeout = 250;
7519 	sdp->isp_max_queue_depth = MAXISPREQUEST(isp);
7520 	sdp->isp_tag_aging = 8;
7521 	sdp->isp_bus_reset_delay = 5;
7522 	/*
7523 	 * Don't retry selection, busy or queue full automatically- reflect
7524 	 * these back to us.
7525 	 */
7526 	sdp->isp_retry_count = 0;
7527 	sdp->isp_retry_delay = 0;
7528 
7529 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7530 		sdp->isp_devparam[tgt].exc_throttle = ISP_EXEC_THROTTLE;
7531 		sdp->isp_devparam[tgt].dev_enable = 1;
7532 	}
7533 
7534 	/*
7535 	 * The trick here is to establish a default for the default (honk!)
7536 	 * state (goal_flags). Then try and get the current status from
7537 	 * the card to fill in the current state. We don't, in fact, set
7538 	 * the default to the SAFE default state- that's not the goal state.
7539 	 */
7540 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
7541 		uint8_t off, per;
7542 		sdp->isp_devparam[tgt].actv_offset = 0;
7543 		sdp->isp_devparam[tgt].actv_period = 0;
7544 		sdp->isp_devparam[tgt].actv_flags = 0;
7545 
7546 		sdp->isp_devparam[tgt].goal_flags =
7547 		    sdp->isp_devparam[tgt].nvrm_flags = DPARM_DEFAULT;
7548 
7549 		/*
7550 		 * We default to Wide/Fast for versions less than a 1040
7551 		 * (unless it's SBus).
7552 		 */
7553 		if (IS_ULTRA3(isp)) {
7554 			off = ISP_80M_SYNCPARMS >> 8;
7555 			per = ISP_80M_SYNCPARMS & 0xff;
7556 		} else if (IS_ULTRA2(isp)) {
7557 			off = ISP_40M_SYNCPARMS >> 8;
7558 			per = ISP_40M_SYNCPARMS & 0xff;
7559 		} else if (IS_1240(isp)) {
7560 			off = ISP_20M_SYNCPARMS >> 8;
7561 			per = ISP_20M_SYNCPARMS & 0xff;
7562 		} else if ((isp->isp_bustype == ISP_BT_SBUS &&
7563 		    isp->isp_type < ISP_HA_SCSI_1020A) ||
7564 		    (isp->isp_bustype == ISP_BT_PCI &&
7565 		    isp->isp_type < ISP_HA_SCSI_1040) ||
7566 		    (isp->isp_clock && isp->isp_clock < 60) ||
7567 		    (sdp->isp_ultramode == 0)) {
7568 			off = ISP_10M_SYNCPARMS >> 8;
7569 			per = ISP_10M_SYNCPARMS & 0xff;
7570 		} else {
7571 			off = ISP_20M_SYNCPARMS_1040 >> 8;
7572 			per = ISP_20M_SYNCPARMS_1040 & 0xff;
7573 		}
7574 		sdp->isp_devparam[tgt].goal_offset =
7575 		    sdp->isp_devparam[tgt].nvrm_offset = off;
7576 		sdp->isp_devparam[tgt].goal_period =
7577 		    sdp->isp_devparam[tgt].nvrm_period = per;
7578 
7579 	}
7580 
7581 	/*
7582 	 * If we're a dual bus card, just copy the data over
7583 	 */
7584 	if (sdp1) {
7585 		*sdp1 = *sdp;
7586 		sdp1->isp_initiator_id = DEFAULT_IID(isp, 1);
7587 	}
7588 
7589 	/*
7590 	 * If we've not been told to avoid reading NVRAM, try and read it.
7591 	 * If we're successful reading it, we can then return because NVRAM
7592 	 * will tell us what the desired settings are. Otherwise, we establish
7593 	 * some reasonable 'fake' nvram and goal defaults.
7594 	 */
7595 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7596 		mbreg_t mbs;
7597 
7598 		if (isp_read_nvram(isp, 0) == 0) {
7599 			if (IS_DUALBUS(isp)) {
7600 				if (isp_read_nvram(isp, 1) == 0) {
7601 					return;
7602 				}
7603 			}
7604 		}
7605 		MBSINIT(&mbs, MBOX_GET_ACT_NEG_STATE, MBLOGNONE, 0);
7606 		isp_mboxcmd(isp, &mbs);
7607 		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
7608 			sdp->isp_req_ack_active_neg = 1;
7609 			sdp->isp_data_line_active_neg = 1;
7610 			if (sdp1) {
7611 				sdp1->isp_req_ack_active_neg = 1;
7612 				sdp1->isp_data_line_active_neg = 1;
7613 			}
7614 		} else {
7615 			sdp->isp_req_ack_active_neg =
7616 			    (mbs.param[1] >> 4) & 0x1;
7617 			sdp->isp_data_line_active_neg =
7618 			    (mbs.param[1] >> 5) & 0x1;
7619 			if (sdp1) {
7620 				sdp1->isp_req_ack_active_neg =
7621 				    (mbs.param[2] >> 4) & 0x1;
7622 				sdp1->isp_data_line_active_neg =
7623 				    (mbs.param[2] >> 5) & 0x1;
7624 			}
7625 		}
7626 	}
7627 
7628 }
7629 
7630 static void
7631 isp_setdfltfcparm(ispsoftc_t *isp, int chan)
7632 {
7633 	fcparam *fcp = FCPARAM(isp, chan);
7634 
7635 	/*
7636 	 * Establish some default parameters.
7637 	 */
7638 	fcp->role = DEFAULT_ROLE(isp, chan);
7639 	fcp->isp_maxalloc = ICB_DFLT_ALLOC;
7640 	fcp->isp_retry_delay = ICB_DFLT_RDELAY;
7641 	fcp->isp_retry_count = ICB_DFLT_RCOUNT;
7642 	fcp->isp_loopid = DEFAULT_LOOPID(isp, chan);
7643 	fcp->isp_wwnn_nvram = DEFAULT_NODEWWN(isp, chan);
7644 	fcp->isp_wwpn_nvram = DEFAULT_PORTWWN(isp, chan);
7645 	fcp->isp_fwoptions = 0;
7646 	fcp->isp_xfwoptions = 0;
7647 	fcp->isp_zfwoptions = 0;
7648 	fcp->isp_lasthdl = NIL_HANDLE;
7649 
7650 	if (IS_24XX(isp)) {
7651 		fcp->isp_fwoptions |= ICB2400_OPT1_FAIRNESS;
7652 		fcp->isp_fwoptions |= ICB2400_OPT1_HARD_ADDRESS;
7653 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7654 			fcp->isp_fwoptions |= ICB2400_OPT1_FULL_DUPLEX;
7655 		}
7656 		fcp->isp_fwoptions |= ICB2400_OPT1_BOTH_WWNS;
7657 		fcp->isp_zfwoptions |= ICB2400_OPT3_RATE_AUTO;
7658 	} else {
7659 		fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
7660 		fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
7661 		fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
7662 		if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX) {
7663 			fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
7664 		}
7665 		/*
7666 		 * Make sure this is turned off now until we get
7667 		 * extended options from NVRAM
7668 		 */
7669 		fcp->isp_fwoptions &= ~ICBOPT_EXTENDED;
7670 		fcp->isp_zfwoptions |= ICBZOPT_RATE_AUTO;
7671 	}
7672 
7673 
7674 	/*
7675 	 * Now try and read NVRAM unless told to not do so.
7676 	 * This will set fcparam's isp_wwnn_nvram && isp_wwpn_nvram.
7677 	 */
7678 	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
7679 		int i, j = 0;
7680 		/*
7681 		 * Give a couple of tries at reading NVRAM.
7682 		 */
7683 		for (i = 0; i < 2; i++) {
7684 			j = isp_read_nvram(isp, chan);
7685 			if (j == 0) {
7686 				break;
7687 			}
7688 		}
7689 		if (j) {
7690 			isp->isp_confopts |= ISP_CFG_NONVRAM;
7691 		}
7692 	}
7693 
7694 	fcp->isp_wwnn = ACTIVE_NODEWWN(isp, chan);
7695 	fcp->isp_wwpn = ACTIVE_PORTWWN(isp, chan);
7696 	isp_prt(isp, ISP_LOGCONFIG, "Chan %d 0x%08x%08x/0x%08x%08x Role %s",
7697 	    chan, (uint32_t) (fcp->isp_wwnn >> 32), (uint32_t) (fcp->isp_wwnn),
7698 	    (uint32_t) (fcp->isp_wwpn >> 32), (uint32_t) (fcp->isp_wwpn),
7699 	    isp_class3_roles[fcp->role]);
7700 }
7701 
7702 /*
7703  * Re-initialize the ISP and complete all orphaned commands
7704  * with a 'botched' notice. The reset/init routines should
7705  * not disturb an already active list of commands.
7706  */
7707 
7708 int
7709 isp_reinit(ispsoftc_t *isp, int do_load_defaults)
7710 {
7711 	int i, res = 0;
7712 
7713 	if (isp->isp_state == ISP_RUNSTATE)
7714 		isp_deinit(isp);
7715 	if (isp->isp_state != ISP_RESETSTATE)
7716 		isp_reset(isp, do_load_defaults);
7717 	if (isp->isp_state != ISP_RESETSTATE) {
7718 		res = EIO;
7719 		isp_prt(isp, ISP_LOGERR, "%s: cannot reset card", __func__);
7720 		ISP_DISABLE_INTS(isp);
7721 		goto cleanup;
7722 	}
7723 
7724 	isp_init(isp);
7725 	if (isp->isp_state > ISP_RESETSTATE &&
7726 	    isp->isp_state != ISP_RUNSTATE) {
7727 		res = EIO;
7728 		isp_prt(isp, ISP_LOGERR, "%s: cannot init card", __func__);
7729 		ISP_DISABLE_INTS(isp);
7730 		if (IS_FC(isp)) {
7731 			/*
7732 			 * If we're in ISP_ROLE_NONE, turn off the lasers.
7733 			 */
7734 			if (!IS_24XX(isp)) {
7735 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FPM0_REGS);
7736 				ISP_WRITE(isp, FPM_DIAG_CONFIG, FPM_SOFT_RESET);
7737 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_FB_REGS);
7738 				ISP_WRITE(isp, FBM_CMD, FBMCMD_FIFO_RESET_ALL);
7739 				ISP_WRITE(isp, BIU2100_CSR, BIU2100_RISC_REGS);
7740 			}
7741 		}
7742 	}
7743 
7744 cleanup:
7745 	isp->isp_nactive = 0;
7746 	isp_clear_commands(isp);
7747 	if (IS_FC(isp)) {
7748 		for (i = 0; i < isp->isp_nchan; i++)
7749 			isp_clear_portdb(isp, i);
7750 	}
7751 	return (res);
7752 }
7753 
7754 /*
7755  * NVRAM Routines
7756  */
7757 static int
7758 isp_read_nvram(ispsoftc_t *isp, int bus)
7759 {
7760 	int i, amt, retval;
7761 	uint8_t csum, minversion;
7762 	union {
7763 		uint8_t _x[ISP2400_NVRAM_SIZE];
7764 		uint16_t _s[ISP2400_NVRAM_SIZE>>1];
7765 	} _n;
7766 #define	nvram_data	_n._x
7767 #define	nvram_words	_n._s
7768 
7769 	if (IS_24XX(isp)) {
7770 		return (isp_read_nvram_2400(isp, nvram_data));
7771 	} else if (IS_FC(isp)) {
7772 		amt = ISP2100_NVRAM_SIZE;
7773 		minversion = 1;
7774 	} else if (IS_ULTRA2(isp)) {
7775 		amt = ISP1080_NVRAM_SIZE;
7776 		minversion = 0;
7777 	} else {
7778 		amt = ISP_NVRAM_SIZE;
7779 		minversion = 2;
7780 	}
7781 
7782 	for (i = 0; i < amt>>1; i++) {
7783 		isp_rdnvram_word(isp, i, &nvram_words[i]);
7784 	}
7785 
7786 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7787 	    nvram_data[2] != 'P') {
7788 		if (isp->isp_bustype != ISP_BT_SBUS) {
7789 			isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header");
7790 			isp_prt(isp, ISP_LOGDEBUG0, "%x %x %x", nvram_data[0], nvram_data[1], nvram_data[2]);
7791 		}
7792 		retval = -1;
7793 		goto out;
7794 	}
7795 
7796 	for (csum = 0, i = 0; i < amt; i++) {
7797 		csum += nvram_data[i];
7798 	}
7799 	if (csum != 0) {
7800 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7801 		retval = -1;
7802 		goto out;
7803 	}
7804 
7805 	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
7806 		isp_prt(isp, ISP_LOGWARN, "version %d NVRAM not understood",
7807 		    ISP_NVRAM_VERSION(nvram_data));
7808 		retval = -1;
7809 		goto out;
7810 	}
7811 
7812 	if (IS_ULTRA3(isp)) {
7813 		isp_parse_nvram_12160(isp, bus, nvram_data);
7814 	} else if (IS_1080(isp)) {
7815 		isp_parse_nvram_1080(isp, bus, nvram_data);
7816 	} else if (IS_1280(isp) || IS_1240(isp)) {
7817 		isp_parse_nvram_1080(isp, bus, nvram_data);
7818 	} else if (IS_SCSI(isp)) {
7819 		isp_parse_nvram_1020(isp, nvram_data);
7820 	} else {
7821 		isp_parse_nvram_2100(isp, nvram_data);
7822 	}
7823 	retval = 0;
7824 out:
7825 	return (retval);
7826 #undef	nvram_data
7827 #undef	nvram_words
7828 }
7829 
7830 static int
7831 isp_read_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
7832 {
7833 	int retval = 0;
7834 	uint32_t addr, csum, lwrds, *dptr;
7835 
7836 	if (isp->isp_port) {
7837 		addr = ISP2400_NVRAM_PORT1_ADDR;
7838 	} else {
7839 		addr = ISP2400_NVRAM_PORT0_ADDR;
7840 	}
7841 
7842 	dptr = (uint32_t *) nvram_data;
7843 	for (lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7844 		isp_rd_2400_nvram(isp, addr++, dptr++);
7845 	}
7846 	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
7847 	    nvram_data[2] != 'P') {
7848 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM header (%x %x %x)",
7849 		    nvram_data[0], nvram_data[1], nvram_data[2]);
7850 		retval = -1;
7851 		goto out;
7852 	}
7853 	dptr = (uint32_t *) nvram_data;
7854 	for (csum = 0, lwrds = 0; lwrds < ISP2400_NVRAM_SIZE >> 2; lwrds++) {
7855 		uint32_t tmp;
7856 		ISP_IOXGET_32(isp, &dptr[lwrds], tmp);
7857 		csum += tmp;
7858 	}
7859 	if (csum != 0) {
7860 		isp_prt(isp, ISP_LOGWARN, "invalid NVRAM checksum");
7861 		retval = -1;
7862 		goto out;
7863 	}
7864 	isp_parse_nvram_2400(isp, nvram_data);
7865 out:
7866 	return (retval);
7867 }
7868 
7869 static void
7870 isp_rdnvram_word(ispsoftc_t *isp, int wo, uint16_t *rp)
7871 {
7872 	int i, cbits;
7873 	uint16_t bit, rqst, junk;
7874 
7875 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7876 	ISP_DELAY(10);
7877 	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7878 	ISP_DELAY(10);
7879 
7880 	if (IS_FC(isp)) {
7881 		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
7882 		if (IS_2312(isp) && isp->isp_port) {
7883 			wo += 128;
7884 		}
7885 		rqst = (ISP_NVRAM_READ << 8) | wo;
7886 		cbits = 10;
7887 	} else if (IS_ULTRA2(isp)) {
7888 		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
7889 		rqst = (ISP_NVRAM_READ << 8) | wo;
7890 		cbits = 10;
7891 	} else {
7892 		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
7893 		rqst = (ISP_NVRAM_READ << 6) | wo;
7894 		cbits = 8;
7895 	}
7896 
7897 	/*
7898 	 * Clock the word select request out...
7899 	 */
7900 	for (i = cbits; i >= 0; i--) {
7901 		if ((rqst >> i) & 1) {
7902 			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
7903 		} else {
7904 			bit = BIU_NVRAM_SELECT;
7905 		}
7906 		ISP_WRITE(isp, BIU_NVRAM, bit);
7907 		ISP_DELAY(10);
7908 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7909 		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
7910 		ISP_DELAY(10);
7911 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7912 		ISP_WRITE(isp, BIU_NVRAM, bit);
7913 		ISP_DELAY(10);
7914 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7915 	}
7916 	/*
7917 	 * Now read the result back in (bits come back in MSB format).
7918 	 */
7919 	*rp = 0;
7920 	for (i = 0; i < 16; i++) {
7921 		uint16_t rv;
7922 		*rp <<= 1;
7923 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
7924 		ISP_DELAY(10);
7925 		rv = ISP_READ(isp, BIU_NVRAM);
7926 		if (rv & BIU_NVRAM_DATAIN) {
7927 			*rp |= 1;
7928 		}
7929 		ISP_DELAY(10);
7930 		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
7931 		ISP_DELAY(10);
7932 		junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7933 	}
7934 	ISP_WRITE(isp, BIU_NVRAM, 0);
7935 	ISP_DELAY(10);
7936 	junk = ISP_READ(isp, BIU_NVRAM);	/* force PCI flush */
7937 	ISP_SWIZZLE_NVRAM_WORD(isp, rp);
7938 }
7939 
7940 static void
7941 isp_rd_2400_nvram(ispsoftc_t *isp, uint32_t addr, uint32_t *rp)
7942 {
7943 	int loops = 0;
7944 	uint32_t base = 0x7ffe0000;
7945 	uint32_t tmp = 0;
7946 
7947 	if (IS_26XX(isp)) {
7948 		base = 0x7fe7c000;	/* XXX: Observation, may be wrong. */
7949 	} else if (IS_25XX(isp)) {
7950 		base = 0x7ff00000 | 0x48000;
7951 	}
7952 	ISP_WRITE(isp, BIU2400_FLASH_ADDR, base | addr);
7953 	for (loops = 0; loops < 5000; loops++) {
7954 		ISP_DELAY(10);
7955 		tmp = ISP_READ(isp, BIU2400_FLASH_ADDR);
7956 		if ((tmp & (1U << 31)) != 0) {
7957 			break;
7958 		}
7959 	}
7960 	if (tmp & (1U << 31)) {
7961 		*rp = ISP_READ(isp, BIU2400_FLASH_DATA);
7962 		ISP_SWIZZLE_NVRAM_LONG(isp, rp);
7963 	} else {
7964 		*rp = 0xffffffff;
7965 	}
7966 }
7967 
7968 static void
7969 isp_parse_nvram_1020(ispsoftc_t *isp, uint8_t *nvram_data)
7970 {
7971 	sdparam *sdp = SDPARAM(isp, 0);
7972 	int tgt;
7973 
7974 	sdp->isp_fifo_threshold =
7975 		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
7976 		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
7977 
7978 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
7979 		sdp->isp_initiator_id = ISP_NVRAM_INITIATOR_ID(nvram_data);
7980 
7981 	sdp->isp_bus_reset_delay =
7982 		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
7983 
7984 	sdp->isp_retry_count =
7985 		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
7986 
7987 	sdp->isp_retry_delay =
7988 		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
7989 
7990 	sdp->isp_async_data_setup =
7991 		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
7992 
7993 	if (isp->isp_type >= ISP_HA_SCSI_1040) {
7994 		if (sdp->isp_async_data_setup < 9) {
7995 			sdp->isp_async_data_setup = 9;
7996 		}
7997 	} else {
7998 		if (sdp->isp_async_data_setup != 6) {
7999 			sdp->isp_async_data_setup = 6;
8000 		}
8001 	}
8002 
8003 	sdp->isp_req_ack_active_neg =
8004 		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
8005 
8006 	sdp->isp_data_line_active_neg =
8007 		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
8008 
8009 	sdp->isp_data_dma_burst_enabl =
8010 		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
8011 
8012 	sdp->isp_cmd_dma_burst_enable =
8013 		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
8014 
8015 	sdp->isp_tag_aging =
8016 		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
8017 
8018 	sdp->isp_selection_timeout =
8019 		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
8020 
8021 	sdp->isp_max_queue_depth =
8022 		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
8023 
8024 	sdp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
8025 
8026 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8027 		sdp->isp_devparam[tgt].dev_enable =
8028 			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt);
8029 		sdp->isp_devparam[tgt].exc_throttle =
8030 			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt);
8031 		sdp->isp_devparam[tgt].nvrm_offset =
8032 			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt);
8033 		sdp->isp_devparam[tgt].nvrm_period =
8034 			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt);
8035 		/*
8036 		 * We probably shouldn't lie about this, but it
8037 		 * it makes it much safer if we limit NVRAM values
8038 		 * to sanity.
8039 		 */
8040 		if (isp->isp_type < ISP_HA_SCSI_1040) {
8041 			/*
8042 			 * If we're not ultra, we can't possibly
8043 			 * be a shorter period than this.
8044 			 */
8045 			if (sdp->isp_devparam[tgt].nvrm_period < 0x19) {
8046 				sdp->isp_devparam[tgt].nvrm_period = 0x19;
8047 			}
8048 			if (sdp->isp_devparam[tgt].nvrm_offset > 0xc) {
8049 				sdp->isp_devparam[tgt].nvrm_offset = 0x0c;
8050 			}
8051 		} else {
8052 			if (sdp->isp_devparam[tgt].nvrm_offset > 0x8) {
8053 				sdp->isp_devparam[tgt].nvrm_offset = 0x8;
8054 			}
8055 		}
8056 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8057 		if (ISP_NVRAM_TGT_RENEG(nvram_data, tgt))
8058 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8059 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8060 		if (ISP_NVRAM_TGT_TQING(nvram_data, tgt))
8061 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8062 		if (ISP_NVRAM_TGT_SYNC(nvram_data, tgt))
8063 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8064 		if (ISP_NVRAM_TGT_WIDE(nvram_data, tgt))
8065 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8066 		if (ISP_NVRAM_TGT_PARITY(nvram_data, tgt))
8067 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8068 		if (ISP_NVRAM_TGT_DISC(nvram_data, tgt))
8069 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8070 		sdp->isp_devparam[tgt].actv_flags = 0; /* we don't know */
8071 		sdp->isp_devparam[tgt].goal_offset =
8072 		    sdp->isp_devparam[tgt].nvrm_offset;
8073 		sdp->isp_devparam[tgt].goal_period =
8074 		    sdp->isp_devparam[tgt].nvrm_period;
8075 		sdp->isp_devparam[tgt].goal_flags =
8076 		    sdp->isp_devparam[tgt].nvrm_flags;
8077 	}
8078 }
8079 
8080 static void
8081 isp_parse_nvram_1080(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8082 {
8083 	sdparam *sdp = SDPARAM(isp, bus);
8084 	int tgt;
8085 
8086 	sdp->isp_fifo_threshold =
8087 	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
8088 
8089 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8090 		sdp->isp_initiator_id = ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
8091 
8092 	sdp->isp_bus_reset_delay =
8093 	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8094 
8095 	sdp->isp_retry_count =
8096 	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8097 
8098 	sdp->isp_retry_delay =
8099 	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8100 
8101 	sdp->isp_async_data_setup =
8102 	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8103 
8104 	sdp->isp_req_ack_active_neg =
8105 	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8106 
8107 	sdp->isp_data_line_active_neg =
8108 	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8109 
8110 	sdp->isp_data_dma_burst_enabl =
8111 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8112 
8113 	sdp->isp_cmd_dma_burst_enable =
8114 	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
8115 
8116 	sdp->isp_selection_timeout =
8117 	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8118 
8119 	sdp->isp_max_queue_depth =
8120 	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8121 
8122 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8123 		sdp->isp_devparam[tgt].dev_enable =
8124 		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8125 		sdp->isp_devparam[tgt].exc_throttle =
8126 			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8127 		sdp->isp_devparam[tgt].nvrm_offset =
8128 			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8129 		sdp->isp_devparam[tgt].nvrm_period =
8130 			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8131 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8132 		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8133 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8134 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8135 		if (ISP1080_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8136 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8137 		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8138 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8139 		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8140 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8141 		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8142 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8143 		if (ISP1080_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8144 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8145 		sdp->isp_devparam[tgt].actv_flags = 0;
8146 		sdp->isp_devparam[tgt].goal_offset =
8147 		    sdp->isp_devparam[tgt].nvrm_offset;
8148 		sdp->isp_devparam[tgt].goal_period =
8149 		    sdp->isp_devparam[tgt].nvrm_period;
8150 		sdp->isp_devparam[tgt].goal_flags =
8151 		    sdp->isp_devparam[tgt].nvrm_flags;
8152 	}
8153 }
8154 
8155 static void
8156 isp_parse_nvram_12160(ispsoftc_t *isp, int bus, uint8_t *nvram_data)
8157 {
8158 	sdparam *sdp = SDPARAM(isp, bus);
8159 	int tgt;
8160 
8161 	sdp->isp_fifo_threshold =
8162 	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
8163 
8164 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0)
8165 		sdp->isp_initiator_id = ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
8166 
8167 	sdp->isp_bus_reset_delay =
8168 	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
8169 
8170 	sdp->isp_retry_count =
8171 	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
8172 
8173 	sdp->isp_retry_delay =
8174 	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
8175 
8176 	sdp->isp_async_data_setup =
8177 	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data, bus);
8178 
8179 	sdp->isp_req_ack_active_neg =
8180 	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data, bus);
8181 
8182 	sdp->isp_data_line_active_neg =
8183 	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data, bus);
8184 
8185 	sdp->isp_data_dma_burst_enabl =
8186 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8187 
8188 	sdp->isp_cmd_dma_burst_enable =
8189 	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
8190 
8191 	sdp->isp_selection_timeout =
8192 	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
8193 
8194 	sdp->isp_max_queue_depth =
8195 	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
8196 
8197 	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
8198 		sdp->isp_devparam[tgt].dev_enable =
8199 		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, tgt, bus);
8200 		sdp->isp_devparam[tgt].exc_throttle =
8201 			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, tgt, bus);
8202 		sdp->isp_devparam[tgt].nvrm_offset =
8203 			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, tgt, bus);
8204 		sdp->isp_devparam[tgt].nvrm_period =
8205 			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, tgt, bus);
8206 		sdp->isp_devparam[tgt].nvrm_flags = 0;
8207 		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, tgt, bus))
8208 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_RENEG;
8209 		sdp->isp_devparam[tgt].nvrm_flags |= DPARM_ARQ;
8210 		if (ISP12160_NVRAM_TGT_TQING(nvram_data, tgt, bus))
8211 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_TQING;
8212 		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, tgt, bus))
8213 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_SYNC;
8214 		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, tgt, bus))
8215 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_WIDE;
8216 		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, tgt, bus))
8217 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_PARITY;
8218 		if (ISP12160_NVRAM_TGT_DISC(nvram_data, tgt, bus))
8219 			sdp->isp_devparam[tgt].nvrm_flags |= DPARM_DISC;
8220 		sdp->isp_devparam[tgt].actv_flags = 0;
8221 		sdp->isp_devparam[tgt].goal_offset =
8222 		    sdp->isp_devparam[tgt].nvrm_offset;
8223 		sdp->isp_devparam[tgt].goal_period =
8224 		    sdp->isp_devparam[tgt].nvrm_period;
8225 		sdp->isp_devparam[tgt].goal_flags =
8226 		    sdp->isp_devparam[tgt].nvrm_flags;
8227 	}
8228 }
8229 
8230 static void
8231 isp_parse_nvram_2100(ispsoftc_t *isp, uint8_t *nvram_data)
8232 {
8233 	fcparam *fcp = FCPARAM(isp, 0);
8234 	uint64_t wwn;
8235 
8236 	/*
8237 	 * There is NVRAM storage for both Port and Node entities-
8238 	 * but the Node entity appears to be unused on all the cards
8239 	 * I can find. However, we should account for this being set
8240 	 * at some point in the future.
8241 	 *
8242 	 * Qlogic WWNs have an NAA of 2, but usually nothing shows up in
8243 	 * bits 48..60. In the case of the 2202, it appears that they do
8244 	 * use bit 48 to distinguish between the two instances on the card.
8245 	 * The 2204, which I've never seen, *probably* extends this method.
8246 	 */
8247 	wwn = ISP2100_NVRAM_PORT_NAME(nvram_data);
8248 	if (wwn) {
8249 		isp_prt(isp, ISP_LOGCONFIG, "NVRAM Port WWN 0x%08x%08x",
8250 		    (uint32_t) (wwn >> 32), (uint32_t) (wwn));
8251 		if ((wwn >> 60) == 0) {
8252 			wwn |= (((uint64_t) 2)<< 60);
8253 		}
8254 	}
8255 	fcp->isp_wwpn_nvram = wwn;
8256 	if (IS_2200(isp) || IS_23XX(isp)) {
8257 		wwn = ISP2100_NVRAM_NODE_NAME(nvram_data);
8258 		if (wwn) {
8259 			isp_prt(isp, ISP_LOGCONFIG, "NVRAM Node WWN 0x%08x%08x",
8260 			    (uint32_t) (wwn >> 32),
8261 			    (uint32_t) (wwn));
8262 			if ((wwn >> 60) == 0) {
8263 				wwn |= (((uint64_t) 2)<< 60);
8264 			}
8265 		} else {
8266 			wwn = fcp->isp_wwpn_nvram & ~((uint64_t) 0xfff << 48);
8267 		}
8268 	} else {
8269 		wwn &= ~((uint64_t) 0xfff << 48);
8270 	}
8271 	fcp->isp_wwnn_nvram = wwn;
8272 
8273 	fcp->isp_maxalloc = ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
8274 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8275 		DEFAULT_FRAMESIZE(isp) =
8276 		    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
8277 	}
8278 	fcp->isp_retry_delay = ISP2100_NVRAM_RETRY_DELAY(nvram_data);
8279 	fcp->isp_retry_count = ISP2100_NVRAM_RETRY_COUNT(nvram_data);
8280 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8281 		fcp->isp_loopid = ISP2100_NVRAM_HARDLOOPID(nvram_data);
8282 	}
8283 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8284 		DEFAULT_EXEC_THROTTLE(isp) =
8285 			ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
8286 	}
8287 	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
8288 	isp_prt(isp, ISP_LOGDEBUG0,
8289 	    "NVRAM 0x%08x%08x 0x%08x%08x maxalloc %d maxframelen %d",
8290 	    (uint32_t) (fcp->isp_wwnn_nvram >> 32),
8291 	    (uint32_t) fcp->isp_wwnn_nvram,
8292 	    (uint32_t) (fcp->isp_wwpn_nvram >> 32),
8293 	    (uint32_t) fcp->isp_wwpn_nvram,
8294 	    ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data),
8295 	    ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data));
8296 	isp_prt(isp, ISP_LOGDEBUG0,
8297 	    "execthrottle %d fwoptions 0x%x hardloop %d tov %d",
8298 	    ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data),
8299 	    ISP2100_NVRAM_OPTIONS(nvram_data),
8300 	    ISP2100_NVRAM_HARDLOOPID(nvram_data),
8301 	    ISP2100_NVRAM_TOV(nvram_data));
8302 	fcp->isp_xfwoptions = ISP2100_XFW_OPTIONS(nvram_data);
8303 	fcp->isp_zfwoptions = ISP2100_ZFW_OPTIONS(nvram_data);
8304 	isp_prt(isp, ISP_LOGDEBUG0, "xfwoptions 0x%x zfw options 0x%x",
8305 	    ISP2100_XFW_OPTIONS(nvram_data), ISP2100_ZFW_OPTIONS(nvram_data));
8306 }
8307 
8308 static void
8309 isp_parse_nvram_2400(ispsoftc_t *isp, uint8_t *nvram_data)
8310 {
8311 	fcparam *fcp = FCPARAM(isp, 0);
8312 	uint64_t wwn;
8313 
8314 	isp_prt(isp, ISP_LOGDEBUG0,
8315 	    "NVRAM 0x%08x%08x 0x%08x%08x exchg_cnt %d maxframelen %d",
8316 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data) >> 32),
8317 	    (uint32_t) (ISP2400_NVRAM_NODE_NAME(nvram_data)),
8318 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data) >> 32),
8319 	    (uint32_t) (ISP2400_NVRAM_PORT_NAME(nvram_data)),
8320 	    ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data),
8321 	    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data));
8322 	isp_prt(isp, ISP_LOGDEBUG0,
8323 	    "NVRAM execthr %d loopid %d fwopt1 0x%x fwopt2 0x%x fwopt3 0x%x",
8324 	    ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data),
8325 	    ISP2400_NVRAM_HARDLOOPID(nvram_data),
8326 	    ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data),
8327 	    ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data),
8328 	    ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data));
8329 
8330 	wwn = ISP2400_NVRAM_PORT_NAME(nvram_data);
8331 	fcp->isp_wwpn_nvram = wwn;
8332 
8333 	wwn = ISP2400_NVRAM_NODE_NAME(nvram_data);
8334 	if (wwn) {
8335 		if ((wwn >> 60) != 2 && (wwn >> 60) != 5) {
8336 			wwn = 0;
8337 		}
8338 	}
8339 	if (wwn == 0 && (fcp->isp_wwpn_nvram >> 60) == 2) {
8340 		wwn = fcp->isp_wwpn_nvram;
8341 		wwn &= ~((uint64_t) 0xfff << 48);
8342 	}
8343 	fcp->isp_wwnn_nvram = wwn;
8344 
8345 	if (ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data)) {
8346 		fcp->isp_maxalloc = ISP2400_NVRAM_EXCHANGE_COUNT(nvram_data);
8347 	}
8348 	if ((isp->isp_confopts & ISP_CFG_OWNFSZ) == 0) {
8349 		DEFAULT_FRAMESIZE(isp) =
8350 		    ISP2400_NVRAM_MAXFRAMELENGTH(nvram_data);
8351 	}
8352 	if ((isp->isp_confopts & ISP_CFG_OWNLOOPID) == 0) {
8353 		fcp->isp_loopid = ISP2400_NVRAM_HARDLOOPID(nvram_data);
8354 	}
8355 	if ((isp->isp_confopts & ISP_CFG_OWNEXCTHROTTLE) == 0) {
8356 		DEFAULT_EXEC_THROTTLE(isp) =
8357 			ISP2400_NVRAM_EXECUTION_THROTTLE(nvram_data);
8358 	}
8359 	fcp->isp_fwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS1(nvram_data);
8360 	fcp->isp_xfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS2(nvram_data);
8361 	fcp->isp_zfwoptions = ISP2400_NVRAM_FIRMWARE_OPTIONS3(nvram_data);
8362 }
8363