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