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