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