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