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