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