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