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