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