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