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