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