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