isp.c revision 61776
113546Sjulian/* $FreeBSD: head/sys/dev/isp/isp.c 61776 2000-06-18 04:56:17Z mjacob $ */
2113658Sdeischen/*
3113658Sdeischen * Machine and OS Independent (well, as best as possible)
435509Sjb * code for the Qlogic ISP SCSI adapters.
513546Sjulian *
613546Sjulian * Copyright (c) 1997, 1998, 1999 by Matthew Jacob
713546Sjulian * NASA/Ames Research Center
813546Sjulian * All rights reserved.
913546Sjulian *
1013546Sjulian * Redistribution and use in source and binary forms, with or without
1113546Sjulian * modification, are permitted provided that the following conditions
1213546Sjulian * are met:
1313546Sjulian * 1. Redistributions of source code must retain the above copyright
1413546Sjulian *    notice immediately at the beginning of the file, without modification,
1513546Sjulian *    this list of conditions, and the following disclaimer.
1613546Sjulian * 2. Redistributions in binary form must reproduce the above copyright
1713546Sjulian *    notice, this list of conditions and the following disclaimer in the
1813546Sjulian *    documentation and/or other materials provided with the distribution.
1913546Sjulian * 3. The name of the author may not be used to endorse or promote products
2013546Sjulian *    derived from this software without specific prior written permission.
2113546Sjulian *
2213546Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2313546Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2413546Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2544963Sjb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2613546Sjulian * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2713546Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2813546Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2913546Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3013546Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3113546Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3213546Sjulian * SUCH DAMAGE.
3313546Sjulian */
3413546Sjulian
35113658Sdeischen/*
36113662Sdeischen * Inspiration and ideas about this driver are from Erik Moe's Linux driver
37113658Sdeischen * (qlogicisp.c) and Dave Miller's SBus version of same (qlogicisp.c). Some
38113658Sdeischen * ideas dredged from the Solaris driver.
39113658Sdeischen */
40113658Sdeischen
41113658Sdeischen/*
42113658Sdeischen * Include header file appropriate for platform we're building on.
43113658Sdeischen */
44113658Sdeischen
45113870Sdeischen#ifdef	__NetBSD__
46113658Sdeischen#include <dev/ic/isp_netbsd.h>
4713546Sjulian#endif
4813546Sjulian#ifdef	__FreeBSD__
49113658Sdeischen#include <dev/isp/isp_freebsd.h>
50113658Sdeischen#endif
5113546Sjulian#ifdef	__OpenBSD__
52113658Sdeischen#include <dev/ic/isp_openbsd.h>
53113658Sdeischen#endif
54103388Smini#ifdef	__linux__
55113658Sdeischen#include "isp_linux.h"
56113658Sdeischen#endif
5713546Sjulian
58113658Sdeischen/*
5967097Sdeischen * General defines
6067097Sdeischen */
6167097Sdeischen
6267097Sdeischen#define	MBOX_DELAY_COUNT	1000000 / 100
6367097Sdeischen
6467097Sdeischen/*
65113658Sdeischen * Local static data
66113658Sdeischen */
67113658Sdeischen
68113658Sdeischen/*
69113658Sdeischen * Local function prototypes.
70113658Sdeischen */
71113658Sdeischenstatic int isp_parse_async __P((struct ispsoftc *, int));
72113658Sdeischenstatic int isp_handle_other_response
73113658Sdeischen__P((struct ispsoftc *, ispstatusreq_t *, u_int16_t *));
74113658Sdeischenstatic void isp_parse_status
75113658Sdeischen__P((struct ispsoftc *, ispstatusreq_t *, ISP_SCSI_XFER_T *));
76113658Sdeischenstatic void isp_fastpost_complete __P((struct ispsoftc *, u_int32_t));
77113658Sdeischenstatic void isp_scsi_init __P((struct ispsoftc *));
78113658Sdeischenstatic void isp_scsi_channel_init __P((struct ispsoftc *, int));
79106786Sministatic void isp_fibre_init __P((struct ispsoftc *));
80113658Sdeischenstatic void isp_mark_getpdb_all __P((struct ispsoftc *));
81113658Sdeischenstatic int isp_getpdb __P((struct ispsoftc *, int, isp_pdb_t *));
8213546Sjulianstatic u_int64_t isp_get_portname __P((struct ispsoftc *, int, int));
83113658Sdeischenstatic int isp_fclink_test __P((struct ispsoftc *, int));
8448046Sjbstatic int isp_same_lportdb __P((struct lportdb *, struct lportdb *));
85113658Sdeischenstatic int isp_pdb_sync __P((struct ispsoftc *, int));
86113658Sdeischen#ifdef	ISP2100_FABRIC
87113658Sdeischenstatic int isp_scan_fabric __P((struct ispsoftc *));
88113658Sdeischen#endif
89113658Sdeischenstatic void isp_fw_state __P((struct ispsoftc *));
90113658Sdeischenstatic void isp_dumpregs __P((struct ispsoftc *, const char *));
91113658Sdeischenstatic void isp_mboxcmd __P((struct ispsoftc *, mbreg_t *));
92113658Sdeischen
93113658Sdeischenstatic void isp_update __P((struct ispsoftc *));
94113658Sdeischenstatic void isp_update_bus __P((struct ispsoftc *, int));
95113658Sdeischenstatic void isp_setdfltparm __P((struct ispsoftc *, int));
96113658Sdeischenstatic int isp_read_nvram __P((struct ispsoftc *));
97113658Sdeischenstatic void isp_rdnvram_word __P((struct ispsoftc *, int, u_int16_t *));
98114187Sdeischenstatic void isp_parse_nvram_1020 __P((struct ispsoftc *, u_int8_t *));
99113658Sdeischenstatic void isp_parse_nvram_1080 __P((struct ispsoftc *, int, u_int8_t *));
100113658Sdeischenstatic void isp_parse_nvram_12160 __P((struct ispsoftc *, int, u_int8_t *));
101113658Sdeischenstatic void isp_parse_nvram_2100 __P((struct ispsoftc *, u_int8_t *));
102113658Sdeischen
103113658Sdeischen
104113658Sdeischen/*
105113658Sdeischen * Reset Hardware.
106113658Sdeischen *
107113658Sdeischen * Hit the chip over the head, download new f/w if available and set it running.
108113658Sdeischen *
109113661Sdeischen * Locking done elsewhere.
110113658Sdeischen */
111113658Sdeischenvoid
112113658Sdeischenisp_reset(isp)
113113658Sdeischen	struct ispsoftc *isp;
114113658Sdeischen{
115113658Sdeischen	mbreg_t mbs;
116113658Sdeischen	int loops, i, touched, dodnld = 1;
117113658Sdeischen	char *revname;
118113658Sdeischen
119113658Sdeischen	isp->isp_state = ISP_NILSTATE;
120113658Sdeischen
121113658Sdeischen	/*
122113658Sdeischen	 * Basic types (SCSI, FibreChannel and PCI or SBus)
123113658Sdeischen	 * have been set in the MD code. We figure out more
124113942Sdeischen	 * here.
125113658Sdeischen	 */
126113786Sdeischen	isp->isp_dblev = DFLT_DBLEVEL;
127113658Sdeischen
128113786Sdeischen	/*
129113658Sdeischen	 * After we've fired this chip up, zero out the conf1 register
130113786Sdeischen	 * for SCSI adapters and other settings for the 2100.
131113661Sdeischen	 */
132113870Sdeischen
133113658Sdeischen	/*
134113786Sdeischen	 * Get the current running firmware revision out of the
135113658Sdeischen	 * chip before we hit it over the head (if this is our
136114187Sdeischen	 * first time through). Note that we store this as the
137114187Sdeischen	 * 'ROM' firmware revision- which it may not be. In any
138113658Sdeischen	 * case, we don't really use this yet, but we may in
139113658Sdeischen	 * the future.
140113658Sdeischen	 */
141113658Sdeischen	if ((touched = isp->isp_touched) == 0) {
142113658Sdeischen		/*
143113658Sdeischen		 * Just in case it was paused...
144113658Sdeischen		 */
145113658Sdeischen		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
146113658Sdeischen		mbs.param[0] = MBOX_ABOUT_FIRMWARE;
147113658Sdeischen		isp_mboxcmd(isp, &mbs);
148113658Sdeischen		/*
149113658Sdeischen		 * If this fails, it probably means we're running
15013546Sjulian		 * an old prom, if anything at all...
151113658Sdeischen		 */
15213546Sjulian		if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
153113658Sdeischen			isp->isp_romfw_rev[0] = mbs.param[1];
154113658Sdeischen			isp->isp_romfw_rev[1] = mbs.param[2];
155113658Sdeischen			isp->isp_romfw_rev[2] = mbs.param[3];
156113658Sdeischen		}
157113658Sdeischen		isp->isp_touched = 1;
15871581Sdeischen	}
15967097Sdeischen
160113658Sdeischen	DISABLE_INTS(isp);
161113658Sdeischen
162113658Sdeischen	/*
16367097Sdeischen	 * Put the board into PAUSE mode (so we can read the SXP registers).
164113658Sdeischen	 */
165113658Sdeischen	ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
16613546Sjulian
167106191Smini	if (IS_FC(isp)) {
168113658Sdeischen		revname = "2X00";
169113658Sdeischen		switch (isp->isp_type) {
170106191Smini		case ISP_HA_FC_2100:
171113658Sdeischen			revname[1] = '1';
172113658Sdeischen			break;
173106191Smini		case ISP_HA_FC_2200:
174113658Sdeischen			revname[1] = '2';
175113658Sdeischen			break;
176113658Sdeischen		default:
177113658Sdeischen			break;
178113658Sdeischen		}
179113658Sdeischen	} else if (IS_1240(isp)) {
180113658Sdeischen		sdparam *sdp = isp->isp_param;
181113658Sdeischen		revname = "1240";
182113658Sdeischen		isp->isp_clock = 60;
183106191Smini		sdp->isp_ultramode = 1;
184113658Sdeischen		sdp++;
185113658Sdeischen		sdp->isp_ultramode = 1;
186113658Sdeischen		/*
187113658Sdeischen		 * XXX: Should probably do some bus sensing.
188113658Sdeischen		 */
189113658Sdeischen	} else if (IS_ULTRA2(isp)) {
190113658Sdeischen		static char *m = "%s: bus %d is in %s Mode\n";
191113658Sdeischen		u_int16_t l;
192113658Sdeischen		sdparam *sdp = isp->isp_param;
193113658Sdeischen
194113658Sdeischen		isp->isp_clock = 100;
195106191Smini
196106191Smini		if (IS_1280(isp))
197106191Smini			revname = "1280";
198113658Sdeischen		else if (IS_1080(isp))
199113658Sdeischen			revname = "1080";
200113658Sdeischen		else if (IS_12160(isp))
201113658Sdeischen			revname = "12160";
202113658Sdeischen		else
203113658Sdeischen			revname = "<UNKLVD>";
204113658Sdeischen
205113658Sdeischen		l = ISP_READ(isp, SXP_PINS_DIFF) & ISP1080_MODE_MASK;
206113658Sdeischen		switch (l) {
207113658Sdeischen		case ISP1080_LVD_MODE:
208113658Sdeischen			sdp->isp_lvdmode = 1;
209113658Sdeischen			CFGPRINTF(m, isp->isp_name, 0, "LVD");
210113658Sdeischen			break;
211113786Sdeischen		case ISP1080_HVD_MODE:
212113786Sdeischen			sdp->isp_diffmode = 1;
213113658Sdeischen			CFGPRINTF(m, isp->isp_name, 0, "Differential");
214113658Sdeischen			break;
215113658Sdeischen		case ISP1080_SE_MODE:
216113658Sdeischen			sdp->isp_ultramode = 1;
217113658Sdeischen			CFGPRINTF(m, isp->isp_name, 0, "Single-Ended");
218113658Sdeischen			break;
219113658Sdeischen		default:
220113658Sdeischen			CFGPRINTF("%s: unknown mode on bus %d (0x%x)\n",
221113658Sdeischen			    isp->isp_name, 0, l);
222113658Sdeischen			break;
223113658Sdeischen		}
224113786Sdeischen
225113786Sdeischen		if (IS_DUALBUS(isp)) {
226113658Sdeischen			sdp++;
227113658Sdeischen			l = ISP_READ(isp, SXP_PINS_DIFF|SXP_BANK1_SELECT);
228113658Sdeischen			l &= ISP1080_MODE_MASK;
229113658Sdeischen			switch(l) {
230113658Sdeischen			case ISP1080_LVD_MODE:
231113658Sdeischen				sdp->isp_lvdmode = 1;
232113658Sdeischen				CFGPRINTF(m, isp->isp_name, 1, "LVD");
233113658Sdeischen				break;
234113658Sdeischen			case ISP1080_HVD_MODE:
235113661Sdeischen				sdp->isp_diffmode = 1;
236113658Sdeischen				CFGPRINTF(m, isp->isp_name, 1, "Differential");
237113658Sdeischen				break;
238113658Sdeischen			case ISP1080_SE_MODE:
239113658Sdeischen				sdp->isp_ultramode = 1;
240113658Sdeischen				CFGPRINTF(m, isp->isp_name, 1, "Single-Ended");
241113658Sdeischen				break;
242113658Sdeischen			default:
243113658Sdeischen				CFGPRINTF("%s: unknown mode on bus %d (0x%x)\n",
244113658Sdeischen				    isp->isp_name, 1, l);
245113658Sdeischen				break;
246113661Sdeischen			}
247113658Sdeischen		}
248113658Sdeischen	} else {
249113658Sdeischen		sdparam *sdp = isp->isp_param;
250113658Sdeischen		i = ISP_READ(isp, BIU_CONF0) & BIU_CONF0_HW_MASK;
251113658Sdeischen		switch (i) {
252113658Sdeischen		default:
253113658Sdeischen			PRINTF("%s: unknown chip rev. 0x%x- assuming a 1020\n",
254113658Sdeischen			    isp->isp_name, i);
255113658Sdeischen			/* FALLTHROUGH */
256113658Sdeischen		case 1:
257113658Sdeischen			revname = "1020";
258113658Sdeischen			isp->isp_type = ISP_HA_SCSI_1020;
259113658Sdeischen			isp->isp_clock = 40;
260113658Sdeischen			break;
261113658Sdeischen		case 2:
262113658Sdeischen			/*
263113658Sdeischen			 * Some 1020A chips are Ultra Capable, but don't
264113658Sdeischen			 * run the clock rate up for that unless told to
265113658Sdeischen			 * do so by the Ultra Capable bits being set.
266113661Sdeischen			 */
267113942Sdeischen			revname = "1020A";
268113942Sdeischen			isp->isp_type = ISP_HA_SCSI_1020A;
269113942Sdeischen			isp->isp_clock = 40;
270113942Sdeischen			break;
271113658Sdeischen		case 3:
272113658Sdeischen			revname = "1040";
273113661Sdeischen			isp->isp_type = ISP_HA_SCSI_1040;
274113661Sdeischen			isp->isp_clock = 60;
275113658Sdeischen			break;
276113658Sdeischen		case 4:
277113658Sdeischen			revname = "1040A";
278113658Sdeischen			isp->isp_type = ISP_HA_SCSI_1040A;
279113658Sdeischen			isp->isp_clock = 60;
280113658Sdeischen			break;
281113658Sdeischen		case 5:
282113658Sdeischen			revname = "1040B";
283113658Sdeischen			isp->isp_type = ISP_HA_SCSI_1040B;
284113658Sdeischen			isp->isp_clock = 60;
285113658Sdeischen			break;
286113658Sdeischen		case 6:
287106191Smini			revname = "1040C";
288113658Sdeischen			isp->isp_type = ISP_HA_SCSI_1040C;
289113658Sdeischen			isp->isp_clock = 60;
290106191Smini                        break;
291113658Sdeischen		}
292113658Sdeischen		/*
293113658Sdeischen		 * Now, while we're at it, gather info about ultra
294113658Sdeischen		 * and/or differential mode.
295113658Sdeischen		 */
296113658Sdeischen		if (ISP_READ(isp, SXP_PINS_DIFF) & SXP_PINS_DIFF_MODE) {
297113658Sdeischen			CFGPRINTF("%s: Differential Mode\n", isp->isp_name);
298113658Sdeischen			sdp->isp_diffmode = 1;
299113658Sdeischen		} else {
300113658Sdeischen			sdp->isp_diffmode = 0;
301113658Sdeischen		}
302113658Sdeischen		i = ISP_READ(isp, RISC_PSR);
303113658Sdeischen		if (isp->isp_bustype == ISP_BT_SBUS) {
304113658Sdeischen			i &= RISC_PSR_SBUS_ULTRA;
305113658Sdeischen		} else {
306113658Sdeischen			i &= RISC_PSR_PCI_ULTRA;
307113658Sdeischen		}
308113658Sdeischen		if (i != 0) {
309113658Sdeischen			CFGPRINTF("%s: Ultra Mode Capable\n", isp->isp_name);
310113658Sdeischen			sdp->isp_ultramode = 1;
311113658Sdeischen			/*
312113658Sdeischen			 * If we're in Ultra Mode, we have to be 60Mhz clock-
313113658Sdeischen			 * even for the SBus version.
314113658Sdeischen			 */
315113658Sdeischen			isp->isp_clock = 60;
316113658Sdeischen		} else {
317113658Sdeischen			sdp->isp_ultramode = 0;
318113658Sdeischen			/*
319113658Sdeischen			 * Clock is known. Gronk.
320113661Sdeischen			 */
321113658Sdeischen		}
322113658Sdeischen
323113658Sdeischen		/*
324113658Sdeischen		 * Machine dependent clock (if set) overrides
325113658Sdeischen		 * our generic determinations.
326113658Sdeischen		 */
327113658Sdeischen		if (isp->isp_mdvec->dv_clock) {
328113658Sdeischen			if (isp->isp_mdvec->dv_clock < isp->isp_clock) {
329113658Sdeischen				isp->isp_clock = isp->isp_mdvec->dv_clock;
330113658Sdeischen			}
331113658Sdeischen		}
332113661Sdeischen
333113658Sdeischen	}
334113658Sdeischen
335113658Sdeischen	/*
336113658Sdeischen	 * Do MD specific pre initialization
337113658Sdeischen	 */
338113658Sdeischen	ISP_RESET0(isp);
339113658Sdeischen
340113658Sdeischenagain:
341113658Sdeischen
342113658Sdeischen	/*
343113658Sdeischen	 * Hit the chip over the head with hammer,
344113658Sdeischen	 * and give the ISP a chance to recover.
345113658Sdeischen	 */
346113658Sdeischen
347113786Sdeischen	if (IS_SCSI(isp)) {
348113658Sdeischen		ISP_WRITE(isp, BIU_ICR, BIU_ICR_SOFT_RESET);
349113658Sdeischen		/*
350113658Sdeischen		 * A slight delay...
351106191Smini		 */
352113658Sdeischen		SYS_DELAY(100);
353113658Sdeischen
354106191Smini#if	0
355113658Sdeischen		PRINTF("%s: mbox0-5: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
356113658Sdeischen		    isp->isp_name, ISP_READ(isp, OUTMAILBOX0),
357113658Sdeischen		    ISP_READ(isp, OUTMAILBOX1), ISP_READ(isp, OUTMAILBOX2),
358113658Sdeischen		    ISP_READ(isp, OUTMAILBOX3), ISP_READ(isp, OUTMAILBOX4),
359113658Sdeischen		    ISP_READ(isp, OUTMAILBOX5));
360113658Sdeischen#endif
361113786Sdeischen
362113786Sdeischen		/*
363113786Sdeischen		 * Clear data && control DMA engines.
364114187Sdeischen		 */
365113786Sdeischen		ISP_WRITE(isp, CDMA_CONTROL,
366113786Sdeischen		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
367113786Sdeischen		ISP_WRITE(isp, DDMA_CONTROL,
368113786Sdeischen		    DMA_CNTRL_CLEAR_CHAN | DMA_CNTRL_RESET_INT);
369113658Sdeischen
370114187Sdeischen
371113658Sdeischen	} else {
372113786Sdeischen		ISP_WRITE(isp, BIU2100_CSR, BIU2100_SOFT_RESET);
373113658Sdeischen		/*
374113658Sdeischen		 * A slight delay...
375113658Sdeischen		 */
376113658Sdeischen		SYS_DELAY(100);
377113658Sdeischen
378113658Sdeischen		/*
379113658Sdeischen		 * Clear data && control DMA engines.
380113658Sdeischen		 */
381113658Sdeischen		ISP_WRITE(isp, CDMA2100_CONTROL,
382113658Sdeischen			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
383113658Sdeischen		ISP_WRITE(isp, TDMA2100_CONTROL,
384113658Sdeischen			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
385113658Sdeischen		ISP_WRITE(isp, RDMA2100_CONTROL,
386113658Sdeischen			DMA_CNTRL2100_CLEAR_CHAN | DMA_CNTRL2100_RESET_INT);
387113658Sdeischen	}
388113658Sdeischen
389113658Sdeischen	/*
390113658Sdeischen	 * Wait for ISP to be ready to go...
391113658Sdeischen	 */
392113786Sdeischen	loops = MBOX_DELAY_COUNT;
393113658Sdeischen	for (;;) {
394113786Sdeischen		if (IS_SCSI(isp)) {
395113786Sdeischen			if (!(ISP_READ(isp, BIU_ICR) & BIU_ICR_SOFT_RESET))
396113658Sdeischen				break;
397113658Sdeischen		} else {
398113658Sdeischen			if (!(ISP_READ(isp, BIU2100_CSR) & BIU2100_SOFT_RESET))
399113658Sdeischen				break;
400113658Sdeischen		}
401113658Sdeischen		SYS_DELAY(100);
402113658Sdeischen		if (--loops < 0) {
403113658Sdeischen			isp_dumpregs(isp, "chip reset timed out");
404113658Sdeischen			return;
405113658Sdeischen		}
406113658Sdeischen	}
407113786Sdeischen
408113870Sdeischen	/*
409113786Sdeischen	 * After we've fired this chip up, zero out the conf1 register
410113786Sdeischen	 * for SCSI adapters and other settings for the 2100.
411113658Sdeischen	 */
412113658Sdeischen
413113658Sdeischen	if (IS_SCSI(isp)) {
414113658Sdeischen		ISP_WRITE(isp, BIU_CONF1, 0);
415113658Sdeischen	} else {
416113658Sdeischen		ISP_WRITE(isp, BIU2100_CSR, 0);
417113658Sdeischen	}
418113658Sdeischen
419113658Sdeischen	/*
420113658Sdeischen	 * Reset RISC Processor
421113658Sdeischen	 */
422113658Sdeischen	ISP_WRITE(isp, HCCR, HCCR_CMD_RESET);
423113658Sdeischen	SYS_DELAY(100);
424113658Sdeischen
425113658Sdeischen	/*
426113658Sdeischen	 * Establish some initial burst rate stuff.
427113658Sdeischen	 * (only for the 1XX0 boards). This really should
428113658Sdeischen	 * be done later after fetching from NVRAM.
429113658Sdeischen	 */
430113658Sdeischen	if (IS_SCSI(isp)) {
431113658Sdeischen		u_int16_t tmp = isp->isp_mdvec->dv_conf1;
432113658Sdeischen		/*
433113658Sdeischen		 * Busted FIFO. Turn off all but burst enables.
434113658Sdeischen		 */
435113658Sdeischen		if (isp->isp_type == ISP_HA_SCSI_1040A) {
436113658Sdeischen			tmp &= BIU_BURST_ENABLE;
437113658Sdeischen		}
438113658Sdeischen		ISP_SETBITS(isp, BIU_CONF1, tmp);
439113658Sdeischen		if (tmp & BIU_BURST_ENABLE) {
440113658Sdeischen			ISP_SETBITS(isp, CDMA_CONF, DMA_ENABLE_BURST);
441113658Sdeischen			ISP_SETBITS(isp, DDMA_CONF, DMA_ENABLE_BURST);
442113658Sdeischen		}
443113658Sdeischen#ifdef	PTI_CARDS
444113658Sdeischen		if (((sdparam *) isp->isp_param)->isp_ultramode) {
445113658Sdeischen			while (ISP_READ(isp, RISC_MTR) != 0x1313) {
446113658Sdeischen				ISP_WRITE(isp, RISC_MTR, 0x1313);
447113658Sdeischen				ISP_WRITE(isp, HCCR, HCCR_CMD_STEP);
448113658Sdeischen			}
449113658Sdeischen		} else {
450113658Sdeischen			ISP_WRITE(isp, RISC_MTR, 0x1212);
451113658Sdeischen		}
452113658Sdeischen		/*
453113658Sdeischen		 * PTI specific register
454113658Sdeischen		 */
455113658Sdeischen		ISP_WRITE(isp, RISC_EMB, DUAL_BANK)
456113658Sdeischen#else
457113658Sdeischen		ISP_WRITE(isp, RISC_MTR, 0x1212);
458113658Sdeischen#endif
459113658Sdeischen	} else {
460113658Sdeischen		ISP_WRITE(isp, RISC_MTR2100, 0x1212);
461113658Sdeischen	}
462113658Sdeischen
463113658Sdeischen	ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE); /* release paused processor */
464114187Sdeischen
465113658Sdeischen	/*
466113658Sdeischen	 * Do MD specific post initialization
467113658Sdeischen	 */
468113658Sdeischen	ISP_RESET1(isp);
469113658Sdeischen
470106191Smini	/*
471114187Sdeischen	 * Wait for everything to finish firing up...
472113658Sdeischen	 */
473113658Sdeischen	loops = MBOX_DELAY_COUNT;
474106191Smini	while (ISP_READ(isp, OUTMAILBOX0) == MBOX_BUSY) {
475113658Sdeischen		SYS_DELAY(100);
476113658Sdeischen		if (--loops < 0) {
477113658Sdeischen			PRINTF("%s: MBOX_BUSY never cleared on reset\n",
478113658Sdeischen			    isp->isp_name);
479113658Sdeischen			return;
480114187Sdeischen		}
481113658Sdeischen	}
482113658Sdeischen
483113658Sdeischen	/*
484113658Sdeischen	 * Up until this point we've done everything by just reading or
485114187Sdeischen	 * setting registers. From this point on we rely on at least *some*
486114187Sdeischen	 * kind of firmware running in the card.
487114187Sdeischen	 */
488114187Sdeischen
489114187Sdeischen	/*
490114187Sdeischen	 * Do some sanity checking.
491114187Sdeischen	 */
492114187Sdeischen	mbs.param[0] = MBOX_NO_OP;
493114187Sdeischen	isp_mboxcmd(isp, &mbs);
494114187Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
495114187Sdeischen		isp_dumpregs(isp, "NOP test failed");
496113658Sdeischen		return;
497113658Sdeischen	}
498114187Sdeischen
499114187Sdeischen	if (IS_SCSI(isp)) {
500113658Sdeischen		mbs.param[0] = MBOX_MAILBOX_REG_TEST;
501113658Sdeischen		mbs.param[1] = 0xdead;
502113658Sdeischen		mbs.param[2] = 0xbeef;
503113658Sdeischen		mbs.param[3] = 0xffff;
504113658Sdeischen		mbs.param[4] = 0x1111;
505113658Sdeischen		mbs.param[5] = 0xa5a5;
506113658Sdeischen		isp_mboxcmd(isp, &mbs);
507113658Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
508113658Sdeischen			isp_dumpregs(isp,
509113658Sdeischen				"Mailbox Register test didn't complete");
510113658Sdeischen			return;
511113658Sdeischen		}
512113658Sdeischen		if (mbs.param[1] != 0xdead || mbs.param[2] != 0xbeef ||
513113658Sdeischen		    mbs.param[3] != 0xffff || mbs.param[4] != 0x1111 ||
514113658Sdeischen		    mbs.param[5] != 0xa5a5) {
515113658Sdeischen			isp_dumpregs(isp, "Register Test Failed");
516113658Sdeischen			return;
517113658Sdeischen		}
518113658Sdeischen
519113658Sdeischen	}
520113658Sdeischen
521113942Sdeischen	/*
522113942Sdeischen	 * Download new Firmware, unless requested not to do so.
523113942Sdeischen	 * This is made slightly trickier in some cases where the
524113942Sdeischen	 * firmware of the ROM revision is newer than the revision
525113942Sdeischen	 * compiled into the driver. So, where we used to compare
526113942Sdeischen	 * versions of our f/w and the ROM f/w, now we just see
527113658Sdeischen	 * whether we have f/w at all and whether a config flag
528113658Sdeischen	 * has disabled our download.
529113658Sdeischen	 */
530113658Sdeischen	if ((isp->isp_mdvec->dv_ispfw == NULL) ||
531113658Sdeischen	    (isp->isp_confopts & ISP_CFG_NORELOAD)) {
532113658Sdeischen		dodnld = 0;
533113658Sdeischen	}
534113658Sdeischen
535113658Sdeischen	if (dodnld) {
536113658Sdeischen		u_int16_t fwlen  = isp->isp_mdvec->dv_fwlen;
537113658Sdeischen		if (fwlen == 0)
538113658Sdeischen			fwlen = isp->isp_mdvec->dv_ispfw[3]; /* usually here */
539113658Sdeischen		for (i = 0; i < fwlen; i++) {
540113658Sdeischen			mbs.param[0] = MBOX_WRITE_RAM_WORD;
541113658Sdeischen			mbs.param[1] = isp->isp_mdvec->dv_codeorg + i;
542113658Sdeischen			mbs.param[2] = isp->isp_mdvec->dv_ispfw[i];
543113658Sdeischen			isp_mboxcmd(isp, &mbs);
544113658Sdeischen			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
545113658Sdeischen				PRINTF("%s: F/W download failed at word %d\n",
546113658Sdeischen				    isp->isp_name, i);
547113658Sdeischen				dodnld = 0;
548113658Sdeischen				goto again;
549113658Sdeischen			}
550113658Sdeischen		}
551113658Sdeischen
552113658Sdeischen		/*
553114187Sdeischen		 * Verify that it downloaded correctly.
554114187Sdeischen		 */
555113658Sdeischen		mbs.param[0] = MBOX_VERIFY_CHECKSUM;
556113658Sdeischen		mbs.param[1] = isp->isp_mdvec->dv_codeorg;
557113658Sdeischen		isp_mboxcmd(isp, &mbs);
558113658Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
559113658Sdeischen			isp_dumpregs(isp, "ram checksum failure");
560113658Sdeischen			return;
561113658Sdeischen		}
562113658Sdeischen	} else {
563113658Sdeischen		IDPRINTF(3, ("%s: skipping f/w download\n", isp->isp_name));
564113658Sdeischen	}
565113658Sdeischen
566113658Sdeischen	/*
567113658Sdeischen	 * Now start it rolling.
568113658Sdeischen	 *
569113658Sdeischen	 * If we didn't actually download f/w,
570113658Sdeischen	 * we still need to (re)start it.
571113658Sdeischen	 */
572113658Sdeischen
573113658Sdeischen	mbs.param[0] = MBOX_EXEC_FIRMWARE;
574113658Sdeischen	if (isp->isp_mdvec->dv_codeorg)
575113658Sdeischen		mbs.param[1] = isp->isp_mdvec->dv_codeorg;
576114187Sdeischen	else
577114187Sdeischen		mbs.param[1] = 0x1000;
578114187Sdeischen	isp_mboxcmd(isp, &mbs);
579113658Sdeischen	/* give it a chance to start */
580114187Sdeischen	DELAY(500);
581113658Sdeischen
582113658Sdeischen	if (IS_SCSI(isp)) {
583113658Sdeischen		/*
584113658Sdeischen		 * Set CLOCK RATE, but only if asked to.
585113658Sdeischen		 */
586113658Sdeischen		if (isp->isp_clock) {
587113658Sdeischen			mbs.param[0] = MBOX_SET_CLOCK_RATE;
588113658Sdeischen			mbs.param[1] = isp->isp_clock;
589113658Sdeischen			isp_mboxcmd(isp, &mbs);
590113658Sdeischen			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
591113658Sdeischen				PRINTF("failed to set clockrate (0x%x)\n",
592113658Sdeischen				    mbs.param[0]);
593113786Sdeischen				/* but continue */
594113658Sdeischen			}
595113658Sdeischen		}
596113658Sdeischen	}
597113786Sdeischen	mbs.param[0] = MBOX_ABOUT_FIRMWARE;
598113786Sdeischen	isp_mboxcmd(isp, &mbs);
599113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
600113658Sdeischen		PRINTF("could not get f/w started (0x%x)\n", mbs.param[0]);
601113658Sdeischen		return;
602113658Sdeischen	}
603113658Sdeischen	CFGPRINTF("%s: Board Revision %s, %s F/W Revision %d.%d.%d\n",
604113658Sdeischen	    isp->isp_name, revname, dodnld? "loaded" : "resident",
605113658Sdeischen	    mbs.param[1], mbs.param[2], mbs.param[3]);
606113658Sdeischen	if (IS_FC(isp)) {
607113658Sdeischen		if (ISP_READ(isp, BIU2100_CSR) & BIU2100_PCI64) {
608113658Sdeischen			CFGPRINTF("%s: in 64-Bit PCI slot\n", isp->isp_name);
609113658Sdeischen		}
610106191Smini	}
611113786Sdeischen
612106191Smini	isp->isp_fwrev[0] = mbs.param[1];
613113786Sdeischen	isp->isp_fwrev[1] = mbs.param[2];
614113786Sdeischen	isp->isp_fwrev[2] = mbs.param[3];
615113786Sdeischen	if (isp->isp_romfw_rev[0] || isp->isp_romfw_rev[1] ||
616113658Sdeischen	    isp->isp_romfw_rev[2]) {
617113786Sdeischen		CFGPRINTF("%s: Last F/W revision was %d.%d.%d\n", isp->isp_name,
618113786Sdeischen		    isp->isp_romfw_rev[0], isp->isp_romfw_rev[1],
619113786Sdeischen		    isp->isp_romfw_rev[2]);
620113786Sdeischen	}
621113786Sdeischen
622113786Sdeischen	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
623113786Sdeischen	isp_mboxcmd(isp, &mbs);
624113786Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
625113786Sdeischen		PRINTF("%s: could not GET FIRMWARE STATUS\n", isp->isp_name);
626113786Sdeischen		return;
627113786Sdeischen	}
628113786Sdeischen	isp->isp_maxcmds = mbs.param[2];
629113786Sdeischen	CFGPRINTF("%s: %d max I/O commands supported\n",
630113786Sdeischen	    isp->isp_name, mbs.param[2]);
631113786Sdeischen	isp_fw_state(isp);
632113786Sdeischen
633113786Sdeischen	/*
634113786Sdeischen	 * Set up DMA for the request and result mailboxes.
635113786Sdeischen	 */
636113786Sdeischen	if (ISP_MBOXDMASETUP(isp) != 0) {
637113786Sdeischen		PRINTF("%s: can't setup dma mailboxes\n", isp->isp_name);
638113786Sdeischen		return;
639113786Sdeischen	}
640113786Sdeischen	isp->isp_state = ISP_RESETSTATE;
641113786Sdeischen
642113786Sdeischen	/*
643113786Sdeischen	 * Okay- now that we have new firmware running, we now (re)set our
644113786Sdeischen	 * notion of how many luns we support. This is somewhat tricky because
645113786Sdeischen	 * if we haven't loaded firmware, we don't have an easy way of telling
646113786Sdeischen	 * how many luns we support.
647113786Sdeischen	 *
648113786Sdeischen	 * We'll make a simplifying assumption- if we loaded firmware, we
649113786Sdeischen	 * are running with expanded lun firmware, otherwise not.
650113786Sdeischen	 *
651113786Sdeischen	 * Expanded lun firmware gives you 32 luns for SCSI cards and
652113786Sdeischen	 * 65536 luns for Fibre Channel cards.
653113786Sdeischen	 *
654113786Sdeischen	 * Because the lun is in a a different position in the Request Queue
655113786Sdeischen	 * Entry structure for Fibre Channel with expanded lun firmware, we
656113786Sdeischen	 * can only support one lun (lun zero) when we don't know what kind
657113786Sdeischen	 * of firmware we're running.
658113786Sdeischen	 *
659113786Sdeischen	 * Note that we only do this once (the first time thru isp_reset)
660113786Sdeischen	 * because we may be called again after firmware has been loaded once
661113786Sdeischen	 * and released.
662113658Sdeischen	 */
663113786Sdeischen	if (touched == 0) {
664113786Sdeischen		if (dodnld) {
665113658Sdeischen			if (IS_SCSI(isp)) {
666113786Sdeischen				isp->isp_maxluns = 32;
667113786Sdeischen			} else {
668113786Sdeischen				isp->isp_maxluns = 65536;
669113786Sdeischen			}
670113786Sdeischen		} else {
671113658Sdeischen			if (IS_SCSI(isp)) {
672113786Sdeischen				isp->isp_maxluns = 8;
673113658Sdeischen			} else {
674113786Sdeischen				PRINTF("%s: WARNING- cannot determine Expanded "
675113786Sdeischen				    "LUN capability- limiting to one LUN\n",
676113786Sdeischen				    isp->isp_name);
677113786Sdeischen				isp->isp_maxluns = 1;
678113786Sdeischen			}
679113786Sdeischen		}
680113786Sdeischen	}
681113786Sdeischen}
682113786Sdeischen
683113658Sdeischen/*
684106191Smini * Initialize Parameters of Hardware to a known state.
685113786Sdeischen *
686113786Sdeischen * Locks are held before coming here.
687113786Sdeischen */
688113658Sdeischen
689107202Sminivoid
690113658Sdeischenisp_init(isp)
691113658Sdeischen	struct ispsoftc *isp;
692107202Smini{
693113658Sdeischen	/*
694113658Sdeischen	 * Must do this first to get defaults established.
695107202Smini	 */
696113658Sdeischen	isp_setdfltparm(isp, 0);
697113658Sdeischen	if (IS_DUALBUS(isp)) {
698113658Sdeischen		isp_setdfltparm(isp, 1);
699113786Sdeischen	}
700113658Sdeischen
701113786Sdeischen	if (IS_FC(isp)) {
702113658Sdeischen		isp_fibre_init(isp);
703113786Sdeischen	} else {
704106191Smini		isp_scsi_init(isp);
705113658Sdeischen	}
706113658Sdeischen}
707113658Sdeischen
708113658Sdeischenstatic void
709106191Sminiisp_scsi_init(isp)
710113658Sdeischen	struct ispsoftc *isp;
711113658Sdeischen{
712113658Sdeischen	sdparam *sdp_chan0, *sdp_chan1;
713113658Sdeischen	mbreg_t mbs;
714113658Sdeischen
715113658Sdeischen	sdp_chan0 = isp->isp_param;
716106191Smini	sdp_chan1 = sdp_chan0;
717113658Sdeischen	if (IS_DUALBUS(isp)) {
718113658Sdeischen		sdp_chan1++;
719113658Sdeischen	}
720113658Sdeischen
721113658Sdeischen	/* First do overall per-card settings. */
722113658Sdeischen
723113786Sdeischen	/*
724113658Sdeischen	 * If we have fast memory timing enabled, turn it on.
725113658Sdeischen	 */
726113658Sdeischen	if (isp->isp_fast_mttr) {
727113870Sdeischen		ISP_WRITE(isp, RISC_MTR, 0x1313);
728113870Sdeischen	}
729113870Sdeischen
730113786Sdeischen	/*
731113786Sdeischen	 * Set Retry Delay and Count.
732113786Sdeischen	 * You set both channels at the same time.
733113786Sdeischen	 */
734113786Sdeischen	mbs.param[0] = MBOX_SET_RETRY_COUNT;
735113786Sdeischen	mbs.param[1] = sdp_chan0->isp_retry_count;
736113786Sdeischen	mbs.param[2] = sdp_chan0->isp_retry_delay;
737113786Sdeischen	mbs.param[6] = sdp_chan1->isp_retry_count;
738113786Sdeischen	mbs.param[7] = sdp_chan1->isp_retry_delay;
739113786Sdeischen
740113658Sdeischen	isp_mboxcmd(isp, &mbs);
741113870Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
742113870Sdeischen		PRINTF("%s: failed to set retry count and retry delay\n",
743113658Sdeischen		    isp->isp_name);
744113870Sdeischen		return;
745113658Sdeischen	}
746114187Sdeischen
747114187Sdeischen	/*
748114187Sdeischen	 * Set ASYNC DATA SETUP time. This is very important.
749114187Sdeischen	 */
750114187Sdeischen	mbs.param[0] = MBOX_SET_ASYNC_DATA_SETUP_TIME;
751114187Sdeischen	mbs.param[1] = sdp_chan0->isp_async_data_setup;
752114187Sdeischen	mbs.param[2] = sdp_chan1->isp_async_data_setup;
753114187Sdeischen	isp_mboxcmd(isp, &mbs);
754113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
755113658Sdeischen		PRINTF("%s: failed to set asynchronous data setup time\n",
756113658Sdeischen		    isp->isp_name);
757113658Sdeischen		return;
758113658Sdeischen	}
759114187Sdeischen
760113658Sdeischen	/*
761113658Sdeischen	 * Set ACTIVE Negation State.
762113658Sdeischen	 */
763113658Sdeischen	mbs.param[0] = MBOX_SET_ACT_NEG_STATE;
764113658Sdeischen	mbs.param[1] =
765113658Sdeischen	    (sdp_chan0->isp_req_ack_active_neg << 4) |
766113658Sdeischen	    (sdp_chan0->isp_data_line_active_neg << 5);
767113658Sdeischen	mbs.param[2] =
768113658Sdeischen	    (sdp_chan1->isp_req_ack_active_neg << 4) |
769106191Smini	    (sdp_chan1->isp_data_line_active_neg << 5);
770106191Smini
771113658Sdeischen	isp_mboxcmd(isp, &mbs);
772113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
77367097Sdeischen		PRINTF("%s: failed to set active negation state "
77435509Sjb		    "(%d,%d),(%d,%d)\n", isp->isp_name,
775113658Sdeischen		    sdp_chan0->isp_req_ack_active_neg,
77635509Sjb		    sdp_chan0->isp_data_line_active_neg,
777113658Sdeischen		    sdp_chan1->isp_req_ack_active_neg,
77813546Sjulian		    sdp_chan1->isp_data_line_active_neg);
779113658Sdeischen		/*
780113658Sdeischen		 * But don't return.
781113658Sdeischen		 */
782113658Sdeischen	}
783113658Sdeischen
784113658Sdeischen	/*
785113658Sdeischen	 * Set the Tag Aging limit
786113658Sdeischen	 */
787113658Sdeischen	mbs.param[0] = MBOX_SET_TAG_AGE_LIMIT;
788113658Sdeischen	mbs.param[1] = sdp_chan0->isp_tag_aging;
789113658Sdeischen	mbs.param[2] = sdp_chan1->isp_tag_aging;
790113658Sdeischen	isp_mboxcmd(isp, &mbs);
791113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
792114187Sdeischen		PRINTF("%s: failed to set tag age limit (%d,%d)\n",
793113658Sdeischen		    isp->isp_name, sdp_chan0->isp_tag_aging,
794113658Sdeischen		    sdp_chan1->isp_tag_aging);
795113658Sdeischen		return;
796113658Sdeischen	}
797113658Sdeischen
798113658Sdeischen	/*
799113658Sdeischen	 * Set selection timeout.
800114187Sdeischen	 */
801114187Sdeischen	mbs.param[0] = MBOX_SET_SELECT_TIMEOUT;
802114187Sdeischen	mbs.param[1] = sdp_chan0->isp_selection_timeout;
803114187Sdeischen	mbs.param[2] = sdp_chan1->isp_selection_timeout;
804114187Sdeischen	isp_mboxcmd(isp, &mbs);
805114187Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
806114187Sdeischen		PRINTF("%s: failed to set selection timeout\n", isp->isp_name);
807114187Sdeischen		return;
808113658Sdeischen	}
809113658Sdeischen
810103419Smini	/* now do per-channel settings */
811113658Sdeischen	isp_scsi_channel_init(isp, 0);
812113658Sdeischen	if (IS_DUALBUS(isp))
813113658Sdeischen		isp_scsi_channel_init(isp, 1);
81453812Salfred
815114187Sdeischen	/*
816114187Sdeischen	 * Now enable request/response queues
817113658Sdeischen	 */
818113658Sdeischen
819113658Sdeischen	mbs.param[0] = MBOX_INIT_RES_QUEUE;
820113658Sdeischen	mbs.param[1] = RESULT_QUEUE_LEN;
821113658Sdeischen	mbs.param[2] = DMA_MSW(isp->isp_result_dma);
822113658Sdeischen	mbs.param[3] = DMA_LSW(isp->isp_result_dma);
823113658Sdeischen	mbs.param[4] = 0;
824113658Sdeischen	mbs.param[5] = 0;
825113658Sdeischen	isp_mboxcmd(isp, &mbs);
826113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
827113658Sdeischen		PRINTF("%s: set of response queue failed\n", isp->isp_name);
828113658Sdeischen		return;
829113658Sdeischen	}
830113658Sdeischen	isp->isp_residx = 0;
831113786Sdeischen
832113786Sdeischen	mbs.param[0] = MBOX_INIT_REQ_QUEUE;
833113786Sdeischen	mbs.param[1] = RQUEST_QUEUE_LEN;
834113658Sdeischen	mbs.param[2] = DMA_MSW(isp->isp_rquest_dma);
835113658Sdeischen	mbs.param[3] = DMA_LSW(isp->isp_rquest_dma);
836113658Sdeischen	mbs.param[4] = 0;
837113658Sdeischen	mbs.param[5] = 0;
83867097Sdeischen	isp_mboxcmd(isp, &mbs);
839113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
840113658Sdeischen		PRINTF("%s: set of request queue failed\n", isp->isp_name);
841113658Sdeischen		return;
842113658Sdeischen	}
843113658Sdeischen	isp->isp_reqidx = isp->isp_reqodx = 0;
844113658Sdeischen
845113658Sdeischen	/*
846113658Sdeischen	 * Turn on Fast Posting, LVD transitions
847113658Sdeischen	 *
848113658Sdeischen	 * Ultra2 F/W always has had fast posting (and LVD transitions)
849113658Sdeischen	 *
850113658Sdeischen	 * Ultra and older (i.e., SBus) cards may not. It's just safer
851113658Sdeischen	 * to assume not for them.
852113658Sdeischen	 */
853113658Sdeischen
854113658Sdeischen	mbs.param[0] = MBOX_SET_FW_FEATURES;
855113658Sdeischen	mbs.param[1] = 0;
856113658Sdeischen	if (IS_ULTRA2(isp))
857113658Sdeischen		mbs.param[1] |= FW_FEATURE_LVD_NOTIFY;
858113658Sdeischen	if (IS_ULTRA2(isp) || IS_1240(isp))
859113658Sdeischen		mbs.param[1] |= FW_FEATURE_FAST_POST;
860113658Sdeischen	if (mbs.param[1] != 0) {
861113658Sdeischen		u_int16_t sfeat = mbs.param[1];
862113658Sdeischen		isp_mboxcmd(isp, &mbs);
863113658Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
864113658Sdeischen			PRINTF("%s: cannot enable FW features (0x%x)\n",
865113658Sdeischen			    isp->isp_name, sfeat);
866113658Sdeischen		} else {
867113658Sdeischen			CFGPRINTF("%s: enabled FW features (0x%x)\n",
868113658Sdeischen			    isp->isp_name, sfeat);
869113658Sdeischen		}
870113658Sdeischen	}
871113658Sdeischen
872113658Sdeischen	/*
873113658Sdeischen	 * Let the outer layers decide whether to issue a SCSI bus reset.
874113658Sdeischen	 */
875113658Sdeischen	isp->isp_state = ISP_INITSTATE;
876113658Sdeischen}
877113658Sdeischen
878113658Sdeischenstatic void
879113658Sdeischenisp_scsi_channel_init(isp, channel)
880113658Sdeischen	struct ispsoftc *isp;
881113658Sdeischen	int channel;
882113658Sdeischen{
883113658Sdeischen	sdparam *sdp;
884113658Sdeischen	mbreg_t mbs;
885113658Sdeischen	int tgt;
886113658Sdeischen
887113658Sdeischen	sdp = isp->isp_param;
888113658Sdeischen	sdp += channel;
889113658Sdeischen
890113658Sdeischen	/*
891113658Sdeischen	 * Set (possibly new) Initiator ID.
892113658Sdeischen	 */
893114187Sdeischen	mbs.param[0] = MBOX_SET_INIT_SCSI_ID;
894114187Sdeischen	mbs.param[1] = (channel << 7) | sdp->isp_initiator_id;
895113658Sdeischen	isp_mboxcmd(isp, &mbs);
896113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
897113658Sdeischen		PRINTF("%s: cannot set initiator id on bus %d to %d\n",
898113658Sdeischen		    isp->isp_name, channel, sdp->isp_initiator_id);
899113658Sdeischen		return;
900113658Sdeischen	}
901113658Sdeischen
902113658Sdeischen	/*
903113658Sdeischen	 * Set current per-target parameters to a safe minimum.
904113658Sdeischen	 */
905113661Sdeischen	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
906113658Sdeischen		int lun;
907113658Sdeischen		u_int16_t sdf;
908114187Sdeischen
909113658Sdeischen		if (sdp->isp_devparam[tgt].dev_enable == 0) {
910113658Sdeischen			IDPRINTF(1, ("%s: skipping target %d bus %d settings\n",
911114187Sdeischen			    isp->isp_name, tgt, channel));
912114187Sdeischen			continue;
913114187Sdeischen		}
914114187Sdeischen
915113658Sdeischen		/*
916113786Sdeischen		 * If we're in LVD mode, then we pretty much should
917113786Sdeischen		 * only disable tagged queuing.
918113786Sdeischen		 */
919113786Sdeischen		if (IS_ULTRA2(isp) && sdp->isp_lvdmode) {
920113658Sdeischen			sdf = DPARM_DEFAULT & ~DPARM_TQING;
921113658Sdeischen		} else {
922113658Sdeischen			int rvf = ISP_FW_REVX(isp->isp_fwrev);
923114187Sdeischen			sdf = DPARM_SAFE_DFLT;
924114187Sdeischen
925114187Sdeischen			/*
926114187Sdeischen			 * It is not quite clear when this changed over so that
927114187Sdeischen			 * we could force narrow and async, so assume >= 7.55
928114187Sdeischen			 * for i/t F/W and = 4.55 for initiator f/w.
929114187Sdeischen			 */
930113658Sdeischen			if ((ISP_FW_REV(4, 55, 0) <= rvf &&
931113658Sdeischen			    (ISP_FW_REV(5, 0, 0) > rvf)) ||
932113658Sdeischen			    (ISP_FW_REV(7, 55, 0) <= rvf)) {
933113658Sdeischen				sdf |= DPARM_NARROW | DPARM_ASYNC;
934113658Sdeischen			}
93567097Sdeischen		}
93648046Sjb		mbs.param[0] = MBOX_SET_TARGET_PARAMS;
937113658Sdeischen		mbs.param[1] = (tgt << 8) | (channel << 15);
938113658Sdeischen		mbs.param[2] = sdf;
93967097Sdeischen		mbs.param[3] =
940113658Sdeischen		    (sdp->isp_devparam[tgt].sync_offset << 8) |
941113658Sdeischen		    (sdp->isp_devparam[tgt].sync_period);
94267097Sdeischen		isp_mboxcmd(isp, &mbs);
943113658Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
944113658Sdeischen			sdf = DPARM_SAFE_DFLT;
945113658Sdeischen			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
946113658Sdeischen			mbs.param[1] = (tgt << 8) | (channel << 15);
947113658Sdeischen			mbs.param[2] = sdf;
948113658Sdeischen			mbs.param[3] =
949113658Sdeischen			    (sdp->isp_devparam[tgt].sync_offset << 8) |
950113658Sdeischen			    (sdp->isp_devparam[tgt].sync_period);
951113658Sdeischen			isp_mboxcmd(isp, &mbs);
952113658Sdeischen			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
953113658Sdeischen				PRINTF("%s: failed even to set defaults for "
954113658Sdeischen				    "target %d\n", isp->isp_name, tgt);
955113658Sdeischen				continue;
956113658Sdeischen			}
957113658Sdeischen		}
958113658Sdeischen
959113658Sdeischen#if	0
960113658Sdeischen		/*
961113658Sdeischen		 * We don't update dev_flags with what we've set
962113658Sdeischen		 * because that's not the ultimate goal setting.
963113658Sdeischen		 * If we succeed with the command, we *do* update
964113658Sdeischen		 * cur_dflags by getting target parameters.
965113658Sdeischen		 */
966113658Sdeischen		mbs.param[0] = MBOX_GET_TARGET_PARAMS;
967103419Smini		mbs.param[1] = (tgt << 8) | (channel << 15);
968113658Sdeischen		isp_mboxcmd(isp, &mbs);
969113658Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
970113658Sdeischen			/*
971113658Sdeischen			 * Urrr.... We'll set cur_dflags to DPARM_SAFE_DFLT so
97213546Sjulian			 * we don't try and do tags if tags aren't enabled.
973113658Sdeischen			 */
974113658Sdeischen			sdp->isp_devparam[tgt].cur_dflags = DPARM_SAFE_DFLT;
975113658Sdeischen		} else {
976113658Sdeischen			sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
977113658Sdeischen			sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
978113658Sdeischen			sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
979113658Sdeischen		}
980113658Sdeischen		IDPRINTF(3, ("%s: set flags 0x%x got 0x%x back for target %d\n",
981113658Sdeischen		    isp->isp_name, sdf, mbs.param[2], tgt));
982113658Sdeischen
983113658Sdeischen#else
984113658Sdeischen		/*
985106191Smini		 * We don't update any information because we need to run
986113658Sdeischen		 * at least one command per target to cause a new state
987113658Sdeischen		 * to be latched.
988113658Sdeischen		 */
989113658Sdeischen#endif
990106191Smini		/*
991113658Sdeischen		 * Ensure that we don't believe tagged queuing is enabled yet.
992113658Sdeischen		 * It turns out that sometimes the ISP just ignores our
993113658Sdeischen		 * attempts to set parameters for devices that it hasn't
994114187Sdeischen		 * seen yet.
995113658Sdeischen		 */
996113658Sdeischen		sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
997113658Sdeischen		for (lun = 0; lun < isp->isp_maxluns; lun++) {
998114187Sdeischen			mbs.param[0] = MBOX_SET_DEV_QUEUE_PARAMS;
999113658Sdeischen			mbs.param[1] = (channel << 15) | (tgt << 8) | lun;
1000113658Sdeischen			mbs.param[2] = sdp->isp_max_queue_depth;
1001113658Sdeischen			mbs.param[3] = sdp->isp_devparam[tgt].exc_throttle;
1002113658Sdeischen			isp_mboxcmd(isp, &mbs);
1003113658Sdeischen			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1004113658Sdeischen				PRINTF("%s: failed to set device queue "
1005113658Sdeischen				    "parameters for target %d, lun %d\n",
1006113658Sdeischen				    isp->isp_name, tgt, lun);
1007113658Sdeischen				break;
1008113658Sdeischen			}
1009113658Sdeischen		}
1010113658Sdeischen	}
1011113658Sdeischen}
1012113658Sdeischen
1013113658Sdeischen/*
1014113658Sdeischen * Fibre Channel specific initialization.
1015113658Sdeischen *
1016113658Sdeischen * Locks are held before coming here.
1017113658Sdeischen */
1018113658Sdeischenstatic void
1019113658Sdeischenisp_fibre_init(isp)
1020113658Sdeischen	struct ispsoftc *isp;
1021113658Sdeischen{
1022113658Sdeischen	fcparam *fcp;
1023113658Sdeischen	isp_icb_t *icbp;
1024113658Sdeischen	mbreg_t mbs;
1025113658Sdeischen	int loopid;
1026113658Sdeischen
1027113658Sdeischen	fcp = isp->isp_param;
1028113658Sdeischen
1029106786Smini	/*
103013546Sjulian	 * For systems that don't have BIOS methods for which
1031113658Sdeischen	 * we can easily change the NVRAM based loopid, we'll
1032113658Sdeischen	 * override that here. Note that when we initialize
103313546Sjulian	 * the firmware we may get back a different loopid than
1034113661Sdeischen	 * we asked for anyway. XXX This is probably not the
1035113661Sdeischen	 * best way to figure this out XXX
1036113661Sdeischen	 */
1037113661Sdeischen#ifndef	__i386__
1038113661Sdeischen	loopid = DEFAULT_LOOPID(isp);
1039113661Sdeischen#else
1040113661Sdeischen	loopid = fcp->isp_loopid;
1041113661Sdeischen#endif
1042113661Sdeischen
1043113661Sdeischen	icbp = (isp_icb_t *) fcp->isp_scratch;
1044113661Sdeischen	MEMZERO(icbp, sizeof (*icbp));
1045113661Sdeischen
1046113661Sdeischen	icbp->icb_version = ICB_VERSION1;
1047113658Sdeischen#ifdef	ISP_TARGET_MODE
1048113661Sdeischen	fcp->isp_fwoptions = ICBOPT_TGT_ENABLE;
1049113661Sdeischen#else
1050113661Sdeischen	fcp->isp_fwoptions = 0;
1051113661Sdeischen#endif
1052113661Sdeischen	fcp->isp_fwoptions |= ICBOPT_FAIRNESS;
1053113661Sdeischen	/*
1054113661Sdeischen	 * If this is a 2100 < revision 5, we have to turn off FAIRNESS.
1055113658Sdeischen	 */
1056113661Sdeischen	if ((isp->isp_type == ISP_HA_FC_2100) && isp->isp_revision < 5) {
1057113658Sdeischen		fcp->isp_fwoptions &= ~ICBOPT_FAIRNESS;
1058113661Sdeischen	}
1059113658Sdeischen	fcp->isp_fwoptions |= ICBOPT_PDBCHANGE_AE;
106067097Sdeischen	fcp->isp_fwoptions |= ICBOPT_HARD_ADDRESS;
1061113658Sdeischen	/*
1062113661Sdeischen	 * We have to use FULL LOGIN even though it resets the loop too much
1063113658Sdeischen	 * because otherwise port database entries don't get updated after
1064113661Sdeischen	 * a LIP- this is a known f/w bug for 2100 f/w less than 1.17.0.
1065113661Sdeischen	 */
1066113786Sdeischen	if (ISP_FW_REVX(isp->isp_fwrev) < ISP_FW_REV(1, 17, 0)) {
1067106786Smini		fcp->isp_fwoptions |= ICBOPT_FULL_LOGIN;
1068113786Sdeischen	}
1069113661Sdeischen#ifndef	ISP_NO_FASTPOST_FC
1070113661Sdeischen	fcp->isp_fwoptions |= ICBOPT_FAST_POST;
1071113661Sdeischen#endif
1072113661Sdeischen	if (isp->isp_confopts & ISP_CFG_FULL_DUPLEX)
1073113661Sdeischen		fcp->isp_fwoptions |= ICBOPT_FULL_DUPLEX;
1074113661Sdeischen
1075113661Sdeischen	/*
1076113661Sdeischen	 * We don't set ICBOPT_PORTNAME because we want our
1077113661Sdeischen	 * Node Name && Port Names to be distinct.
1078113661Sdeischen	 */
1079113661Sdeischen
1080113661Sdeischen	icbp->icb_fwoptions = fcp->isp_fwoptions;
1081113661Sdeischen	icbp->icb_maxfrmlen = fcp->isp_maxfrmlen;
1082113661Sdeischen	if (icbp->icb_maxfrmlen < ICB_MIN_FRMLEN ||
1083113661Sdeischen	    icbp->icb_maxfrmlen > ICB_MAX_FRMLEN) {
1084113661Sdeischen		PRINTF("%s: bad frame length (%d) from NVRAM- using %d\n",
1085113661Sdeischen		    isp->isp_name, fcp->isp_maxfrmlen, ICB_DFLT_FRMLEN);
1086113661Sdeischen		icbp->icb_maxfrmlen = ICB_DFLT_FRMLEN;
1087113661Sdeischen	}
1088113786Sdeischen	icbp->icb_maxalloc = fcp->isp_maxalloc;
1089113786Sdeischen	if (icbp->icb_maxalloc < 1) {
1090113786Sdeischen		PRINTF("%s: bad maximum allocation (%d)- using 16\n",
1091113786Sdeischen		     isp->isp_name, fcp->isp_maxalloc);
1092113786Sdeischen		icbp->icb_maxalloc = 16;
1093113658Sdeischen	}
1094113786Sdeischen	icbp->icb_execthrottle = fcp->isp_execthrottle;
1095113786Sdeischen	if (icbp->icb_execthrottle < 1) {
1096113786Sdeischen		PRINTF("%s: bad execution throttle of %d- using 16\n",
1097113786Sdeischen		    isp->isp_name, fcp->isp_execthrottle);
1098113786Sdeischen		icbp->icb_execthrottle = ICB_DFLT_THROTTLE;
1099113661Sdeischen	}
1100113786Sdeischen	icbp->icb_retry_delay = fcp->isp_retry_delay;
1101113786Sdeischen	icbp->icb_retry_count = fcp->isp_retry_count;
1102113786Sdeischen	icbp->icb_hardaddr = loopid;
1103113786Sdeischen#ifdef	PRET_A_PORTE
1104113786Sdeischen	if (IS_2200(isp)) {
1105113786Sdeischen		icbp->icb_fwoptions |= ICBOPT_EXTENDED;
1106113786Sdeischen		/*
1107114187Sdeischen		 * Prefer or force Point-To-Point instead Loop?
1108113786Sdeischen		 */
1109113786Sdeischen		if (isp->isp_confopts & ISP_CFG_NPORT)
1110113786Sdeischen			icbp->icb_xfwoptions = ICBXOPT_PTP_2_LOOP;
1111113786Sdeischen		else
1112113786Sdeischen			icbp->icb_xfwoptions = ICBXOPT_LOOP_2_PTP;
1113113658Sdeischen	}
1114113786Sdeischen#endif
1115113786Sdeischen	icbp->icb_logintime = 60;	/* 60 second login timeout */
1116113786Sdeischen
1117113661Sdeischen	if (fcp->isp_nodewwn) {
1118113786Sdeischen		MAKE_NODE_NAME_FROM_WWN(icbp->icb_nodename, fcp->isp_nodewwn);
1119113661Sdeischen		MAKE_NODE_NAME_FROM_WWN(icbp->icb_portname, fcp->isp_portwwn);
1120113661Sdeischen	} else {
1121113870Sdeischen		fcp->isp_fwoptions &= ~(ICBOPT_USE_PORTNAME|ICBOPT_FULL_LOGIN);
1122113661Sdeischen	}
1123113661Sdeischen	icbp->icb_rqstqlen = RQUEST_QUEUE_LEN;
1124113658Sdeischen	icbp->icb_rsltqlen = RESULT_QUEUE_LEN;
1125113786Sdeischen	icbp->icb_rqstaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_rquest_dma);
1126113786Sdeischen	icbp->icb_rqstaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_rquest_dma);
1127113658Sdeischen	icbp->icb_respaddr[RQRSP_ADDR0015] = DMA_LSW(isp->isp_result_dma);
1128113658Sdeischen	icbp->icb_respaddr[RQRSP_ADDR1631] = DMA_MSW(isp->isp_result_dma);
1129106786Smini	ISP_SWIZZLE_ICB(isp, icbp);
1130113658Sdeischen
1131113658Sdeischen	/*
1132113658Sdeischen	 * Do this *before* initializing the firmware.
1133113658Sdeischen	 */
1134113870Sdeischen	isp_mark_getpdb_all(isp);
1135113658Sdeischen	fcp->isp_fwstate = FW_CONFIG_WAIT;
1136113658Sdeischen	fcp->isp_loopstate = LOOP_NIL;
1137113658Sdeischen
1138113658Sdeischen	MemoryBarrier();
1139113658Sdeischen	for (;;) {
1140113870Sdeischen		mbs.param[0] = MBOX_INIT_FIRMWARE;
1141113658Sdeischen		mbs.param[1] = 0;
1142113658Sdeischen		mbs.param[2] = DMA_MSW(fcp->isp_scdma);
1143113658Sdeischen		mbs.param[3] = DMA_LSW(fcp->isp_scdma);
1144113658Sdeischen		mbs.param[4] = 0;
1145113658Sdeischen		mbs.param[5] = 0;
1146113658Sdeischen		mbs.param[6] = 0;
1147113786Sdeischen		mbs.param[7] = 0;
1148113786Sdeischen		isp_mboxcmd(isp, &mbs);
1149113786Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1150113786Sdeischen			PRINTF("%s: INIT FIRMWARE failed (code 0x%x)\n",
1151113786Sdeischen			    isp->isp_name, mbs.param[0]);
1152113786Sdeischen			if (mbs.param[0] & 0x8000) {
1153113786Sdeischen				SYS_DELAY(1000);
1154113658Sdeischen				continue;
1155113658Sdeischen			}
1156113658Sdeischen			return;
1157113658Sdeischen		}
1158113658Sdeischen		break;
1159113786Sdeischen	}
1160113786Sdeischen
1161113870Sdeischen	isp->isp_reqidx = isp->isp_reqodx = 0;
1162113658Sdeischen	isp->isp_residx = 0;
1163113658Sdeischen	isp->isp_sendmarker = 1;
1164113786Sdeischen
1165113786Sdeischen	/*
1166113786Sdeischen	 * Whatever happens, we're now committed to being here.
1167113881Sdeischen	 */
1168113786Sdeischen	isp->isp_state = ISP_INITSTATE;
1169113658Sdeischen}
1170113658Sdeischen
1171113658Sdeischen/*
1172113658Sdeischen * Fibre Channel Support- get the port database for the id.
1173113658Sdeischen *
1174113658Sdeischen * Locks are held before coming here. Return 0 if success,
1175113786Sdeischen * else failure.
1176113870Sdeischen */
1177113870Sdeischen
1178113870Sdeischenstatic void
1179113658Sdeischenisp_mark_getpdb_all(isp)
1180113658Sdeischen	struct ispsoftc *isp;
1181113658Sdeischen{
1182113658Sdeischen	fcparam *fcp = (fcparam *) isp->isp_param;
1183113658Sdeischen	int i;
1184113658Sdeischen	for (i = 0; i < MAX_FC_TARG; i++) {
1185113658Sdeischen		fcp->portdb[i].valid = 0;
1186113658Sdeischen	}
1187113658Sdeischen}
1188113658Sdeischen
1189113658Sdeischenstatic int
1190113658Sdeischenisp_getpdb(isp, id, pdbp)
1191113658Sdeischen	struct ispsoftc *isp;
1192113658Sdeischen	int id;
1193113658Sdeischen	isp_pdb_t *pdbp;
119413546Sjulian{
1195113658Sdeischen	fcparam *fcp = (fcparam *) isp->isp_param;
1196113658Sdeischen	mbreg_t mbs;
1197103419Smini
1198113658Sdeischen	mbs.param[0] = MBOX_GET_PORT_DB;
1199113786Sdeischen	mbs.param[1] = id << 8;
1200113786Sdeischen	mbs.param[2] = DMA_MSW(fcp->isp_scdma);
1201113786Sdeischen	mbs.param[3] = DMA_LSW(fcp->isp_scdma);
1202113658Sdeischen	/*
1203113658Sdeischen	 * Unneeded. For the 2100, except for initializing f/w, registers
1204113658Sdeischen	 * 4/5 have to not be written to.
1205113658Sdeischen	 *	mbs.param[4] = 0;
1206113658Sdeischen	 *	mbs.param[5] = 0;
1207113658Sdeischen	 *
1208113658Sdeischen	 */
1209114187Sdeischen	mbs.param[6] = 0;
1210103419Smini	mbs.param[7] = 0;
1211113658Sdeischen	isp_mboxcmd(isp, &mbs);
121213546Sjulian	switch (mbs.param[0]) {
1213114187Sdeischen	case MBOX_COMMAND_COMPLETE:
121448046Sjb		MemoryBarrier();
1215113870Sdeischen		ISP_UNSWIZZLE_AND_COPY_PDBP(isp, pdbp, fcp->isp_scratch);
1216113658Sdeischen		break;
1217113870Sdeischen	case MBOX_HOST_INTERFACE_ERROR:
1218113658Sdeischen		PRINTF("%s: DMA error getting port database\n", isp->isp_name);
121913546Sjulian		return (-1);
1220113658Sdeischen	case MBOX_COMMAND_PARAM_ERROR:
1221113658Sdeischen		/* Not Logged In */
1222113658Sdeischen		IDPRINTF(3, ("%s: Param Error on Get Port Database for id %d\n",
1223113658Sdeischen		    isp->isp_name, id));
1224113658Sdeischen		return (-1);
1225113658Sdeischen	default:
1226113658Sdeischen		PRINTF("%s: error 0x%x getting port database for ID %d\n",
1227113658Sdeischen		    isp->isp_name, mbs.param[0], id);
1228113658Sdeischen		return (-1);
1229113658Sdeischen	}
1230113658Sdeischen	return (0);
1231113658Sdeischen}
1232113658Sdeischen
1233113658Sdeischenstatic u_int64_t
1234113658Sdeischenisp_get_portname(isp, loopid, nodename)
1235113658Sdeischen	struct ispsoftc *isp;
1236113658Sdeischen	int loopid;
1237113658Sdeischen	int nodename;
1238113658Sdeischen{
1239113658Sdeischen	u_int64_t wwn = 0;
1240113658Sdeischen	mbreg_t mbs;
1241113658Sdeischen
1242113658Sdeischen	mbs.param[0] = MBOX_GET_PORT_NAME;
1243113658Sdeischen	mbs.param[1] = loopid << 8;
1244113658Sdeischen	if (nodename)
1245113658Sdeischen		mbs.param[1] |= 1;
1246113658Sdeischen	isp_mboxcmd(isp, &mbs);
1247113658Sdeischen	if (mbs.param[0] == MBOX_COMMAND_COMPLETE) {
1248113658Sdeischen		wwn =
1249113658Sdeischen		    (((u_int64_t)(mbs.param[2] & 0xff)) << 56) |
1250113658Sdeischen		    (((u_int64_t)(mbs.param[2] >> 8))	<< 48) |
1251113658Sdeischen		    (((u_int64_t)(mbs.param[3] & 0xff))	<< 40) |
1252113658Sdeischen		    (((u_int64_t)(mbs.param[3] >> 8))	<< 32) |
1253113658Sdeischen		    (((u_int64_t)(mbs.param[6] & 0xff))	<< 24) |
1254113658Sdeischen		    (((u_int64_t)(mbs.param[6] >> 8))	<< 16) |
1255113658Sdeischen		    (((u_int64_t)(mbs.param[7] & 0xff))	<<  8) |
1256113658Sdeischen		    (((u_int64_t)(mbs.param[7] >> 8)));
1257113658Sdeischen	}
1258113658Sdeischen	return (wwn);
1259113658Sdeischen}
1260113658Sdeischen
1261113658Sdeischen/*
1262113658Sdeischen * Make sure we have good FC link and know our Loop ID.
1263113658Sdeischen */
1264113658Sdeischen
1265113658Sdeischenstatic int
1266113658Sdeischenisp_fclink_test(isp, waitdelay)
1267113658Sdeischen	struct ispsoftc *isp;
1268113658Sdeischen	int waitdelay;
1269113658Sdeischen{
1270113658Sdeischen	static char *toponames[] = {
1271113658Sdeischen		"Private Loop",
1272113658Sdeischen		"FL Port",
1273113658Sdeischen		"N-Port to N-Port",
1274113658Sdeischen		"F Port",
1275113658Sdeischen		"F Port (no FLOGI_ACC response)"
1276113658Sdeischen	};
1277113658Sdeischen	mbreg_t mbs;
1278113658Sdeischen	int count;
1279113658Sdeischen	u_int8_t lwfs;
1280113658Sdeischen	fcparam *fcp;
1281113658Sdeischen#if	defined(ISP2100_FABRIC)
1282113658Sdeischen	isp_pdb_t pdb;
1283113658Sdeischen#endif
1284113658Sdeischen	fcp = isp->isp_param;
1285113658Sdeischen
1286113658Sdeischen	/*
1287113658Sdeischen	 * Wait up to N microseconds for F/W to go to a ready state.
1288113658Sdeischen	 */
1289113658Sdeischen	lwfs = FW_CONFIG_WAIT;
1290113658Sdeischen	for (count = 0; count < waitdelay; count += 100) {
1291113658Sdeischen		isp_fw_state(isp);
1292113658Sdeischen		if (lwfs != fcp->isp_fwstate) {
1293113658Sdeischen			PRINTF("%s: Firmware State %s -> %s\n",
1294113658Sdeischen			    isp->isp_name, isp2100_fw_statename((int)lwfs),
1295113658Sdeischen			    isp2100_fw_statename((int)fcp->isp_fwstate));
1296113658Sdeischen			lwfs = fcp->isp_fwstate;
1297113658Sdeischen		}
1298113658Sdeischen		if (fcp->isp_fwstate == FW_READY) {
1299113658Sdeischen			break;
1300113658Sdeischen		}
1301113658Sdeischen		SYS_DELAY(100);	/* wait 100 microseconds */
1302113658Sdeischen	}
1303113658Sdeischen
1304113658Sdeischen	/*
1305113658Sdeischen	 * If we haven't gone to 'ready' state, return.
1306113658Sdeischen	 */
1307113658Sdeischen	if (fcp->isp_fwstate != FW_READY) {
1308113658Sdeischen		return (-1);
1309113658Sdeischen	}
1310113658Sdeischen
1311113658Sdeischen	/*
1312113658Sdeischen	 * Get our Loop ID (if possible). We really need to have it.
1313113658Sdeischen	 */
1314113658Sdeischen	mbs.param[0] = MBOX_GET_LOOP_ID;
1315113658Sdeischen	isp_mboxcmd(isp, &mbs);
1316113658Sdeischen	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1317113658Sdeischen		PRINTF("%s: GET LOOP ID failed\n", isp->isp_name);
1318113658Sdeischen		return (-1);
1319113658Sdeischen	}
1320113658Sdeischen	fcp->isp_loopid = mbs.param[1];
1321113658Sdeischen	if (IS_2200(isp)) {
1322113658Sdeischen		int topo = (int) mbs.param[6];
1323113658Sdeischen		if (topo < TOPO_NL_PORT || topo > TOPO_PTP_STUB)
1324113658Sdeischen			topo = TOPO_PTP_STUB;
1325113658Sdeischen		fcp->isp_topo = topo;
1326113658Sdeischen	} else {
1327113658Sdeischen		fcp->isp_topo = TOPO_NL_PORT;
1328113658Sdeischen	}
1329113658Sdeischen	fcp->isp_alpa = mbs.param[2];
1330113658Sdeischen
1331113658Sdeischen#if	defined(ISP2100_FABRIC)
1332113658Sdeischen	fcp->isp_onfabric = 0;
1333113658Sdeischen	if (fcp->isp_topo != TOPO_N_PORT &&
1334113658Sdeischen	    isp_getpdb(isp, FL_PORT_ID, &pdb) == 0) {
1335113658Sdeischen		struct lportdb *lp;
1336113658Sdeischen		if (IS_2100(isp)) {
1337113658Sdeischen			fcp->isp_topo = TOPO_FL_PORT;
1338113658Sdeischen		}
1339113658Sdeischen		fcp->isp_portid = mbs.param[2] | (((int)mbs.param[3]) << 16);
1340113658Sdeischen		fcp->isp_onfabric = 1;
1341113658Sdeischen
1342113658Sdeischen		/*
1343113658Sdeischen		 * Save the Fabric controller's port database entry.
1344113658Sdeischen		 */
1345113658Sdeischen		lp = &fcp->portdb[FL_PORT_ID];
1346113658Sdeischen		lp->node_wwn =
1347113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1348113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1349113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1350113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1351113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1352113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1353113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1354113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[7]));
1355113658Sdeischen		lp->port_wwn =
1356113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1357113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1358113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1359113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1360113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1361113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1362113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1363114187Sdeischen		    (((u_int64_t)pdb.pdb_portname[7]));
1364114187Sdeischen		lp->roles =
1365113658Sdeischen		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1366113658Sdeischen		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
136748046Sjb		lp->loopid = pdb.pdb_loopid;
1368113658Sdeischen		lp->loggedin = lp->valid = 1;
1369113658Sdeischen#if	0
137013546Sjulian		if (isp->isp_rfabric == 0) {
1371113658Sdeischen			isp_i_register_fc4_type(isp);
1372113658Sdeischen		}
1373113658Sdeischen#endif
1374113658Sdeischen	} else
1375113658Sdeischen#endif
1376113658Sdeischen	{
1377113658Sdeischen		fcp->isp_portid = mbs.param[2];
1378113658Sdeischen		fcp->isp_onfabric = 0;
1379113658Sdeischen#if	0
1380113658Sdeischen		isp->isp_rfabric = 0;
1381113658Sdeischen#endif
1382113658Sdeischen		fcp->portdb[FL_PORT_ID].valid = 0;
1383113658Sdeischen	}
1384113658Sdeischen
1385114187Sdeischen	CFGPRINTF("%s: Loop ID %d, AL_PA 0x%x, Port ID 0x%x Loop State "
1386114187Sdeischen	    "0x%x topology '%s'\n", isp->isp_name, fcp->isp_loopid,
1387113658Sdeischen	    fcp->isp_alpa, fcp->isp_portid, fcp->isp_loopstate,
1388113658Sdeischen	    toponames[fcp->isp_topo]);
1389113658Sdeischen
139013546Sjulian	return (0);
1391113658Sdeischen}
1392113658Sdeischen
1393113658Sdeischen/*
139448046Sjb * Compare two local port db entities and return 1 if they're the same, else 0.
1395113658Sdeischen */
1396113658Sdeischen
1397113658Sdeischenstatic int
1398113658Sdeischenisp_same_lportdb(a, b)
1399113658Sdeischen	struct lportdb *a, *b;
140013546Sjulian{
1401113658Sdeischen	/*
140213546Sjulian	 * We decide two lports are the same if they have non-zero and
1403113658Sdeischen	 * identical port WWNs and identical loop IDs.
140413546Sjulian	 */
1405113658Sdeischen
1406113658Sdeischen	if (a->port_wwn == 0 || a->port_wwn != b->port_wwn ||
1407113658Sdeischen	    a->loopid != b->loopid || a->roles != b->roles) {
1408113658Sdeischen		return (0);
1409113658Sdeischen	} else {
1410113658Sdeischen		return (1);
1411113658Sdeischen	}
1412113658Sdeischen}
141313546Sjulian
1414113658Sdeischen/*
1415113658Sdeischen * Synchronize our soft copy of the port database with what the f/w thinks
1416113658Sdeischen * (with a view toward possibly for a specific target....)
1417113658Sdeischen */
1418113658Sdeischen
1419113658Sdeischenstatic int
1420113658Sdeischenisp_pdb_sync(isp, target)
142113546Sjulian	struct ispsoftc *isp;
1422113658Sdeischen	int target;
142313546Sjulian{
1424113658Sdeischen	struct lportdb *lp, *tport;
1425113658Sdeischen	fcparam *fcp = isp->isp_param;
142613546Sjulian	isp_pdb_t pdb;
1427113658Sdeischen	int loopid, prange, lim;
1428113658Sdeischen
1429113658Sdeischen#ifdef	ISP2100_FABRIC
1430113658Sdeischen	/*
1431113658Sdeischen	 * XXX: If we do this *after* building up our local port database,
1432113658Sdeischen	 * XXX: the commands simply don't work.
1433113658Sdeischen	 */
1434106191Smini	/*
1435113658Sdeischen	 * (Re)discover all fabric devices
1436113658Sdeischen	 */
1437113658Sdeischen	if (fcp->isp_onfabric)
1438113658Sdeischen		(void) isp_scan_fabric(isp);
1439113658Sdeischen#endif
1440113658Sdeischen
1441113658Sdeischen
1442113658Sdeischen	switch (fcp->isp_topo) {
1443113658Sdeischen	case TOPO_F_PORT:
1444113658Sdeischen	case TOPO_PTP_STUB:
1445113658Sdeischen		prange = 0;
1446113658Sdeischen		break;
1447113658Sdeischen	case TOPO_N_PORT:
1448106786Smini		prange = 2;
1449113658Sdeischen		break;
1450106786Smini	default:
1451113658Sdeischen		prange = FL_PORT_ID;
1452113658Sdeischen		break;
1453113658Sdeischen	}
1454106786Smini
1455113658Sdeischen	/*
1456113658Sdeischen	 * Run through the local loop ports and get port database info
1457113658Sdeischen	 * for each loop ID.
1458113658Sdeischen	 *
1459113658Sdeischen	 * There's a somewhat unexplained situation where the f/w passes back
1460113658Sdeischen	 * the wrong database entity- if that happens, just restart (up to
1461113658Sdeischen	 * FL_PORT_ID times).
1462113658Sdeischen	 */
1463113658Sdeischen	tport = fcp->tport;
146413546Sjulian
146513546Sjulian	/*
1466113658Sdeischen	 * make sure the temp port database is clean...
1467113658Sdeischen	 */
146813546Sjulian	MEMZERO((void *) tport, sizeof (tport));
146913546Sjulian
1470113658Sdeischen	for (lim = loopid = 0; loopid < prange; loopid++) {
1471113658Sdeischen		lp = &tport[loopid];
1472113658Sdeischen		lp->node_wwn = isp_get_portname(isp, loopid, 1);
1473113658Sdeischen		if (fcp->isp_loopstate != LOOP_PDB_RCVD)
1474113658Sdeischen			return (-1);
1475113658Sdeischen		if (lp->node_wwn == 0)
1476113658Sdeischen			continue;
1477113786Sdeischen		lp->port_wwn = isp_get_portname(isp, loopid, 0);
147813546Sjulian		if (fcp->isp_loopstate != LOOP_PDB_RCVD)
1479113786Sdeischen			return (-1);
1480113786Sdeischen		if (lp->port_wwn == 0) {
148171581Sdeischen			lp->node_wwn = 0;
1482113786Sdeischen			continue;
148348046Sjb		}
1484113786Sdeischen
1485113870Sdeischen		/*
1486113870Sdeischen		 * Get an entry....
1487113786Sdeischen		 */
1488113786Sdeischen		if (isp_getpdb(isp, loopid, &pdb) != 0) {
1489113786Sdeischen			if (fcp->isp_loopstate != LOOP_PDB_RCVD)
1490113870Sdeischen				return (-1);
1491113870Sdeischen			continue;
1492113658Sdeischen		}
1493113658Sdeischen
1494113658Sdeischen		if (fcp->isp_loopstate != LOOP_PDB_RCVD)
1495113786Sdeischen			return (-1);
1496113786Sdeischen
1497114187Sdeischen		/*
1498114187Sdeischen		 * If the returned database element doesn't match what we
1499113786Sdeischen		 * asked for, restart the process entirely (up to a point...).
1500113786Sdeischen		 */
1501113786Sdeischen		if (pdb.pdb_loopid != loopid) {
1502113786Sdeischen			IDPRINTF(1, ("%s: wankage (%d != %d)\n",
1503113786Sdeischen			    isp->isp_name, pdb.pdb_loopid, loopid));
1504113786Sdeischen			loopid = 0;
1505114187Sdeischen			if (lim++ < FL_PORT_ID) {
1506114187Sdeischen				continue;
1507114187Sdeischen			}
1508114187Sdeischen			PRINTF("%s: giving up on synchronizing the port "
1509113786Sdeischen			    "database\n", isp->isp_name);
151013546Sjulian			return (-1);
151113546Sjulian		}
1512113658Sdeischen
1513113658Sdeischen		/*
1514113658Sdeischen		 * Save the pertinent info locally.
1515113658Sdeischen		 */
1516113658Sdeischen		lp->node_wwn =
1517113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
151841164Sjb		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1519113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1520113661Sdeischen		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
152171581Sdeischen		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1522113661Sdeischen		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1523113661Sdeischen		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
152448046Sjb		    (((u_int64_t)pdb.pdb_nodename[7]));
1525113661Sdeischen		lp->port_wwn =
152648046Sjb		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1527113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1528113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1529113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1530113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1531113870Sdeischen		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1532113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1533113661Sdeischen		    (((u_int64_t)pdb.pdb_portname[7]));
1534113661Sdeischen		lp->roles =
1535113661Sdeischen		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1536113658Sdeischen		lp->portid = BITS2WORD(pdb.pdb_portid_bits);
1537113661Sdeischen		lp->loopid = pdb.pdb_loopid;
1538113661Sdeischen		/*
1539113661Sdeischen		 * Do a quick check to see whether this matches the saved port
1540114187Sdeischen		 * database for the same loopid. We do this here to save
1541113661Sdeischen		 * searching later (if possible). Note that this fails over
1542113661Sdeischen		 * time as things shuffle on the loop- we get the current
1543113870Sdeischen		 * loop state (where loop id as an index matches loop id in
1544113661Sdeischen		 * use) and then compare it to our saved database which
1545113661Sdeischen		 * never shifts.
1546114187Sdeischen		 */
1547113661Sdeischen		if (target >= 0 && isp_same_lportdb(lp, &fcp->portdb[target])) {
1548113661Sdeischen			lp->valid = 1;
1549113661Sdeischen		}
1550113661Sdeischen	}
1551113658Sdeischen
1552113658Sdeischen	/*
1553113658Sdeischen	 * If we get this far, we've settled our differences with the f/w
1554113658Sdeischen	 * and we can say that the loop state is ready.
1555113658Sdeischen	 */
1556113658Sdeischen	fcp->isp_loopstate = LOOP_READY;
1557113658Sdeischen
1558113658Sdeischen	/*
1559113658Sdeischen	 * Mark all of the permanent local loop database entries as invalid.
1560113658Sdeischen	 */
1561113658Sdeischen	for (loopid = 0; loopid < FL_PORT_ID; loopid++) {
1562113658Sdeischen		fcp->portdb[loopid].valid = 0;
1563113658Sdeischen	}
1564113658Sdeischen
1565113658Sdeischen	/*
1566113870Sdeischen	 * Now merge our local copy of the port database into our saved copy.
1567113870Sdeischen	 * Notify the outer layers of new devices arriving.
156848046Sjb	 */
1569113658Sdeischen	for (loopid = 0; loopid < prange; loopid++) {
1570113658Sdeischen		int i;
1571113658Sdeischen
1572113658Sdeischen		/*
1573113658Sdeischen		 * If we don't have a non-zero Port WWN, we're not here.
1574113658Sdeischen		 */
1575113658Sdeischen		if (tport[loopid].port_wwn == 0) {
157641164Sjb			continue;
157741164Sjb		}
1578106786Smini
1579113658Sdeischen		/*
158013546Sjulian		 * If we've already marked our tmp copy as valid,
1581113658Sdeischen		 * this means that we've decided that it's the
158213546Sjulian		 * same as our saved data base. This didn't include
1583113658Sdeischen		 * the 'valid' marking so we have set that here.
1584113658Sdeischen		 */
1585113658Sdeischen		if (tport[loopid].valid) {
1586113658Sdeischen			fcp->portdb[loopid].valid = 1;
1587113658Sdeischen			continue;
1588113658Sdeischen		}
1589113658Sdeischen
1590113658Sdeischen		/*
1591113658Sdeischen		 * For the purposes of deciding whether this is the
1592113658Sdeischen		 * 'same' device or not, we only search for an identical
1593113658Sdeischen		 * Port WWN. Node WWNs may or may not be the same as
1594113658Sdeischen		 * the Port WWN, and there may be multiple different
159513546Sjulian		 * Port WWNs with the same Node WWN. It would be chaos
1596113658Sdeischen		 * to have multiple identical Port WWNs, so we don't
1597113658Sdeischen		 * allow that.
1598113658Sdeischen		 */
1599113658Sdeischen
1600113658Sdeischen		for (i = 0; i < FL_PORT_ID; i++) {
1601113658Sdeischen			int j;
1602113658Sdeischen			if (fcp->portdb[i].port_wwn == 0)
1603113658Sdeischen				continue;
1604113658Sdeischen			if (fcp->portdb[i].port_wwn != tport[loopid].port_wwn)
1605113658Sdeischen				continue;
1606113658Sdeischen			/*
160713546Sjulian			 * We found this WWN elsewhere- it's changed
160813546Sjulian			 * loopids then. We don't change it's actual
160913546Sjulian			 * position in our cached port database- we
1610113658Sdeischen			 * just change the actual loop ID we'd use.
161113546Sjulian			 */
161271581Sdeischen			if (fcp->portdb[i].loopid != loopid) {
1613113658Sdeischen				PRINTF("%s: Target ID %d Loop 0x%x (Port 0x%x) "
161413546Sjulian				    "=> Loop 0x%x (Port 0x%x) \n",
161513546Sjulian				    isp->isp_name, i, fcp->portdb[i].loopid,
161671581Sdeischen				    fcp->portdb[i].portid, loopid,
161713546Sjulian				    tport[loopid].portid);
161813546Sjulian			}
161913546Sjulian			fcp->portdb[i].portid = tport[loopid].portid;
162013546Sjulian			fcp->portdb[i].loopid = loopid;
162113546Sjulian			fcp->portdb[i].valid = 1;
162268516Sdeischen			fcp->portdb[i].roles = tport[loopid].roles;
162313546Sjulian
162471581Sdeischen			/*
162571581Sdeischen			 * Now make sure this Port WWN doesn't exist elsewhere
162613546Sjulian			 * in the port database.
162713546Sjulian			 */
1628113658Sdeischen			for (j = i+1; j < FL_PORT_ID; j++) {
162913546Sjulian				if (fcp->portdb[i].port_wwn !=
163071581Sdeischen				    fcp->portdb[j].port_wwn) {
163171581Sdeischen					continue;
163213546Sjulian				}
1633113658Sdeischen				PRINTF("%s: Target ID %d Duplicates Target ID "
1634113658Sdeischen				    "%d- killing off both\n",
1635113658Sdeischen				    isp->isp_name, j, i);
1636113658Sdeischen				/*
1637113658Sdeischen				 * Invalidate the 'old' *and* 'new' ones.
163813546Sjulian				 * This is really harsh and not quite right,
1639113658Sdeischen				 * but if this happens, we really don't know
1640113658Sdeischen				 * who is what at this point.
1641113658Sdeischen				 */
1642113658Sdeischen				fcp->portdb[i].valid = 0;
164313546Sjulian				fcp->portdb[j].valid = 0;
1644113658Sdeischen			}
1645113658Sdeischen			break;
1646113658Sdeischen		}
164713546Sjulian
164844963Sjb		/*
164944963Sjb		 * If we didn't traverse the entire port database,
1650113658Sdeischen		 * then we found (and remapped) an existing entry.
165144963Sjb		 * No need to notify anyone- go for the next one.
1652113658Sdeischen		 */
165371581Sdeischen		if (i < FL_PORT_ID) {
1654113658Sdeischen			continue;
1655113658Sdeischen		}
1656113658Sdeischen
1657113658Sdeischen		/*
1658113658Sdeischen		 * We've not found this Port WWN anywhere. It's a new entry.
165944963Sjb		 * See if we can leave it where it is (with target == loopid).
166044963Sjb		 */
166144963Sjb		if (fcp->portdb[loopid].port_wwn != 0) {
1662113658Sdeischen			for (lim = 0; lim < FL_PORT_ID; lim++) {
166344963Sjb				if (fcp->portdb[lim].port_wwn == 0)
1664113658Sdeischen					break;
1665113658Sdeischen			}
1666113658Sdeischen			/* "Cannot Happen" */
1667114187Sdeischen			if (lim == FL_PORT_ID) {
1668113658Sdeischen				PRINTF("%s: remap overflow?\n", isp->isp_name);
1669113658Sdeischen				continue;
1670113658Sdeischen			}
1671113658Sdeischen			i = lim;
1672113658Sdeischen		} else {
1673113658Sdeischen			i = loopid;
1674113658Sdeischen		}
1675113658Sdeischen
1676113658Sdeischen		/*
1677113658Sdeischen		 * NB:	The actual loopid we use here is loopid- we may
1678113658Sdeischen		 *	in fact be at a completely different index (target).
1679113658Sdeischen		 */
1680113658Sdeischen		fcp->portdb[i].loopid = loopid;
1681113658Sdeischen		fcp->portdb[i].port_wwn = tport[loopid].port_wwn;
1682113658Sdeischen		fcp->portdb[i].node_wwn = tport[loopid].node_wwn;
1683113658Sdeischen		fcp->portdb[i].roles = tport[loopid].roles;
1684113658Sdeischen		fcp->portdb[i].portid = tport[loopid].portid;
1685113658Sdeischen		fcp->portdb[i].valid = 1;
1686113658Sdeischen
1687113658Sdeischen		/*
1688114187Sdeischen		 * Tell the outside world we've arrived.
1689114187Sdeischen		 */
1690114187Sdeischen		(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &i);
1691114187Sdeischen	}
1692114187Sdeischen
1693114187Sdeischen	/*
1694114187Sdeischen	 * Now find all previously used targets that are now invalid and
1695114187Sdeischen	 * notify the outer layers that they're gone.
1696114187Sdeischen	 */
1697114187Sdeischen	for (lp = fcp->portdb; lp < &fcp->portdb[prange]; lp++) {
1698114187Sdeischen		if (lp->valid || lp->port_wwn == 0)
1699113658Sdeischen			continue;
1700114187Sdeischen
1701114187Sdeischen		/*
1702114187Sdeischen		 * Tell the outside world we've gone away.
1703114187Sdeischen		 */
1704114187Sdeischen		loopid = lp - fcp->portdb;
1705114187Sdeischen		(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
1706114187Sdeischen		MEMZERO((void *) lp, sizeof (*lp));
1707114187Sdeischen	}
1708114187Sdeischen
1709114187Sdeischen#ifdef	ISP2100_FABRIC
1710113658Sdeischen	/*
171171581Sdeischen	 * Now log in any fabric devices
1712114187Sdeischen	 */
1713114187Sdeischen	for (lp = &fcp->portdb[FC_SNS_ID+1];
1714114187Sdeischen	     lp < &fcp->portdb[MAX_FC_TARG]; lp++) {
1715114187Sdeischen		u_int32_t portid;
1716114187Sdeischen		mbreg_t mbs;
1717114187Sdeischen
1718114187Sdeischen		/*
1719114187Sdeischen		 * Anything here?
1720114187Sdeischen		 */
1721114187Sdeischen		if (lp->port_wwn == 0)
1722114187Sdeischen			continue;
1723114187Sdeischen
1724114187Sdeischen		/*
1725114187Sdeischen		 * Don't try to log into yourself.
1726114187Sdeischen		 */
1727114187Sdeischen		if ((portid = lp->portid) == fcp->isp_portid)
1728114187Sdeischen			continue;
1729114187Sdeischen
1730114187Sdeischen
1731113658Sdeischen		/*
1732113658Sdeischen		 * If we'd been logged in- see if we still are and we haven't
1733113658Sdeischen		 * changed. If so, no need to log ourselves out, etc..
1734113658Sdeischen		 */
1735113658Sdeischen		if (lp->loggedin &&
1736113658Sdeischen		    isp_getpdb(isp, lp->loopid, &pdb) == 0) {
1737113658Sdeischen			int nrole;
1738113658Sdeischen			u_int64_t nwwnn, nwwpn;
1739113658Sdeischen			nwwnn =
1740113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1741113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1742113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1743113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1744113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1745113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1746113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1747113658Sdeischen			    (((u_int64_t)pdb.pdb_nodename[7]));
1748113658Sdeischen			nwwpn =
1749113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1750113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1751113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1752113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
1753113661Sdeischen			    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1754113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1755113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1756113658Sdeischen			    (((u_int64_t)pdb.pdb_portname[7]));
1757113658Sdeischen			nrole = (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >>
1758113661Sdeischen			    SVC3_ROLE_SHIFT;
1759113658Sdeischen			if (pdb.pdb_loopid == lp->loopid && lp->portid ==
1760113658Sdeischen			    (u_int32_t) BITS2WORD(pdb.pdb_portid_bits) &&
1761113661Sdeischen			    nwwnn == lp->node_wwn && nwwpn == lp->port_wwn &&
1762113658Sdeischen			    lp->roles == nrole) {
1763113661Sdeischen				lp->loggedin = lp->valid = 1;
1764113658Sdeischen				IDPRINTF(1, ("%s: retained login of Target %d "
1765113661Sdeischen				    "(Loop 0x%x) Port ID 0x%x\n",
1766113661Sdeischen				    isp->isp_name, (int) (lp - fcp->portdb),
1767113658Sdeischen				    (int) lp->loopid, lp->portid));
1768113658Sdeischen				continue;
1769113658Sdeischen			}
1770113658Sdeischen		}
1771113658Sdeischen
1772113658Sdeischen		/*
1773113661Sdeischen		 * Force a logout if we were logged in.
1774113661Sdeischen		 */
1775113786Sdeischen		if (lp->loggedin) {
1776113786Sdeischen			mbs.param[0] = MBOX_FABRIC_LOGOUT;
1777113658Sdeischen			mbs.param[1] = lp->loopid << 8;
1778113658Sdeischen			mbs.param[2] = 0;
177944963Sjb			mbs.param[3] = 0;
1780113658Sdeischen			isp_mboxcmd(isp, &mbs);
1781113658Sdeischen			lp->loggedin = 0;
1782113658Sdeischen			IDPRINTF(1, ("%s: Logging out target %d at Loop ID %d "
178344963Sjb			    "(port id 0x%x)\n", isp->isp_name,
1784113658Sdeischen			    (int) (lp - fcp->portdb), lp->loopid, lp->portid));
1785113658Sdeischen		}
1786113661Sdeischen
1787113661Sdeischen		/*
1788113661Sdeischen		 * And log in....
1789113661Sdeischen		 */
1790113661Sdeischen		loopid = lp - fcp->portdb;
1791113661Sdeischen		lp->loopid = 0;
1792113661Sdeischen		do {
1793113661Sdeischen			mbs.param[0] = MBOX_FABRIC_LOGIN;
1794113661Sdeischen			mbs.param[1] = loopid << 8;
1795113661Sdeischen			mbs.param[2] = portid >> 16;
1796113661Sdeischen			mbs.param[3] = portid & 0xffff;
1797113661Sdeischen			if (IS_2200(isp)) {
1798113661Sdeischen				/* only issue a PLOGI if not logged in */
1799113661Sdeischen				mbs.param[1] |= 0x1;
1800113661Sdeischen			}
1801113661Sdeischen			isp_mboxcmd(isp, &mbs);
1802113661Sdeischen			switch (mbs.param[0]) {
1803113661Sdeischen			case MBOX_LOOP_ID_USED:
1804113661Sdeischen				/*
1805113661Sdeischen				 * Try the next available loop id.
1806113661Sdeischen				 */
180748046Sjb				loopid++;
1808113658Sdeischen				break;
1809113658Sdeischen			case MBOX_PORT_ID_USED:
181048046Sjb				/*
1811113658Sdeischen				 * This port is already logged in.
1812113658Sdeischen				 * Snaffle the loop id it's using if it's
1813113658Sdeischen				 * nonzero, otherwise we're hosed.
1814113658Sdeischen				 */
1815113658Sdeischen				if (mbs.param[1] != 0) {
1816113870Sdeischen					loopid = mbs.param[1];
1817113658Sdeischen					IDPRINTF(1, ("%s: Retaining loopid 0x%x"
1818113661Sdeischen					    " for Target %d (port id 0x%x)\n",
1819113658Sdeischen					    isp->isp_name, loopid,
1820113658Sdeischen					    (int) (lp - fcp->portdb),
1821113658Sdeischen					    lp->portid));
1822113658Sdeischen				} else {
1823113658Sdeischen					loopid = MAX_FC_TARG;
1824113870Sdeischen					break;
1825113870Sdeischen				}
1826113870Sdeischen				/* FALLTHROUGH */
1827113870Sdeischen			case MBOX_COMMAND_COMPLETE:
1828113870Sdeischen				lp->loggedin = 1;
1829113870Sdeischen				lp->loopid = loopid;
1830113870Sdeischen				break;
1831113870Sdeischen			case MBOX_COMMAND_ERROR:
1832113870Sdeischen				PRINTF("%s: command error in PLOGI for port "
1833113870Sdeischen				    " 0x%x (0x%x)\n", isp->isp_name, portid,
1834113870Sdeischen				    mbs.param[1]);
1835113870Sdeischen				/* FALLTHROUGH */
1836113870Sdeischen			case MBOX_ALL_IDS_USED: /* We're outta IDs */
1837113870Sdeischen			default:
1838113658Sdeischen				loopid = MAX_FC_TARG;
1839113658Sdeischen				break;
1840113658Sdeischen			}
1841113661Sdeischen		} while (lp->loopid == 0 && loopid < MAX_FC_TARG);
1842113658Sdeischen
1843113658Sdeischen		/*
1844113658Sdeischen		 * If we get here and we haven't set a Loop ID,
1845113658Sdeischen		 * we failed to log into this device.
1846113661Sdeischen		 */
1847113658Sdeischen
1848113658Sdeischen		if (lp->loopid == 0) {
1849113661Sdeischen			continue;
1850113658Sdeischen		}
1851113658Sdeischen
1852113658Sdeischen		/*
1853113661Sdeischen		 * Make sure we can get the approriate port information.
1854113661Sdeischen		 */
1855113661Sdeischen		if (isp_getpdb(isp, lp->loopid, &pdb) != 0) {
1856113658Sdeischen			PRINTF("%s: could not get PDB for device@port 0x%x\n",
1857113658Sdeischen			    isp->isp_name, lp->portid);
1858113786Sdeischen			goto dump_em;
1859113786Sdeischen		}
1860113658Sdeischen
1861113658Sdeischen		if (pdb.pdb_loopid != lp->loopid) {
1862113658Sdeischen			PRINTF("%s: PDB loopid info for device@port 0x%x does "
1863113658Sdeischen			    "not match up (0x%x)\n", isp->isp_name, lp->portid,
1864113658Sdeischen			    pdb.pdb_loopid);
1865113786Sdeischen			goto dump_em;
1866113658Sdeischen		}
1867113658Sdeischen
1868113658Sdeischen		if (lp->portid != (u_int32_t) BITS2WORD(pdb.pdb_portid_bits)) {
1869113870Sdeischen			PRINTF("%s: PDB port info for device@port 0x%x does "
1870113658Sdeischen			    "not match up (0x%x)\n", isp->isp_name, lp->portid,
1871113658Sdeischen			    BITS2WORD(pdb.pdb_portid_bits));
1872113661Sdeischen			goto dump_em;
1873113661Sdeischen		}
1874113942Sdeischen
1875113942Sdeischen		lp->roles =
1876113658Sdeischen		    (pdb.pdb_prli_svc3 & SVC3_ROLE_MASK) >> SVC3_ROLE_SHIFT;
1877113658Sdeischen		lp->node_wwn =
1878113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[0]) << 56) |
1879113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[1]) << 48) |
1880113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[2]) << 40) |
1881113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[3]) << 32) |
1882113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[4]) << 24) |
1883113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[5]) << 16) |
1884113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[6]) <<  8) |
1885113658Sdeischen		    (((u_int64_t)pdb.pdb_nodename[7]));
1886113786Sdeischen		lp->port_wwn =
1887113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[0]) << 56) |
1888113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[1]) << 48) |
1889113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[2]) << 40) |
1890113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[3]) << 32) |
189144963Sjb		    (((u_int64_t)pdb.pdb_portname[4]) << 24) |
1892113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[5]) << 16) |
1893113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[6]) <<  8) |
1894113658Sdeischen		    (((u_int64_t)pdb.pdb_portname[7]));
1895113658Sdeischen		/*
1896113658Sdeischen		 * Check to make sure this all makes sense.
1897113658Sdeischen		 */
1898113658Sdeischen		if (lp->node_wwn && lp->port_wwn) {
189967097Sdeischen			lp->valid = 1;
1900113786Sdeischen			loopid = lp - fcp->portdb;
1901113658Sdeischen			(void) isp_async(isp, ISPASYNC_PDB_CHANGED, &loopid);
1902113658Sdeischen			continue;
1903113658Sdeischen		}
1904113658Sdeischendump_em:
1905113786Sdeischen		lp->valid = 0;
1906113786Sdeischen		PRINTF("%s: Target %d (Loop 0x%x) Port ID 0x%x dumped after "
1907113786Sdeischen		    "login\n", isp->isp_name, loopid, lp->loopid, lp->portid);
1908113786Sdeischen		mbs.param[0] = MBOX_FABRIC_LOGOUT;
1909113786Sdeischen		mbs.param[1] = lp->loopid << 8;
1910113786Sdeischen		mbs.param[2] = 0;
1911113786Sdeischen		mbs.param[3] = 0;
1912113786Sdeischen		isp_mboxcmd(isp, &mbs);
1913113786Sdeischen	}
1914113786Sdeischen#endif
1915113786Sdeischen	/*
1916113786Sdeischen	 * If we get here, we've for sure seen not only a valid loop
1917113658Sdeischen	 * but know what is or isn't on it, so mark this for usage
1918113658Sdeischen	 * in ispscsicmd.
1919113658Sdeischen	 */
192044963Sjb	fcp->loop_seen_once = 1;
1921113658Sdeischen	return (0);
1922113658Sdeischen}
1923113661Sdeischen
1924113661Sdeischen#ifdef	ISP2100_FABRIC
1925113661Sdeischenstatic int
1926113661Sdeischenisp_scan_fabric(isp)
1927113658Sdeischen	struct ispsoftc *isp;
1928113658Sdeischen{
1929113661Sdeischen	fcparam *fcp = isp->isp_param;
1930113661Sdeischen	u_int32_t portid, first_nz_portid;
1931113661Sdeischen	sns_screq_t *reqp;
1932113661Sdeischen	sns_scrsp_t *resp;
1933113658Sdeischen	mbreg_t mbs;
1934113658Sdeischen	int hicap;
1935113658Sdeischen
1936113658Sdeischen	reqp = (sns_screq_t *) fcp->isp_scratch;
1937113658Sdeischen	resp = (sns_scrsp_t *) (&((char *)fcp->isp_scratch)[0x100]);
1938113658Sdeischen	first_nz_portid = portid = fcp->isp_portid;
1939113658Sdeischen
1940113658Sdeischen	for (hicap = 0; hicap < 1024; hicap++) {
1941113870Sdeischen		MEMZERO((void *) reqp, SNS_GAN_REQ_SIZE);
1942113658Sdeischen		reqp->snscb_rblen = SNS_GAN_RESP_SIZE >> 1;
1943113661Sdeischen		reqp->snscb_addr[RQRSP_ADDR0015] =
1944113661Sdeischen			DMA_LSW(fcp->isp_scdma + 0x100);
1945113661Sdeischen		reqp->snscb_addr[RQRSP_ADDR1631] =
1946113661Sdeischen			DMA_MSW(fcp->isp_scdma + 0x100);
1947113658Sdeischen		reqp->snscb_sblen = 6;
1948113658Sdeischen		reqp->snscb_data[0] = SNS_GAN;
194948046Sjb		reqp->snscb_data[4] = portid & 0xffff;
195044963Sjb		reqp->snscb_data[5] = (portid >> 16) & 0xff;
1951113942Sdeischen		ISP_SWIZZLE_SNS_REQ(isp, reqp);
1952113942Sdeischen		mbs.param[0] = MBOX_SEND_SNS;
1953113942Sdeischen		mbs.param[1] = SNS_GAN_REQ_SIZE >> 1;
1954113942Sdeischen		mbs.param[2] = DMA_MSW(fcp->isp_scdma);
1955113942Sdeischen		mbs.param[3] = DMA_LSW(fcp->isp_scdma);
1956113942Sdeischen		mbs.param[6] = 0;
1957113942Sdeischen		mbs.param[7] = 0;
1958113942Sdeischen		MemoryBarrier();
1959113942Sdeischen		isp_mboxcmd(isp, &mbs);
1960113942Sdeischen		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
1961113942Sdeischen			IDPRINTF(1, ("%s: SNS failed (0x%x)\n", isp->isp_name,
1962114187Sdeischen			    mbs.param[0]));
1963113942Sdeischen			return (-1);
1964113942Sdeischen		}
1965113942Sdeischen		ISP_UNSWIZZLE_SNS_RSP(isp, resp, SNS_GAN_RESP_SIZE >> 1);
1966113942Sdeischen		portid = (((u_int32_t) resp->snscb_port_id[0]) << 16) |
1967113942Sdeischen		    (((u_int32_t) resp->snscb_port_id[1]) << 8) |
1968113942Sdeischen		    (((u_int32_t) resp->snscb_port_id[2]));
1969113658Sdeischen		if (isp_async(isp, ISPASYNC_FABRIC_DEV, resp)) {
1970113661Sdeischen			return (-1);
197144963Sjb		}
1972113870Sdeischen		if (first_nz_portid == 0 && portid) {
1973113658Sdeischen			first_nz_portid = portid;
1974113658Sdeischen		}
1975113881Sdeischen		if (first_nz_portid == portid) {
1976113658Sdeischen			return (0);
1977113658Sdeischen		}
1978113658Sdeischen	}
197944963Sjb	/*
198071581Sdeischen	 * We either have a broken name server or a huge fabric if we get here.
1981113661Sdeischen	 */
1982113661Sdeischen	return (0);
1983113661Sdeischen}
1984113661Sdeischen#endif
1985113661Sdeischen/*
1986113661Sdeischen * Start a command. Locking is assumed done in the caller.
1987113661Sdeischen */
1988113661Sdeischen
1989113661Sdeischenint32_t
1990113661Sdeischenispscsicmd(xs)
1991113661Sdeischen	ISP_SCSI_XFER_T *xs;
1992113661Sdeischen{
1993113661Sdeischen	struct ispsoftc *isp;
1994113661Sdeischen	u_int16_t iptr, optr;
1995113661Sdeischen	union {
1996113661Sdeischen		ispreq_t *_reqp;
1997113658Sdeischen		ispreqt2_t *_t2reqp;
1998113658Sdeischen	} _u;
1999113658Sdeischen#define	reqp	_u._reqp
2000113786Sdeischen#define	t2reqp	_u._t2reqp
2001113786Sdeischen#define	UZSIZE	max(sizeof (ispreq_t), sizeof (ispreqt2_t))
2002113786Sdeischen	int target, i;
2003113786Sdeischen
2004113786Sdeischen	XS_INITERR(xs);
2005113786Sdeischen	isp = XS_ISP(xs);
2006113786Sdeischen
2007113786Sdeischen	if (isp->isp_state != ISP_RUNSTATE) {
2008113658Sdeischen		PRINTF("%s: adapter not ready\n", isp->isp_name);
2009113658Sdeischen		XS_SETERR(xs, HBA_BOTCH);
2010113658Sdeischen		return (CMD_COMPLETE);
2011113658Sdeischen	}
2012113870Sdeischen
2013113658Sdeischen	/*
2014113658Sdeischen	 * Check command CDB length, etc.. We really are limited to 16 bytes
2015113658Sdeischen	 * for Fibre Channel, but can do up to 44 bytes in parallel SCSI,
2016113658Sdeischen	 * but probably only if we're running fairly new firmware (we'll
201771581Sdeischen	 * let the old f/w choke on an extended command queue entry).
2018113658Sdeischen	 */
201971581Sdeischen
2020113658Sdeischen	if (XS_CDBLEN(xs) > (IS_FC(isp)? 16 : 44) || XS_CDBLEN(xs) == 0) {
2021113658Sdeischen		PRINTF("%s: unsupported cdb length (%d, CDB[0]=0x%x)\n",
202271581Sdeischen		    isp->isp_name, XS_CDBLEN(xs), XS_CDBP(xs)[0] & 0xff);
2023113658Sdeischen		XS_SETERR(xs, HBA_BOTCH);
2024113661Sdeischen		return (CMD_COMPLETE);
2025113661Sdeischen	}
2026113658Sdeischen
2027113658Sdeischen	/*
2028113661Sdeischen	 * Check to see whether we have good firmware state still or
2029113658Sdeischen	 * need to refresh our port database for this target.
2030113658Sdeischen	 */
2031113658Sdeischen	target = XS_TGT(xs);
2032113658Sdeischen	if (IS_FC(isp)) {
2033113661Sdeischen		fcparam *fcp = isp->isp_param;
2034114187Sdeischen		struct lportdb *lp;
2035113658Sdeischen#if	defined(ISP2100_FABRIC)
2036113658Sdeischen		/*
2037113658Sdeischen		 * If we're not on a Fabric, we can't have a target
2038113658Sdeischen		 * above FL_PORT_ID-1. If we're on a fabric and
2039113658Sdeischen		 * connected as an F-port, we can't have a target
204071581Sdeischen		 * less than FC_SNS_ID+1.
204171581Sdeischen		 */
204271581Sdeischen		if (fcp->isp_onfabric == 0) {
2043113658Sdeischen			if (target >= FL_PORT_ID) {
204471581Sdeischen				XS_SETERR(xs, HBA_SELTIMEOUT);
2045113658Sdeischen				return (CMD_COMPLETE);
2046113786Sdeischen			}
2047113658Sdeischen		} else {
2048113661Sdeischen			if (target >= FL_PORT_ID && target <= FC_SNS_ID) {
2049113786Sdeischen				XS_SETERR(xs, HBA_SELTIMEOUT);
2050113786Sdeischen				return (CMD_COMPLETE);
2051113786Sdeischen			}
2052113786Sdeischen			if (fcp->isp_topo == TOPO_F_PORT &&
2053113786Sdeischen			    target < FL_PORT_ID) {
2054113658Sdeischen				XS_SETERR(xs, HBA_SELTIMEOUT);
2055113786Sdeischen				return (CMD_COMPLETE);
2056113658Sdeischen			}
2057113658Sdeischen		}
2058113661Sdeischen#endif
2059113658Sdeischen		/*
2060113658Sdeischen		 * Check for f/w being in ready state. If the f/w
2061113661Sdeischen		 * isn't in ready state, then we don't know our
2062113658Sdeischen		 * loop ID and the f/w hasn't completed logging
2063113658Sdeischen		 * into all targets on the loop. If this is the
206471581Sdeischen		 * case, then bounce the command. We pretend this is
2065		 * a SELECTION TIMEOUT error if we've never gone to
2066		 * FW_READY state at all- in this case we may not
2067		 * be hooked to a loop at all and we shouldn't hang
2068		 * the machine for this. Otherwise, defer this command
2069		 * until later.
2070		 */
2071		if (fcp->isp_fwstate != FW_READY) {
2072			if (isp_fclink_test(isp, FC_FW_READY_DELAY)) {
2073				XS_SETERR(xs, HBA_SELTIMEOUT);
2074				if (fcp->loop_seen_once) {
2075					return (CMD_RQLATER);
2076				} else {
2077					return (CMD_COMPLETE);
2078				}
2079			}
2080		}
2081
2082		/*
2083		 * If our loop state is such that we haven't yet received
2084		 * a "Port Database Changed" notification (after a LIP or
2085		 * a Loop Reset or firmware initialization), then defer
2086		 * sending commands for a little while, but only if we've
2087		 * seen a valid loop at one point (otherwise we can get
2088		 * stuck at initialization time).
2089		 */
2090		if (fcp->isp_loopstate < LOOP_PDB_RCVD) {
2091			XS_SETERR(xs, HBA_SELTIMEOUT);
2092			if (fcp->loop_seen_once) {
2093				return (CMD_RQLATER);
2094			} else {
2095				return (CMD_COMPLETE);
2096			}
2097		}
2098
2099		/*
2100		 * If our loop state is now such that we've just now
2101		 * received a Port Database Change notification, then
2102		 * we have to go off and (re)synchronize our port
2103		 * database.
2104		 */
2105		if (fcp->isp_loopstate == LOOP_PDB_RCVD) {
2106			if (isp_pdb_sync(isp, target)) {
2107				XS_SETERR(xs, HBA_SELTIMEOUT);
2108				return (CMD_COMPLETE);
2109			}
2110		}
2111
2112		/*
2113		 * Now check whether we should even think about pursuing this.
2114		 */
2115		lp = &fcp->portdb[target];
2116		if (lp->valid == 0) {
2117			XS_SETERR(xs, HBA_SELTIMEOUT);
2118			return (CMD_COMPLETE);
2119		}
2120		if ((lp->roles & (SVC3_TGT_ROLE >> SVC3_ROLE_SHIFT)) == 0) {
2121			IDPRINTF(3, ("%s: target %d is not a target\n",
2122			    isp->isp_name, target));
2123			XS_SETERR(xs, HBA_SELTIMEOUT);
2124			return (CMD_COMPLETE);
2125		}
2126		/*
2127		 * Now turn target into what the actual loop ID is.
2128		 */
2129		target = lp->loopid;
2130	}
2131
2132	/*
2133	 * Next check to see if any HBA or Device
2134	 * parameters need to be updated.
2135	 */
2136	if (isp->isp_update != 0) {
2137		isp_update(isp);
2138	}
2139
2140	if (isp_getrqentry(isp, &iptr, &optr, (void **) &reqp)) {
2141		IDPRINTF(1, ("%s: Request Queue Overflow\n", isp->isp_name));
2142		XS_SETERR(xs, HBA_BOTCH);
2143		return (CMD_EAGAIN);
2144	}
2145
2146	/*
2147	 * Now see if we need to synchronize the ISP with respect to anything.
2148	 * We do dual duty here (cough) for synchronizing for busses other
2149	 * than which we got here to send a command to.
2150	 */
2151	if (isp->isp_sendmarker) {
2152		u_int8_t n = (IS_DUALBUS(isp)? 2: 1);
2153		/*
2154		 * Check ports to send markers for...
2155		 */
2156		for (i = 0; i < n; i++) {
2157			if ((isp->isp_sendmarker & (1 << i)) == 0) {
2158				continue;
2159			}
2160			MEMZERO((void *) reqp, sizeof (*reqp));
2161			reqp->req_header.rqs_entry_count = 1;
2162			reqp->req_header.rqs_entry_type = RQSTYPE_MARKER;
2163			reqp->req_modifier = SYNC_ALL;
2164			reqp->req_target = i << 7;	/* insert bus number */
2165			ISP_SWIZZLE_REQUEST(isp, reqp);
2166			MemoryBarrier();
2167			ISP_ADD_REQUEST(isp, iptr);
2168
2169			if (isp_getrqentry(isp, &iptr, &optr, (void **)&reqp)) {
2170				IDPRINTF(1, ("%s: Request Queue Overflow+\n",
2171				    isp->isp_name));
2172				XS_SETERR(xs, HBA_BOTCH);
2173				return (CMD_EAGAIN);
2174			}
2175		}
2176	}
2177
2178	MEMZERO((void *) reqp, UZSIZE);
2179	reqp->req_header.rqs_entry_count = 1;
2180	if (IS_FC(isp)) {
2181		reqp->req_header.rqs_entry_type = RQSTYPE_T2RQS;
2182	} else {
2183		if (XS_CDBLEN(xs) > 12)
2184			reqp->req_header.rqs_entry_type = RQSTYPE_CMDONLY;
2185		else
2186			reqp->req_header.rqs_entry_type = RQSTYPE_REQUEST;
2187	}
2188	reqp->req_header.rqs_flags = 0;
2189	reqp->req_header.rqs_seqno = 0;
2190	if (IS_FC(isp)) {
2191		/*
2192		 * See comment in isp_intr
2193		 */
2194		XS_RESID(xs) = 0;
2195
2196		/*
2197		 * Fibre Channel always requires some kind of tag.
2198		 * The Qlogic drivers seem be happy not to use a tag,
2199		 * but this breaks for some devices (IBM drives).
2200		 */
2201		if (XS_CANTAG(xs)) {
2202			t2reqp->req_flags = XS_KINDOF_TAG(xs);
2203		} else {
2204			if (XS_CDBP(xs)[0] == 0x3)	/* REQUEST SENSE */
2205				t2reqp->req_flags = REQFLAG_HTAG;
2206			else
2207				t2reqp->req_flags = REQFLAG_OTAG;
2208		}
2209	} else {
2210		sdparam *sdp = (sdparam *)isp->isp_param;
2211		if ((sdp->isp_devparam[target].cur_dflags & DPARM_TQING) &&
2212		    XS_CANTAG(xs)) {
2213			reqp->req_flags = XS_KINDOF_TAG(xs);
2214		}
2215	}
2216	reqp->req_target = target | (XS_CHANNEL(xs) << 7);
2217	if (IS_SCSI(isp)) {
2218		reqp->req_lun_trn = XS_LUN(xs);
2219		reqp->req_cdblen = XS_CDBLEN(xs);
2220	} else {
2221		if (isp->isp_maxluns > 16)
2222			t2reqp->req_scclun = XS_LUN(xs);
2223		else
2224			t2reqp->req_lun_trn = XS_LUN(xs);
2225	}
2226	MEMCPY(reqp->req_cdb, XS_CDBP(xs), XS_CDBLEN(xs));
2227
2228	reqp->req_time = XS_TIME(xs) / 1000;
2229	if (reqp->req_time == 0 && XS_TIME(xs))
2230		reqp->req_time = 1;
2231
2232	/*
2233	 * Always give a bit more leeway to commands after a bus reset.
2234	 * XXX: DOES NOT DISTINGUISH WHICH PORT MAY HAVE BEEN SYNCED
2235	 */
2236	if (isp->isp_sendmarker && reqp->req_time < 5) {
2237		reqp->req_time = 5;
2238	}
2239	if (isp_save_xs(isp, xs, &reqp->req_handle)) {
2240		IDPRINTF(2, ("%s: out of xflist pointers\n", isp->isp_name));
2241		XS_SETERR(xs, HBA_BOTCH);
2242		return (CMD_EAGAIN);
2243	}
2244	/*
2245	 * Set up DMA and/or do any bus swizzling of the request entry
2246	 * so that the Qlogic F/W understands what is being asked of it.
2247 	*/
2248	i = ISP_DMASETUP(isp, xs, reqp, &iptr, optr);
2249	if (i != CMD_QUEUED) {
2250		isp_destroy_handle(isp, reqp->req_handle);
2251		/*
2252		 * dmasetup sets actual error in packet, and
2253		 * return what we were given to return.
2254		 */
2255		return (i);
2256	}
2257	XS_SETERR(xs, HBA_NOERROR);
2258	IDPRINTF(5, ("%s(%d.%d.%d): START cmd 0x%x datalen %d\n",
2259	    isp->isp_name, XS_CHANNEL(xs), target, XS_LUN(xs),
2260	    reqp->req_cdb[0], XS_XFRLEN(xs)));
2261	MemoryBarrier();
2262	ISP_ADD_REQUEST(isp, iptr);
2263	isp->isp_nactive++;
2264	if (isp->isp_sendmarker)
2265		isp->isp_sendmarker = 0;
2266	return (CMD_QUEUED);
2267#undef	reqp
2268#undef	t2reqp
2269}
2270
2271/*
2272 * isp control
2273 * Locks (ints blocked) assumed held.
2274 */
2275
2276int
2277isp_control(isp, ctl, arg)
2278	struct ispsoftc *isp;
2279	ispctl_t ctl;
2280	void *arg;
2281{
2282	ISP_SCSI_XFER_T *xs;
2283	mbreg_t mbs;
2284	int bus, tgt;
2285	u_int32_t handle;
2286
2287	switch (ctl) {
2288	default:
2289		PRINTF("%s: isp_control unknown control op %x\n",
2290		    isp->isp_name, ctl);
2291		break;
2292
2293	case ISPCTL_RESET_BUS:
2294		/*
2295		 * Issue a bus reset.
2296		 */
2297		mbs.param[0] = MBOX_BUS_RESET;
2298		mbs.param[2] = 0;
2299		if (IS_SCSI(isp)) {
2300			mbs.param[1] =
2301			    ((sdparam *) isp->isp_param)->isp_bus_reset_delay;
2302			if (mbs.param[1] < 2)
2303				mbs.param[1] = 2;
2304			bus = *((int *) arg);
2305			if (IS_DUALBUS(isp))
2306				mbs.param[2] = bus;
2307		} else {
2308			mbs.param[1] = 10;
2309			bus = 0;
2310		}
2311		isp->isp_sendmarker |= (1 << bus);
2312		isp_mboxcmd(isp, &mbs);
2313		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2314			isp_dumpregs(isp, "isp_control SCSI bus reset failed");
2315			break;
2316		}
2317		CFGPRINTF("%s: driver initiated bus reset of bus %d\n",
2318		    isp->isp_name, bus);
2319		return (0);
2320
2321	case ISPCTL_RESET_DEV:
2322		tgt = (*((int *) arg)) & 0xffff;
2323		bus = (*((int *) arg)) >> 16;
2324		mbs.param[0] = MBOX_ABORT_TARGET;
2325		mbs.param[1] = (tgt << 8) | (bus << 15);
2326		mbs.param[2] = 3;	/* 'delay', in seconds */
2327		isp_mboxcmd(isp, &mbs);
2328		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2329			PRINTF("%s: isp_control MBOX_RESET_DEV failure (code "
2330			    "%x)\n", isp->isp_name, mbs.param[0]);
2331			break;
2332		}
2333		PRINTF("%s: Target %d on Bus %d Reset Succeeded\n",
2334		    isp->isp_name, tgt, bus);
2335		isp->isp_sendmarker |= (1 << bus);
2336		return (0);
2337
2338	case ISPCTL_ABORT_CMD:
2339		xs = (ISP_SCSI_XFER_T *) arg;
2340		handle = isp_find_handle(isp, xs);
2341		if (handle == 0) {
2342			PRINTF("%s: isp_control- cannot find command to abort "
2343			    "in active list\n", isp->isp_name);
2344			break;
2345		}
2346		bus = XS_CHANNEL(xs);
2347		mbs.param[0] = MBOX_ABORT;
2348		if (IS_FC(isp)) {
2349			if (isp->isp_maxluns > 16) {
2350				mbs.param[1] = XS_TGT(xs) << 8;
2351				mbs.param[4] = 0;
2352				mbs.param[5] = 0;
2353				mbs.param[6] = XS_LUN(xs);
2354			} else {
2355				mbs.param[1] = XS_TGT(xs) << 8 | XS_LUN(xs);
2356			}
2357		} else {
2358			mbs.param[1] =
2359			    (bus << 15) | (XS_TGT(xs) << 8) | XS_LUN(xs);
2360		}
2361		mbs.param[3] = handle >> 16;
2362		mbs.param[2] = handle & 0xffff;
2363		isp_mboxcmd(isp, &mbs);
2364		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2365			PRINTF("%s: isp_control MBOX_ABORT failure (code %x)\n",
2366			    isp->isp_name, mbs.param[0]);
2367			break;
2368		}
2369		PRINTF("%s: command for target %d lun %d was aborted\n",
2370		    isp->isp_name, XS_TGT(xs), XS_LUN(xs));
2371		return (0);
2372
2373	case ISPCTL_UPDATE_PARAMS:
2374		isp_update(isp);
2375		return (0);
2376
2377	case ISPCTL_FCLINK_TEST:
2378		return (isp_fclink_test(isp, FC_FW_READY_DELAY));
2379
2380	case ISPCTL_PDB_SYNC:
2381		return (isp_pdb_sync(isp, -1));
2382
2383#ifdef	ISP_TARGET_MODE
2384	case ISPCTL_TOGGLE_TMODE:
2385		if (IS_SCSI(isp)) {
2386			int ena = *(int *)arg;
2387			mbs.param[0] = MBOX_ENABLE_TARGET_MODE;
2388			mbs.param[1] = (ena)? ENABLE_TARGET_FLAG : 0;
2389			isp_mboxcmd(isp, &mbs);
2390			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
2391				PRINTF("%s: cannot %sable target mode (0x%x)\n",
2392				    isp->isp_name, ena? "en" : "dis",
2393				    mbs.param[0]);
2394				break;
2395			}
2396		}
2397		return (0);
2398#endif
2399	}
2400	return (-1);
2401}
2402
2403/*
2404 * Interrupt Service Routine(s).
2405 *
2406 * External (OS) framework has done the appropriate locking,
2407 * and the locking will be held throughout this function.
2408 */
2409
2410int
2411isp_intr(arg)
2412	void *arg;
2413{
2414	ISP_SCSI_XFER_T *complist[RESULT_QUEUE_LEN], *xs;
2415	struct ispsoftc *isp = arg;
2416	u_int16_t iptr, optr;
2417	u_int16_t isr, sema;
2418	int i, nlooked = 0, ndone = 0;
2419
2420	/*
2421	 * If we've disabled interrupts, we may get a case where
2422	 * isr isn't set, but sema is.
2423	 */
2424	isr = ISP_READ(isp, BIU_ISR);
2425	sema = ISP_READ(isp, BIU_SEMA) & 0x1;
2426	IDPRINTF(5, ("%s: isp_intr isr %x sem %x\n", isp->isp_name, isr, sema));
2427	if (isr == 0 && sema == 0) {
2428		return (0);
2429	}
2430#if	0
2431	if (!INT_PENDING(isp, isr)) {
2432		IDPRINTF(4, ("%s: isp_intr isr=%x\n", isp->isp_name, isr));
2433		return (0);
2434	}
2435#endif
2436	if (isp->isp_state != ISP_RUNSTATE) {
2437		IDPRINTF(3, ("%s: interrupt (isr=%x,sema=%x) when not ready\n",
2438		    isp->isp_name, isr, sema));
2439		ISP_WRITE(isp, INMAILBOX5, ISP_READ(isp, OUTMAILBOX5));
2440		ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
2441		ISP_WRITE(isp, BIU_SEMA, 0);
2442		ENABLE_INTS(isp);
2443		return (1);
2444	}
2445
2446	if (sema) {
2447		u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
2448		if (mbox & 0x4000) {
2449			IDPRINTF(4, ("%s: Command Mbox 0x%x\n",
2450			    isp->isp_name, mbox));
2451		} else {
2452			u_int32_t fhandle = isp_parse_async(isp, (int) mbox);
2453			IDPRINTF(4, ("%s: Async Mbox 0x%x\n",
2454			    isp->isp_name, mbox));
2455			if (fhandle > 0) {
2456				isp_fastpost_complete(isp, fhandle);
2457			}
2458		}
2459		if (IS_FC(isp)) {
2460			ISP_WRITE(isp, BIU_SEMA, 0);
2461			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
2462			ENABLE_INTS(isp);
2463			return (1);
2464		}
2465	}
2466
2467	/*
2468	 * You *must* read OUTMAILBOX5 prior to clearing the RISC interrupt.
2469	 */
2470	optr = isp->isp_residx;
2471	iptr = ISP_READ(isp, OUTMAILBOX5);
2472	if (sema) {
2473		ISP_WRITE(isp, BIU_SEMA, 0);
2474	}
2475	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
2476	if (optr == iptr && sema == 0) {
2477		IDPRINTF(1, ("%s: why intr? isr %x iptr %x optr %x\n",
2478		    isp->isp_name, isr, optr, iptr));
2479	}
2480
2481	while (optr != iptr) {
2482		ispstatusreq_t *sp;
2483		u_int16_t oop;
2484		int buddaboom = 0;
2485
2486		sp = (ispstatusreq_t *) ISP_QUEUE_ENTRY(isp->isp_result, optr);
2487		oop = optr;
2488		optr = ISP_NXT_QENTRY(optr, RESULT_QUEUE_LEN);
2489		nlooked++;
2490		MemoryBarrier();
2491		/*
2492		 * Do any appropriate unswizzling of what the Qlogic f/w has
2493		 * written into memory so it makes sense to us. This is a
2494		 * per-platform thing.
2495		 */
2496		ISP_UNSWIZZLE_RESPONSE(isp, sp);
2497		if (sp->req_header.rqs_entry_type != RQSTYPE_RESPONSE) {
2498			if (isp_handle_other_response(isp, sp, &optr) == 0) {
2499				continue;
2500			}
2501			/*
2502			 * It really has to be a bounced request just copied
2503			 * from the request queue to the response queue. If
2504			 * not, something bad has happened.
2505			 */
2506			if (sp->req_header.rqs_entry_type != RQSTYPE_REQUEST) {
2507				PRINTF("%s: not RESPONSE in RESPONSE Queue "
2508				    "(type 0x%x) @ idx %d (next %d)\n",
2509				    isp->isp_name,
2510				    sp->req_header.rqs_entry_type, oop, optr);
2511				continue;
2512			}
2513			buddaboom = 1;
2514		}
2515
2516		if (sp->req_header.rqs_flags & 0xf) {
2517#define	_RQS_OFLAGS	\
2518	~(RQSFLAG_CONTINUATION|RQSFLAG_FULL|RQSFLAG_BADHEADER|RQSFLAG_BADPACKET)
2519			if (sp->req_header.rqs_flags & RQSFLAG_CONTINUATION) {
2520				IDPRINTF(4, ("%s: continuation segment\n",
2521				    isp->isp_name));
2522				ISP_WRITE(isp, INMAILBOX5, optr);
2523				continue;
2524			}
2525			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
2526				IDPRINTF(2, ("%s: internal queues full\n",
2527				    isp->isp_name));
2528				/*
2529				 * We'll synthesize a QUEUE FULL message below.
2530				 */
2531			}
2532			if (sp->req_header.rqs_flags & RQSFLAG_BADHEADER) {
2533				PRINTF("%s: bad header\n", isp->isp_name);
2534				buddaboom++;
2535			}
2536			if (sp->req_header.rqs_flags & RQSFLAG_BADPACKET) {
2537				PRINTF("%s: bad request packet\n",
2538				    isp->isp_name);
2539				buddaboom++;
2540			}
2541			if (sp->req_header.rqs_flags & _RQS_OFLAGS) {
2542				PRINTF("%s: unknown flags in response (0x%x)\n",
2543				    isp->isp_name, sp->req_header.rqs_flags);
2544				buddaboom++;
2545			}
2546#undef	_RQS_OFLAGS
2547		}
2548		if (sp->req_handle > isp->isp_maxcmds || sp->req_handle < 1) {
2549			PRINTF("%s: bad request handle %d\n", isp->isp_name,
2550			    sp->req_handle);
2551			ISP_WRITE(isp, INMAILBOX5, optr);
2552			continue;
2553		}
2554		xs = isp_find_xs(isp, sp->req_handle);
2555		if (xs == NULL) {
2556			PRINTF("%s: NULL xs in xflist (handle 0x%x)\n",
2557			    isp->isp_name, sp->req_handle);
2558			ISP_WRITE(isp, INMAILBOX5, optr);
2559			continue;
2560		}
2561		isp_destroy_handle(isp, sp->req_handle);
2562		if (sp->req_status_flags & RQSTF_BUS_RESET) {
2563			isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
2564		}
2565		if (buddaboom) {
2566			XS_SETERR(xs, HBA_BOTCH);
2567		}
2568		XS_STS(xs) = sp->req_scsi_status & 0xff;
2569		if (IS_SCSI(isp)) {
2570			if (sp->req_state_flags & RQSF_GOT_SENSE) {
2571				MEMCPY(XS_SNSP(xs), sp->req_sense_data,
2572					XS_SNSLEN(xs));
2573				XS_SNS_IS_VALID(xs);
2574			}
2575			/*
2576			 * A new synchronous rate was negotiated for this
2577			 * target. Mark state such that we'll go look up
2578			 * that which has changed later.
2579			 */
2580			if (sp->req_status_flags & RQSTF_NEGOTIATION) {
2581				sdparam *sdp = isp->isp_param;
2582				sdp += XS_CHANNEL(xs);
2583				sdp->isp_devparam[XS_TGT(xs)].dev_refresh = 1;
2584				isp->isp_update |= (1 << XS_CHANNEL(xs));
2585			}
2586		} else {
2587			if (sp->req_scsi_status & RQCS_SV) {
2588				int amt = min(XS_SNSLEN(xs), sp->req_sense_len);
2589				MEMCPY(XS_SNSP(xs), sp->req_sense_data, amt);
2590				XS_SNS_IS_VALID(xs);
2591				sp->req_state_flags |= RQSF_GOT_SENSE;
2592			} else if (XS_STS(xs) == SCSI_CHECK) {
2593				IDPRINTF(1, ("%s: check condition with no sense"
2594				    " data\n", isp->isp_name));
2595			}
2596		}
2597		if (XS_NOERR(xs) && XS_STS(xs) == SCSI_BUSY) {
2598			XS_SETERR(xs, HBA_TGTBSY);
2599		}
2600
2601		if (sp->req_header.rqs_entry_type == RQSTYPE_RESPONSE) {
2602			if (XS_NOERR(xs)) {
2603			    if (sp->req_completion_status != RQCS_COMPLETE) {
2604				isp_parse_status(isp, sp, xs);
2605			    } else {
2606				XS_SETERR(xs, HBA_NOERROR);
2607			    }
2608			}
2609		} else if (sp->req_header.rqs_entry_type == RQSTYPE_REQUEST) {
2610			if (sp->req_header.rqs_flags & RQSFLAG_FULL) {
2611				/*
2612				 * Force Queue Full status.
2613				 */
2614				XS_STS(xs) = SCSI_QFULL;
2615				XS_SETERR(xs, HBA_NOERROR);
2616			} else if (XS_NOERR(xs)) {
2617				XS_SETERR(xs, HBA_BOTCH);
2618			}
2619		} else {
2620			PRINTF("%s: unhandled respose queue type 0x%x\n",
2621			    isp->isp_name, sp->req_header.rqs_entry_type);
2622			if (XS_NOERR(xs)) {
2623				XS_SETERR(xs, HBA_BOTCH);
2624			}
2625		}
2626		if (IS_SCSI(isp)) {
2627			XS_RESID(xs) = sp->req_resid;
2628		} else if (sp->req_scsi_status & RQCS_RU) {
2629			XS_RESID(xs) = sp->req_resid;
2630			IDPRINTF(4, ("%s: cnt %d rsd %d\n", isp->isp_name,
2631				XS_XFRLEN(xs), sp->req_resid));
2632		}
2633		if (XS_XFRLEN(xs)) {
2634			ISP_DMAFREE(isp, xs, sp->req_handle);
2635		}
2636		/*
2637		 * Let the platforms cope.
2638		 */
2639#if	0
2640		/*
2641		 * XXX: If we have a check condition, but no Sense Data,
2642		 * XXX: mark it as an error (ARQ failed). We need to
2643		 * XXX: to do a more distinct job because there may
2644		 * XXX: cases where ARQ is disabled.
2645		 */
2646		if (XS_STS(xs) == SCSI_CHECK && !(XS_IS_SNS_VALID(xs))) {
2647			if (XS_NOERR(xs)) {
2648				PRINTF("%s: ARQ failure for target %d lun %d\n",
2649				    isp->isp_name, XS_TGT(xs), XS_LUN(xs));
2650				XS_SETERR(xs, HBA_ARQFAIL);
2651			}
2652		}
2653#endif
2654		if ((isp->isp_dblev >= 5) ||
2655		    (isp->isp_dblev > 2 && !XS_NOERR(xs))) {
2656			PRINTF("%s(%d.%d): FIN dl%d resid%d STS %x",
2657			    isp->isp_name, XS_TGT(xs), XS_LUN(xs),
2658			    XS_XFRLEN(xs), XS_RESID(xs), XS_STS(xs));
2659			if (sp->req_state_flags & RQSF_GOT_SENSE) {
2660				PRINTF(" Skey: %x", XS_SNSKEY(xs));
2661				if (!(XS_IS_SNS_VALID(xs))) {
2662					PRINTF(" BUT NOT SET");
2663				}
2664			}
2665			PRINTF(" XS_ERR=0x%x\n", (unsigned int) XS_ERR(xs));
2666		}
2667
2668		if (isp->isp_nactive > 0)
2669		    isp->isp_nactive--;
2670		complist[ndone++] = xs;	/* defer completion call until later */
2671	}
2672
2673	/*
2674	 * If we looked at any commands, then it's valid to find out
2675	 * what the outpointer is. It also is a trigger to update the
2676	 * ISP's notion of what we've seen so far.
2677	 */
2678	if (nlooked) {
2679		ISP_WRITE(isp, INMAILBOX5, optr);
2680		isp->isp_reqodx = ISP_READ(isp, OUTMAILBOX4);
2681	}
2682	isp->isp_residx = optr;
2683	for (i = 0; i < ndone; i++) {
2684		xs = complist[i];
2685		if (xs) {
2686			XS_CMD_DONE(xs);
2687		}
2688	}
2689	ENABLE_INTS(isp);
2690	return (1);
2691}
2692
2693/*
2694 * Support routines.
2695 */
2696
2697static int
2698isp_parse_async(isp, mbox)
2699	struct ispsoftc *isp;
2700	int mbox;
2701{
2702	int bus;
2703	u_int32_t fast_post_handle = 0;
2704
2705	if (IS_DUALBUS(isp)) {
2706		bus = ISP_READ(isp, OUTMAILBOX6);
2707	} else {
2708		bus = 0;
2709	}
2710
2711	switch (mbox) {
2712	case MBOX_COMMAND_COMPLETE:	/* sometimes these show up */
2713		break;
2714	case ASYNC_BUS_RESET:
2715		isp->isp_sendmarker |= (1 << bus);
2716#ifdef	ISP_TARGET_MODE
2717		isp_target_async(isp, bus, mbox);
2718#endif
2719		isp_async(isp, ISPASYNC_BUS_RESET, &bus);
2720		break;
2721	case ASYNC_SYSTEM_ERROR:
2722		mbox = ISP_READ(isp, OUTMAILBOX1);
2723		PRINTF("%s: Internal FW Error @ RISC Addr 0x%x\n",
2724		    isp->isp_name, mbox);
2725		isp_restart(isp);
2726		/* no point continuing after this */
2727		return (-1);
2728
2729	case ASYNC_RQS_XFER_ERR:
2730		PRINTF("%s: Request Queue Transfer Error\n", isp->isp_name);
2731		break;
2732
2733	case ASYNC_RSP_XFER_ERR:
2734		PRINTF("%s: Response Queue Transfer Error\n", isp->isp_name);
2735		break;
2736
2737	case ASYNC_QWAKEUP:
2738		/*
2739		 * We've just been notified that the Queue has woken up.
2740		 * We don't need to be chatty about this- just unlatch things
2741		 * and move on.
2742		 */
2743		mbox = ISP_READ(isp, OUTMAILBOX4);
2744		break;
2745
2746	case ASYNC_TIMEOUT_RESET:
2747		PRINTF("%s: timeout initiated SCSI bus reset of bus %d\n",
2748		    isp->isp_name, bus);
2749		isp->isp_sendmarker |= (1 << bus);
2750#ifdef	ISP_TARGET_MODE
2751		isp_target_async(isp, bus, mbox);
2752#endif
2753		break;
2754
2755	case ASYNC_DEVICE_RESET:
2756		PRINTF("%s: device reset on bus %d\n", isp->isp_name, bus);
2757		isp->isp_sendmarker |= (1 << bus);
2758#ifdef	ISP_TARGET_MODE
2759		isp_target_async(isp, bus, mbox);
2760#endif
2761		break;
2762
2763	case ASYNC_EXTMSG_UNDERRUN:
2764		PRINTF("%s: extended message underrun\n", isp->isp_name);
2765		break;
2766
2767	case ASYNC_SCAM_INT:
2768		PRINTF("%s: SCAM interrupt\n", isp->isp_name);
2769		break;
2770
2771	case ASYNC_HUNG_SCSI:
2772		PRINTF("%s: stalled SCSI Bus after DATA Overrun\n",
2773		    isp->isp_name);
2774		/* XXX: Need to issue SCSI reset at this point */
2775		break;
2776
2777	case ASYNC_KILLED_BUS:
2778		PRINTF("%s: SCSI Bus reset after DATA Overrun\n",
2779		    isp->isp_name);
2780		break;
2781
2782	case ASYNC_BUS_TRANSIT:
2783		mbox = ISP_READ(isp, OUTMAILBOX2);
2784		switch (mbox & 0x1c00) {
2785		case SXP_PINS_LVD_MODE:
2786			PRINTF("%s: Transition to LVD mode\n", isp->isp_name);
2787			((sdparam *)isp->isp_param)->isp_diffmode = 0;
2788			((sdparam *)isp->isp_param)->isp_ultramode = 0;
2789			((sdparam *)isp->isp_param)->isp_lvdmode = 1;
2790			break;
2791		case SXP_PINS_HVD_MODE:
2792			PRINTF("%s: Transition to Differential mode\n",
2793			    isp->isp_name);
2794			((sdparam *)isp->isp_param)->isp_diffmode = 1;
2795			((sdparam *)isp->isp_param)->isp_ultramode = 0;
2796			((sdparam *)isp->isp_param)->isp_lvdmode = 0;
2797			break;
2798		case SXP_PINS_SE_MODE:
2799			PRINTF("%s: Transition to Single Ended mode\n",
2800			    isp->isp_name);
2801			((sdparam *)isp->isp_param)->isp_diffmode = 0;
2802			((sdparam *)isp->isp_param)->isp_ultramode = 1;
2803			((sdparam *)isp->isp_param)->isp_lvdmode = 0;
2804			break;
2805		default:
2806			PRINTF("%s: Transition to unknown mode 0x%x\n",
2807			    isp->isp_name, mbox);
2808			break;
2809		}
2810		/*
2811		 * XXX: Set up to renegotiate again!
2812		 */
2813		/* Can only be for a 1080... */
2814		isp->isp_sendmarker |= (1 << bus);
2815		break;
2816
2817	case ASYNC_CMD_CMPLT:
2818		fast_post_handle = (ISP_READ(isp, OUTMAILBOX2) << 16) |
2819		    ISP_READ(isp, OUTMAILBOX1);
2820		IDPRINTF(4, ("%s: fast post completion of %u\n", isp->isp_name,
2821		    fast_post_handle));
2822		break;
2823
2824	case ASYNC_CTIO_DONE:
2825		/* Should only occur when Fast Posting Set for 2100s */
2826		PRINTF("%s: CTIO done\n", isp->isp_name);
2827		break;
2828
2829	case ASYNC_LIP_OCCURRED:
2830		((fcparam *) isp->isp_param)->isp_lipseq =
2831		    ISP_READ(isp, OUTMAILBOX1);
2832		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
2833		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
2834		isp->isp_sendmarker = 1;
2835		isp_mark_getpdb_all(isp);
2836		IDPRINTF(1, ("%s: LIP occurred\n", isp->isp_name));
2837#ifdef	ISP_TARGET_MODE
2838		isp_target_async(isp, bus, mbox);
2839#endif
2840		break;
2841
2842	case ASYNC_LOOP_UP:
2843		isp->isp_sendmarker = 1;
2844		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
2845		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
2846		isp_mark_getpdb_all(isp);
2847		isp_async(isp, ISPASYNC_LOOP_UP, NULL);
2848#ifdef	ISP_TARGET_MODE
2849		isp_target_async(isp, bus, mbox);
2850#endif
2851		break;
2852
2853	case ASYNC_LOOP_DOWN:
2854		isp->isp_sendmarker = 1;
2855		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
2856		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
2857		isp_mark_getpdb_all(isp);
2858		isp_async(isp, ISPASYNC_LOOP_DOWN, NULL);
2859#ifdef	ISP_TARGET_MODE
2860		isp_target_async(isp, bus, mbox);
2861#endif
2862		break;
2863
2864	case ASYNC_LOOP_RESET:
2865		isp->isp_sendmarker = 1;
2866		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
2867		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
2868		isp_mark_getpdb_all(isp);
2869		PRINTF("%s: Loop RESET\n", isp->isp_name);
2870#ifdef	ISP_TARGET_MODE
2871		isp_target_async(isp, bus, mbox);
2872#endif
2873		break;
2874
2875	case ASYNC_PDB_CHANGED:
2876		isp->isp_sendmarker = 1;
2877		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
2878		isp_mark_getpdb_all(isp);
2879		IDPRINTF(2, ("%s: Port Database Changed\n", isp->isp_name));
2880		break;
2881
2882	case ASYNC_CHANGE_NOTIFY:
2883		isp_mark_getpdb_all(isp);
2884		/*
2885		 * Not correct, but it will force us to rescan the loop.
2886		 */
2887		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
2888		isp_async(isp, ISPASYNC_CHANGE_NOTIFY, NULL);
2889		break;
2890
2891	case ASYNC_PTPMODE:
2892		if (((fcparam *) isp->isp_param)->isp_onfabric)
2893			((fcparam *) isp->isp_param)->isp_topo = TOPO_N_PORT;
2894		else
2895			((fcparam *) isp->isp_param)->isp_topo = TOPO_F_PORT;
2896		isp_mark_getpdb_all(isp);
2897		isp->isp_sendmarker = 1;
2898		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
2899		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
2900#ifdef	ISP_TARGET_MODE
2901		isp_target_async(isp, bus, mbox);
2902#endif
2903		PRINTF("%s: Point-to-Point mode\n", isp->isp_name);
2904		break;
2905
2906	case ASYNC_CONNMODE:
2907		mbox = ISP_READ(isp, OUTMAILBOX1);
2908		switch (mbox) {
2909		case ISP_CONN_LOOP:
2910			PRINTF("%s: Point-to-Point -> Loop mode\n",
2911			    isp->isp_name);
2912			break;
2913		case ISP_CONN_PTP:
2914			PRINTF("%s: Loop -> Point-to-Point mode\n",
2915			    isp->isp_name);
2916			break;
2917		case ISP_CONN_BADLIP:
2918			PRINTF("%s: Point-to-Point -> Loop mode (1)\n",
2919			    isp->isp_name);
2920			break;
2921		case ISP_CONN_FATAL:
2922			PRINTF("%s: FATAL CONNECTION ERROR\n", isp->isp_name);
2923			isp_restart(isp);
2924			/* no point continuing after this */
2925			return (-1);
2926
2927		case ISP_CONN_LOOPBACK:
2928			PRINTF("%s: Looped Back in Point-to-Point mode\n",
2929			     isp->isp_name);
2930		}
2931		break;
2932
2933	default:
2934		PRINTF("%s: unknown async code 0x%x\n", isp->isp_name, mbox);
2935		break;
2936	}
2937	return (fast_post_handle);
2938}
2939
2940/*
2941 * Handle other response entries. A pointer to the request queue output
2942 * index is here in case we want to eat several entries at once, although
2943 * this is not used currently.
2944 */
2945
2946static int
2947isp_handle_other_response(isp, sp, optrp)
2948	struct ispsoftc *isp;
2949	ispstatusreq_t *sp;
2950	u_int16_t *optrp;
2951{
2952	switch (sp->req_header.rqs_entry_type) {
2953	case RQSTYPE_ATIO:
2954	case RQSTYPE_CTIO:
2955	case RQSTYPE_ENABLE_LUN:
2956	case RQSTYPE_MODIFY_LUN:
2957	case RQSTYPE_NOTIFY:
2958	case RQSTYPE_NOTIFY_ACK:
2959	case RQSTYPE_CTIO1:
2960	case RQSTYPE_ATIO2:
2961	case RQSTYPE_CTIO2:
2962	case RQSTYPE_CTIO3:
2963#ifdef	ISP_TARGET_MODE
2964		return (isp_target_notify(isp, sp, optrp));
2965#else
2966		/* FALLTHROUGH */
2967#endif
2968	case RQSTYPE_REQUEST:
2969	default:
2970		PRINTF("%s: unhandled response type 0x%x\n", isp->isp_name,
2971		    sp->req_header.rqs_entry_type);
2972		return (-1);
2973	}
2974}
2975
2976static void
2977isp_parse_status(isp, sp, xs)
2978	struct ispsoftc *isp;
2979	ispstatusreq_t *sp;
2980	ISP_SCSI_XFER_T *xs;
2981{
2982	switch (sp->req_completion_status) {
2983	case RQCS_COMPLETE:
2984		XS_SETERR(xs, HBA_NOERROR);
2985		return;
2986
2987	case RQCS_INCOMPLETE:
2988		if ((sp->req_state_flags & RQSF_GOT_TARGET) == 0) {
2989			IDPRINTF(3, ("%s: Selection Timeout for %d.%d.%d\n",
2990			    isp->isp_name, XS_TGT(xs), XS_LUN(xs),
2991			    XS_CHANNEL(xs)));
2992			XS_SETERR(xs, HBA_SELTIMEOUT);
2993			return;
2994		}
2995		PRINTF("%s: command incomplete for %d.%d.%d, state 0x%x\n",
2996		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs),
2997		    sp->req_state_flags);
2998		break;
2999
3000	case RQCS_DMA_ERROR:
3001		PRINTF("%s: DMA error for command on %d.%d.%d\n",
3002		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3003		break;
3004
3005	case RQCS_TRANSPORT_ERROR:
3006		PRINTF("%s: transport error for %d.%d.%d\n",
3007		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3008		isp_prtstst(sp);
3009		break;
3010
3011	case RQCS_RESET_OCCURRED:
3012		IDPRINTF(1, ("%s: bus reset destroyed command for %d.%d.%d\n",
3013		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)));
3014		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
3015		XS_SETERR(xs, HBA_BUSRESET);
3016		return;
3017
3018	case RQCS_ABORTED:
3019		PRINTF("%s: command aborted for %d.%d.%d\n",
3020		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3021		isp->isp_sendmarker |= (1 << XS_CHANNEL(xs));
3022		XS_SETERR(xs, HBA_ABORTED);
3023		return;
3024
3025	case RQCS_TIMEOUT:
3026		IDPRINTF(2, ("%s: command timed out for %d.%d.%d\n",
3027		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs)));
3028		XS_SETERR(xs, HBA_CMDTIMEOUT);
3029		return;
3030
3031	case RQCS_DATA_OVERRUN:
3032		if (IS_FC(isp)) {
3033			XS_RESID(xs) = sp->req_resid;
3034			break;
3035		}
3036		PRINTF("%s: data overrun for command on %d.%d.%d\n",
3037		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3038		XS_SETERR(xs, HBA_DATAOVR);
3039		return;
3040
3041	case RQCS_COMMAND_OVERRUN:
3042		PRINTF("%s: command overrun for command on %d.%d.%d\n",
3043		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3044		break;
3045
3046	case RQCS_STATUS_OVERRUN:
3047		PRINTF("%s: status overrun for command on %d.%d.%d\n",
3048		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3049		break;
3050
3051	case RQCS_BAD_MESSAGE:
3052		PRINTF("%s: msg not COMMAND COMPLETE after status %d.%d.%d\n",
3053		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3054		break;
3055
3056	case RQCS_NO_MESSAGE_OUT:
3057		PRINTF("%s: No MESSAGE OUT phase after selection on %d.%d.%d\n",
3058		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3059		break;
3060
3061	case RQCS_EXT_ID_FAILED:
3062		PRINTF("%s: EXTENDED IDENTIFY failed %d.%d.%d\n",
3063		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3064		break;
3065
3066	case RQCS_IDE_MSG_FAILED:
3067		PRINTF("%s: INITIATOR DETECTED ERROR rejected by %d.%d.%d\n",
3068		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3069		break;
3070
3071	case RQCS_ABORT_MSG_FAILED:
3072		PRINTF("%s: ABORT OPERATION rejected by %d.%d.%d\n",
3073		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3074		break;
3075
3076	case RQCS_REJECT_MSG_FAILED:
3077		PRINTF("%s: MESSAGE REJECT rejected by %d.%d.%d\n",
3078		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3079		break;
3080
3081	case RQCS_NOP_MSG_FAILED:
3082		PRINTF("%s: NOP rejected by %d.%d.%d\n",
3083		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3084		break;
3085
3086	case RQCS_PARITY_ERROR_MSG_FAILED:
3087		PRINTF("%s: MESSAGE PARITY ERROR rejected by %d.%d.%d\n",
3088		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3089		break;
3090
3091	case RQCS_DEVICE_RESET_MSG_FAILED:
3092		PRINTF("%s: BUS DEVICE RESET rejected by %d.%d.%d\n",
3093		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3094		break;
3095
3096	case RQCS_ID_MSG_FAILED:
3097		PRINTF("%s: IDENTIFY rejected by %d.%d.%d\n",
3098		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3099		break;
3100
3101	case RQCS_UNEXP_BUS_FREE:
3102		PRINTF("%s: %d.%d.%d had an unexpected bus free\n",
3103		    isp->isp_name, XS_CHANNEL(xs), XS_TGT(xs), XS_LUN(xs));
3104		break;
3105
3106	case RQCS_DATA_UNDERRUN:
3107		if (IS_FC(isp)) {
3108			XS_RESID(xs) = sp->req_resid;
3109		}
3110		XS_SETERR(xs, HBA_NOERROR);
3111		return;
3112
3113	case RQCS_XACT_ERR1:
3114		PRINTF("%s: HBA attempted queued transaction with disconnect "
3115		    "not set for %d.%d.%d\n", isp->isp_name, XS_CHANNEL(xs),
3116		    XS_TGT(xs), XS_LUN(xs));
3117		break;
3118
3119	case RQCS_XACT_ERR2:
3120		PRINTF("%s: HBA attempted queued transaction to target "
3121		    "routine %d on target %d, bus %d\n", isp->isp_name,
3122		    XS_LUN(xs), XS_TGT(xs), XS_CHANNEL(xs));
3123		break;
3124
3125	case RQCS_XACT_ERR3:
3126		PRINTF("%s: HBA attempted queued transaction for target %d lun "
3127		    "%d on bus %d when queueing disabled\n", isp->isp_name,
3128		    XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3129		break;
3130
3131	case RQCS_BAD_ENTRY:
3132		PRINTF("%s: invalid IOCB entry type detected\n", isp->isp_name);
3133		break;
3134
3135	case RQCS_QUEUE_FULL:
3136		IDPRINTF(3, ("%s: internal queues full for target %d lun %d "
3137		    "bus %d, status 0x%x\n", isp->isp_name, XS_TGT(xs),
3138		    XS_LUN(xs), XS_CHANNEL(xs), XS_STS(xs)));
3139		/*
3140		 * If QFULL or some other status byte is set, then this
3141		 * isn't an error, per se.
3142		 */
3143		if (XS_STS(xs) != 0) {
3144			XS_SETERR(xs, HBA_NOERROR);
3145			return;
3146		}
3147		break;
3148
3149	case RQCS_PHASE_SKIPPED:
3150		PRINTF("%s: SCSI phase skipped (e.g., COMMAND COMPLETE w/o "
3151		    "STATUS phase) for target %d lun %d bus %d\n",
3152		    isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3153		break;
3154
3155	case RQCS_ARQS_FAILED:
3156		PRINTF("%s: Auto Request Sense failed for %d.%d.%d\n",
3157		    isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3158		return;
3159
3160	case RQCS_WIDE_FAILED:
3161		PRINTF("%s: Wide Negotiation failed for %d.%d.%d\n",
3162		    isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3163		if (IS_SCSI(isp)) {
3164			sdparam *sdp = isp->isp_param;
3165			sdp += XS_CHANNEL(xs);
3166			sdp->isp_devparam[XS_TGT(xs)].dev_flags &= ~DPARM_WIDE;
3167			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
3168			isp->isp_update |= (1 << XS_CHANNEL(xs));
3169		}
3170		XS_SETERR(xs, HBA_NOERROR);
3171		return;
3172
3173	case RQCS_SYNCXFER_FAILED:
3174		PRINTF("%s: SDTR Message failed for target %d.%d.%d\n",
3175		    isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3176		if (IS_SCSI(isp)) {
3177			sdparam *sdp = isp->isp_param;
3178			sdp += XS_CHANNEL(xs);
3179			sdp->isp_devparam[XS_TGT(xs)].dev_flags &= ~DPARM_SYNC;
3180			sdp->isp_devparam[XS_TGT(xs)].dev_update = 1;
3181			isp->isp_update |= (1 << XS_CHANNEL(xs));
3182		}
3183		break;
3184
3185	case RQCS_LVD_BUSERR:
3186		PRINTF("%s: Bad LVD condition while talking to %d.%d.%d\n",
3187		    isp->isp_name, XS_TGT(xs), XS_LUN(xs), XS_CHANNEL(xs));
3188		break;
3189
3190	case RQCS_PORT_UNAVAILABLE:
3191		/*
3192		 * No such port on the loop. Moral equivalent of SELTIMEO
3193		 */
3194		IDPRINTF(3, ("%s: Port Unavailable for target %d\n",
3195		    isp->isp_name, XS_TGT(xs)));
3196		XS_SETERR(xs, HBA_SELTIMEOUT);
3197		return;
3198
3199	case RQCS_PORT_LOGGED_OUT:
3200		/*
3201		 * It was there (maybe)- treat as a selection timeout.
3202		 */
3203		IDPRINTF(2, ("%s: port logout for target %d\n",
3204			isp->isp_name, XS_TGT(xs)));
3205		XS_SETERR(xs, HBA_SELTIMEOUT);
3206		return;
3207
3208	case RQCS_PORT_CHANGED:
3209		PRINTF("%s: port changed for target %d\n",
3210		    isp->isp_name, XS_TGT(xs));
3211		XS_SETERR(xs, HBA_SELTIMEOUT);
3212		return;
3213
3214	case RQCS_PORT_BUSY:
3215		PRINTF("%s: port busy for target %d\n",
3216		    isp->isp_name, XS_TGT(xs));
3217		XS_SETERR(xs, HBA_TGTBSY);
3218		return;
3219
3220	default:
3221		PRINTF("%s: completion status 0x%x\n",
3222		    isp->isp_name, sp->req_completion_status);
3223		break;
3224	}
3225	XS_SETERR(xs, HBA_BOTCH);
3226}
3227
3228static void
3229isp_fastpost_complete(isp, fph)
3230	struct ispsoftc *isp;
3231	u_int32_t fph;
3232{
3233	ISP_SCSI_XFER_T *xs;
3234
3235	if (fph < 1) {
3236		return;
3237	}
3238	xs = isp_find_xs(isp, fph);
3239	if (xs == NULL) {
3240		PRINTF("%s: command for fast posting handle 0x%x not found\n",
3241		    isp->isp_name, fph);
3242		return;
3243	}
3244	isp_destroy_handle(isp, fph);
3245
3246	/*
3247	 * Since we don't have a result queue entry item,
3248	 * we must believe that SCSI status is zero and
3249	 * that all data transferred.
3250	 */
3251	XS_RESID(xs) = 0;
3252	XS_STS(xs) = 0;
3253	if (XS_XFRLEN(xs)) {
3254		ISP_DMAFREE(isp, xs, fph);
3255	}
3256	XS_CMD_DONE(xs);
3257	if (isp->isp_nactive)
3258		isp->isp_nactive--;
3259}
3260
3261#define	HINIB(x)			((x) >> 0x4)
3262#define	LONIB(x)			((x)  & 0xf)
3263#define	MAKNIB(a, b)			(((a) << 4) | (b))
3264static u_int8_t mbpcnt[] = {
3265	MAKNIB(1, 1),	/* 0x00: MBOX_NO_OP */
3266	MAKNIB(5, 5),	/* 0x01: MBOX_LOAD_RAM */
3267	MAKNIB(2, 0),	/* 0x02: MBOX_EXEC_FIRMWARE */
3268	MAKNIB(5, 5),	/* 0x03: MBOX_DUMP_RAM */
3269	MAKNIB(3, 3),	/* 0x04: MBOX_WRITE_RAM_WORD */
3270	MAKNIB(2, 3),	/* 0x05: MBOX_READ_RAM_WORD */
3271	MAKNIB(6, 6),	/* 0x06: MBOX_MAILBOX_REG_TEST */
3272	MAKNIB(2, 3),	/* 0x07: MBOX_VERIFY_CHECKSUM	*/
3273	MAKNIB(1, 4),	/* 0x08: MBOX_ABOUT_FIRMWARE */
3274	MAKNIB(0, 0),	/* 0x09: */
3275	MAKNIB(0, 0),	/* 0x0a: */
3276	MAKNIB(0, 0),	/* 0x0b: */
3277	MAKNIB(0, 0),	/* 0x0c: */
3278	MAKNIB(0, 0),	/* 0x0d: */
3279	MAKNIB(1, 2),	/* 0x0e: MBOX_CHECK_FIRMWARE */
3280	MAKNIB(0, 0),	/* 0x0f: */
3281	MAKNIB(5, 5),	/* 0x10: MBOX_INIT_REQ_QUEUE */
3282	MAKNIB(6, 6),	/* 0x11: MBOX_INIT_RES_QUEUE */
3283	MAKNIB(4, 4),	/* 0x12: MBOX_EXECUTE_IOCB */
3284	MAKNIB(2, 2),	/* 0x13: MBOX_WAKE_UP	*/
3285	MAKNIB(1, 6),	/* 0x14: MBOX_STOP_FIRMWARE */
3286	MAKNIB(4, 4),	/* 0x15: MBOX_ABORT */
3287	MAKNIB(2, 2),	/* 0x16: MBOX_ABORT_DEVICE */
3288	MAKNIB(3, 3),	/* 0x17: MBOX_ABORT_TARGET */
3289	MAKNIB(3, 1),	/* 0x18: MBOX_BUS_RESET */
3290	MAKNIB(2, 3),	/* 0x19: MBOX_STOP_QUEUE */
3291	MAKNIB(2, 3),	/* 0x1a: MBOX_START_QUEUE */
3292	MAKNIB(2, 3),	/* 0x1b: MBOX_SINGLE_STEP_QUEUE */
3293	MAKNIB(2, 3),	/* 0x1c: MBOX_ABORT_QUEUE */
3294	MAKNIB(2, 4),	/* 0x1d: MBOX_GET_DEV_QUEUE_STATUS */
3295	MAKNIB(0, 0),	/* 0x1e: */
3296	MAKNIB(1, 3),	/* 0x1f: MBOX_GET_FIRMWARE_STATUS */
3297	MAKNIB(1, 4),	/* 0x20: MBOX_GET_INIT_SCSI_ID, MBOX_GET_LOOP_ID */
3298	MAKNIB(1, 3),	/* 0x21: MBOX_GET_SELECT_TIMEOUT */
3299	MAKNIB(1, 3),	/* 0x22: MBOX_GET_RETRY_COUNT	*/
3300	MAKNIB(1, 2),	/* 0x23: MBOX_GET_TAG_AGE_LIMIT */
3301	MAKNIB(1, 2),	/* 0x24: MBOX_GET_CLOCK_RATE */
3302	MAKNIB(1, 2),	/* 0x25: MBOX_GET_ACT_NEG_STATE */
3303	MAKNIB(1, 2),	/* 0x26: MBOX_GET_ASYNC_DATA_SETUP_TIME */
3304	MAKNIB(1, 3),	/* 0x27: MBOX_GET_PCI_PARAMS */
3305	MAKNIB(2, 4),	/* 0x28: MBOX_GET_TARGET_PARAMS */
3306	MAKNIB(2, 4),	/* 0x29: MBOX_GET_DEV_QUEUE_PARAMS */
3307	MAKNIB(1, 2),	/* 0x2a: MBOX_GET_RESET_DELAY_PARAMS */
3308	MAKNIB(0, 0),	/* 0x2b: */
3309	MAKNIB(0, 0),	/* 0x2c: */
3310	MAKNIB(0, 0),	/* 0x2d: */
3311	MAKNIB(0, 0),	/* 0x2e: */
3312	MAKNIB(0, 0),	/* 0x2f: */
3313	MAKNIB(2, 2),	/* 0x30: MBOX_SET_INIT_SCSI_ID */
3314	MAKNIB(2, 3),	/* 0x31: MBOX_SET_SELECT_TIMEOUT */
3315	MAKNIB(3, 3),	/* 0x32: MBOX_SET_RETRY_COUNT	*/
3316	MAKNIB(2, 2),	/* 0x33: MBOX_SET_TAG_AGE_LIMIT */
3317	MAKNIB(2, 2),	/* 0x34: MBOX_SET_CLOCK_RATE */
3318	MAKNIB(2, 2),	/* 0x35: MBOX_SET_ACT_NEG_STATE */
3319	MAKNIB(2, 2),	/* 0x36: MBOX_SET_ASYNC_DATA_SETUP_TIME */
3320	MAKNIB(3, 3),	/* 0x37: MBOX_SET_PCI_CONTROL_PARAMS */
3321	MAKNIB(4, 4),	/* 0x38: MBOX_SET_TARGET_PARAMS */
3322	MAKNIB(4, 4),	/* 0x39: MBOX_SET_DEV_QUEUE_PARAMS */
3323	MAKNIB(1, 2),	/* 0x3a: MBOX_SET_RESET_DELAY_PARAMS */
3324	MAKNIB(0, 0),	/* 0x3b: */
3325	MAKNIB(0, 0),	/* 0x3c: */
3326	MAKNIB(0, 0),	/* 0x3d: */
3327	MAKNIB(0, 0),	/* 0x3e: */
3328	MAKNIB(0, 0),	/* 0x3f: */
3329	MAKNIB(1, 2),	/* 0x40: MBOX_RETURN_BIOS_BLOCK_ADDR */
3330	MAKNIB(6, 1),	/* 0x41: MBOX_WRITE_FOUR_RAM_WORDS */
3331	MAKNIB(2, 3),	/* 0x42: MBOX_EXEC_BIOS_IOCB */
3332	MAKNIB(0, 0),	/* 0x43: */
3333	MAKNIB(0, 0),	/* 0x44: */
3334	MAKNIB(0, 0),	/* 0x45: */
3335	MAKNIB(0, 0),	/* 0x46: */
3336	MAKNIB(0, 0),	/* 0x47: */
3337	MAKNIB(0, 0),	/* 0x48: */
3338	MAKNIB(0, 0),	/* 0x49: */
3339	MAKNIB(2, 1),	/* 0x4a: MBOX_SET_FIRMWARE_FEATURES */
3340	MAKNIB(1, 2),	/* 0x4b: MBOX_GET_FIRMWARE_FEATURES */
3341	MAKNIB(0, 0),	/* 0x4c: */
3342	MAKNIB(0, 0),	/* 0x4d: */
3343	MAKNIB(0, 0),	/* 0x4e: */
3344	MAKNIB(0, 0),	/* 0x4f: */
3345	MAKNIB(0, 0),	/* 0x50: */
3346	MAKNIB(0, 0),	/* 0x51: */
3347	MAKNIB(0, 0),	/* 0x52: */
3348	MAKNIB(0, 0),	/* 0x53: */
3349	MAKNIB(8, 0),	/* 0x54: MBOX_EXEC_COMMAND_IOCB_A64 */
3350	MAKNIB(2, 1),	/* 0x55: MBOX_ENABLE_TARGET_MODE */
3351	MAKNIB(0, 0),	/* 0x56: */
3352	MAKNIB(0, 0),	/* 0x57: */
3353	MAKNIB(0, 0),	/* 0x58: */
3354	MAKNIB(0, 0),	/* 0x59: */
3355	MAKNIB(0, 0),	/* 0x5a: */
3356	MAKNIB(0, 0),	/* 0x5b: */
3357	MAKNIB(0, 0),	/* 0x5c: */
3358	MAKNIB(0, 0),	/* 0x5d: */
3359	MAKNIB(0, 0),	/* 0x5e: */
3360	MAKNIB(0, 0),	/* 0x5f: */
3361	MAKNIB(8, 6),	/* 0x60: MBOX_INIT_FIRMWARE */
3362	MAKNIB(0, 0),	/* 0x61: */
3363	MAKNIB(2, 1),	/* 0x62: MBOX_INIT_LIP */
3364	MAKNIB(8, 1),	/* 0x63: MBOX_GET_FC_AL_POSITION_MAP */
3365	MAKNIB(8, 1),	/* 0x64: MBOX_GET_PORT_DB */
3366	MAKNIB(3, 1),	/* 0x65: MBOX_CLEAR_ACA */
3367	MAKNIB(3, 1),	/* 0x66: MBOX_TARGET_RESET */
3368	MAKNIB(3, 1),	/* 0x67: MBOX_CLEAR_TASK_SET */
3369	MAKNIB(3, 1),	/* 0x68: MBOX_ABORT_TASK_SET */
3370	MAKNIB(1, 2),	/* 0x69: MBOX_GET_FW_STATE */
3371	MAKNIB(2, 8),	/* 0x6a: MBOX_GET_PORT_NAME */
3372	MAKNIB(8, 1),	/* 0x6b: MBOX_GET_LINK_STATUS */
3373	MAKNIB(4, 4),	/* 0x6c: MBOX_INIT_LIP_RESET */
3374	MAKNIB(0, 0),	/* 0x6d: */
3375	MAKNIB(8, 2),	/* 0x6e: MBOX_SEND_SNS */
3376	MAKNIB(4, 3),	/* 0x6f: MBOX_FABRIC_LOGIN */
3377	MAKNIB(2, 1),	/* 0x70: MBOX_SEND_CHANGE_REQUEST */
3378	MAKNIB(2, 1),	/* 0x71: MBOX_FABRIC_LOGOUT */
3379	MAKNIB(4, 1)	/* 0x72: MBOX_INIT_LIP_LOGIN */
3380};
3381#define	NMBCOM	(sizeof (mbpcnt) / sizeof (mbpcnt[0]))
3382
3383static void
3384isp_mboxcmd(isp, mbp)
3385	struct ispsoftc *isp;
3386	mbreg_t *mbp;
3387{
3388	int outparam, inparam;
3389	int loops, dld = 0;
3390	u_int8_t opcode;
3391
3392	if (mbp->param[0] == ISP2100_SET_PCI_PARAM) {
3393		opcode = mbp->param[0] = MBOX_SET_PCI_PARAMETERS;
3394		inparam = 4;
3395		outparam = 4;
3396		goto command_known;
3397	} else if (mbp->param[0] > NMBCOM) {
3398		PRINTF("%s: bad command %x\n", isp->isp_name, mbp->param[0]);
3399		return;
3400	}
3401
3402	opcode = mbp->param[0];
3403	inparam = HINIB(mbpcnt[mbp->param[0]]);
3404	outparam =  LONIB(mbpcnt[mbp->param[0]]);
3405
3406	if (inparam == 0 && outparam == 0) {
3407		PRINTF("%s: no parameters for %x\n", isp->isp_name,
3408			mbp->param[0]);
3409		return;
3410	}
3411
3412
3413	/*
3414	 * Check for variants
3415	 */
3416	if (IS_FC(isp) && isp->isp_maxluns > 16) {
3417		switch (mbp->param[0]) {
3418		case MBOX_ABORT:
3419			inparam = 7;
3420			break;
3421		case MBOX_ABORT_DEVICE:
3422		case MBOX_START_QUEUE:
3423		case MBOX_STOP_QUEUE:
3424		case MBOX_SINGLE_STEP_QUEUE:
3425		case MBOX_ABORT_QUEUE:
3426		case MBOX_GET_DEV_QUEUE_STATUS:
3427			inparam = 3;
3428			break;
3429		case MBOX_BUS_RESET:
3430			inparam = 2;
3431			break;
3432		default:
3433			break;
3434		}
3435	}
3436
3437command_known:
3438
3439	/*
3440	 * Set semaphore on mailbox registers to win any races to acquire them.
3441	 */
3442	ISP_WRITE(isp, BIU_SEMA, 1);
3443
3444	/*
3445	 * Qlogic Errata for the ISP2100 says that there is a necessary
3446	 * debounce between between writing the semaphore register
3447	 * and reading a mailbox register. I believe we're okay here.
3448	 */
3449
3450	/*
3451	 * Make sure we can send some words.
3452	 * Check to see if there's an async mbox event pending.
3453	 */
3454
3455	loops = MBOX_DELAY_COUNT;
3456	while ((ISP_READ(isp, HCCR) & HCCR_HOST_INT) != 0) {
3457		if (ISP_READ(isp, BIU_SEMA) & 1) {
3458			int fph;
3459			u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
3460			/*
3461			 * We have a pending MBOX async event.
3462			 */
3463			if (mbox & 0x8000) {
3464				fph = isp_parse_async(isp, (int) mbox);
3465				IDPRINTF(5, ("%s: line %d, fph %d\n",
3466				    isp->isp_name, __LINE__, fph));
3467				ISP_WRITE(isp, BIU_SEMA, 0);
3468				ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3469				if (fph < 0) {
3470					return;
3471				} else if (fph > 0) {
3472					isp_fastpost_complete(isp, fph);
3473				}
3474				SYS_DELAY(100);
3475				goto command_known;
3476			}
3477			/*
3478			 * We have a pending MBOX completion? Might be
3479			 * from a previous command. We can't (sometimes)
3480			 * just clear HOST INTERRUPT, so we'll just silently
3481			 * eat this here.
3482			 */
3483			if (mbox & 0x4000) {
3484				IDPRINTF(5, ("%s: line %d, mbox 0x%x\n",
3485				    isp->isp_name, __LINE__, mbox));
3486				ISP_WRITE(isp, BIU_SEMA, 0);
3487				ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3488				SYS_DELAY(100);
3489				goto command_known;
3490			}
3491		}
3492		SYS_DELAY(100);
3493		if (--loops < 0) {
3494			if (dld++ > 10) {
3495				PRINTF("%s: isp_mboxcmd could not get command "
3496				    "started\n", isp->isp_name);
3497				return;
3498			}
3499			ISP_WRITE(isp, BIU_SEMA, 0);
3500			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3501			goto command_known;
3502		}
3503	}
3504
3505	/*
3506	 * Write input parameters.
3507	 *
3508	 * Special case some of the setups for the dual port SCSI cards.
3509	 * XXX Eventually will be fixed by converting register write/read
3510	 * XXX counts to bitmasks.
3511	 */
3512	if (IS_DUALBUS(isp)) {
3513		switch (opcode) {
3514		case MBOX_GET_RETRY_COUNT:
3515		case MBOX_SET_RETRY_COUNT:
3516			ISP_WRITE(isp, INMAILBOX7, mbp->param[7]);
3517			mbp->param[7] = 0;
3518			ISP_WRITE(isp, INMAILBOX6, mbp->param[6]);
3519			mbp->param[6] = 0;
3520			break;
3521		case MBOX_SET_ASYNC_DATA_SETUP_TIME:
3522		case MBOX_SET_ACT_NEG_STATE:
3523		case MBOX_SET_TAG_AGE_LIMIT:
3524		case MBOX_SET_SELECT_TIMEOUT:
3525			ISP_WRITE(isp, INMAILBOX2, mbp->param[2]);
3526			mbp->param[2] = 0;
3527			break;
3528		}
3529	}
3530
3531	switch (inparam) {
3532	case 8: ISP_WRITE(isp, INMAILBOX7, mbp->param[7]); mbp->param[7] = 0;
3533	case 7: ISP_WRITE(isp, INMAILBOX6, mbp->param[6]); mbp->param[6] = 0;
3534	case 6:
3535		/*
3536		 * The Qlogic 2100 cannot have registers 4 and 5 written to
3537		 * after initialization or BAD THINGS HAPPEN (tm).
3538		 */
3539		if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
3540			ISP_WRITE(isp, INMAILBOX5, mbp->param[5]);
3541		mbp->param[5] = 0;
3542	case 5:
3543		if (IS_SCSI(isp) || mbp->param[0] == MBOX_INIT_FIRMWARE)
3544			ISP_WRITE(isp, INMAILBOX4, mbp->param[4]);
3545		mbp->param[4] = 0;
3546	case 4: ISP_WRITE(isp, INMAILBOX3, mbp->param[3]); mbp->param[3] = 0;
3547	case 3: ISP_WRITE(isp, INMAILBOX2, mbp->param[2]); mbp->param[2] = 0;
3548	case 2: ISP_WRITE(isp, INMAILBOX1, mbp->param[1]); mbp->param[1] = 0;
3549	case 1: ISP_WRITE(isp, INMAILBOX0, mbp->param[0]); mbp->param[0] = 0;
3550	}
3551
3552	/*
3553	 * Clear RISC int condition.
3554	 */
3555	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3556
3557	/*
3558	 * Clear semaphore on mailbox registers so that the Qlogic
3559	 * may update outgoing registers.
3560	 */
3561	ISP_WRITE(isp, BIU_SEMA, 0);
3562
3563	/*
3564	 * Set Host Interrupt condition so that RISC will pick up mailbox regs.
3565	 */
3566	ISP_WRITE(isp, HCCR, HCCR_CMD_SET_HOST_INT);
3567
3568	/*
3569	 * Wait until HOST INT has gone away (meaning that the Qlogic
3570	 * has picked up the mailbox command. Wait a long time.
3571	 */
3572	loops = MBOX_DELAY_COUNT * 5;
3573	while ((ISP_READ(isp, HCCR) & HCCR_CMD_CLEAR_RISC_INT) != 0) {
3574		SYS_DELAY(100);
3575		if (--loops < 0) {
3576			PRINTF("%s: isp_mboxcmd timeout #2\n", isp->isp_name);
3577			return;
3578		}
3579	}
3580
3581	/*
3582	 * While the Semaphore registers isn't set, wait for the Qlogic
3583	 * to process the mailbox command. Again- wait a long time.
3584	 */
3585	loops = MBOX_DELAY_COUNT * 5;
3586	while ((ISP_READ(isp, BIU_SEMA) & 1) == 0) {
3587		SYS_DELAY(100);
3588		/*
3589		 * Wierd- I've seen the case where the semaphore register
3590		 * isn't getting set- sort of a violation of the protocol..
3591		 */
3592		if (ISP_READ(isp, OUTMAILBOX0) & 0x4000)
3593			break;
3594		if (--loops < 0) {
3595			PRINTF("%s: isp_mboxcmd timeout #3\n", isp->isp_name);
3596			return;
3597		}
3598	}
3599
3600	/*
3601	 * Make sure that the MBOX_BUSY has gone away
3602	 */
3603	loops = MBOX_DELAY_COUNT;
3604	for (;;) {
3605		u_int16_t mbox = ISP_READ(isp, OUTMAILBOX0);
3606		if (mbox == MBOX_BUSY) {
3607			if (--loops < 0) {
3608				PRINTF("%s: isp_mboxcmd timeout #4\n",
3609				    isp->isp_name);
3610				return;
3611			}
3612			SYS_DELAY(100);
3613			continue;
3614		}
3615		/*
3616		 * We have a pending MBOX async event.
3617		 */
3618		if (mbox & 0x8000) {
3619			int fph = isp_parse_async(isp, (int) mbox);
3620			ISP_WRITE(isp, BIU_SEMA, 0);
3621			ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3622			if (fph < 0) {
3623				return;
3624			} else if (fph > 0) {
3625				isp_fastpost_complete(isp, fph);
3626			}
3627			SYS_DELAY(100);
3628			continue;
3629		}
3630		break;
3631	}
3632
3633	/*
3634	 * Pick up output parameters. Special case some of the readbacks
3635	 * for the dual port SCSI cards.
3636	 */
3637	if (IS_DUALBUS(isp)) {
3638		switch (opcode) {
3639		case MBOX_GET_RETRY_COUNT:
3640		case MBOX_SET_RETRY_COUNT:
3641			mbp->param[7] = ISP_READ(isp, OUTMAILBOX7);
3642			mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
3643			break;
3644		case MBOX_GET_TAG_AGE_LIMIT:
3645		case MBOX_SET_TAG_AGE_LIMIT:
3646		case MBOX_GET_ACT_NEG_STATE:
3647		case MBOX_SET_ACT_NEG_STATE:
3648		case MBOX_SET_ASYNC_DATA_SETUP_TIME:
3649		case MBOX_GET_ASYNC_DATA_SETUP_TIME:
3650		case MBOX_GET_RESET_DELAY_PARAMS:
3651		case MBOX_SET_RESET_DELAY_PARAMS:
3652			mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
3653			break;
3654		}
3655	}
3656
3657	if (IS_2200(isp)) {
3658		if (opcode == MBOX_GET_LOOP_ID) {
3659			mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
3660		}
3661	}
3662
3663	switch (outparam) {
3664	case 8: mbp->param[7] = ISP_READ(isp, OUTMAILBOX7);
3665	case 7: mbp->param[6] = ISP_READ(isp, OUTMAILBOX6);
3666	case 6: mbp->param[5] = ISP_READ(isp, OUTMAILBOX5);
3667	case 5: mbp->param[4] = ISP_READ(isp, OUTMAILBOX4);
3668	case 4: mbp->param[3] = ISP_READ(isp, OUTMAILBOX3);
3669	case 3: mbp->param[2] = ISP_READ(isp, OUTMAILBOX2);
3670	case 2: mbp->param[1] = ISP_READ(isp, OUTMAILBOX1);
3671	case 1: mbp->param[0] = ISP_READ(isp, OUTMAILBOX0);
3672	}
3673
3674	/*
3675	 * Clear RISC int.
3676	 */
3677	ISP_WRITE(isp, HCCR, HCCR_CMD_CLEAR_RISC_INT);
3678
3679	/*
3680	 * Release semaphore on mailbox registers
3681	 */
3682	ISP_WRITE(isp, BIU_SEMA, 0);
3683
3684	/*
3685	 * Just to be chatty here...
3686	 */
3687	switch (mbp->param[0]) {
3688	case MBOX_COMMAND_COMPLETE:
3689		break;
3690	case MBOX_INVALID_COMMAND:
3691		IDPRINTF(2, ("%s: mbox cmd %x failed with INVALID_COMMAND\n",
3692		    isp->isp_name, opcode));
3693		break;
3694	case MBOX_HOST_INTERFACE_ERROR:
3695		PRINTF("%s: mbox cmd %x failed with HOST_INTERFACE_ERROR\n",
3696		    isp->isp_name, opcode);
3697		break;
3698	case MBOX_TEST_FAILED:
3699		PRINTF("%s: mbox cmd %x failed with TEST_FAILED\n",
3700		    isp->isp_name, opcode);
3701		break;
3702	case MBOX_COMMAND_ERROR:
3703		if (opcode != MBOX_ABOUT_FIRMWARE)
3704		    PRINTF("%s: mbox cmd %x failed with COMMAND_ERROR\n",
3705			isp->isp_name, opcode);
3706		break;
3707	case MBOX_COMMAND_PARAM_ERROR:
3708		switch (opcode) {
3709		case MBOX_GET_PORT_DB:
3710		case MBOX_GET_PORT_NAME:
3711		case MBOX_GET_DEV_QUEUE_PARAMS:
3712			break;
3713		default:
3714			PRINTF("%s: mbox cmd %x failed with "
3715			    "COMMAND_PARAM_ERROR\n", isp->isp_name, opcode);
3716		}
3717		break;
3718
3719	case MBOX_LOOP_ID_USED:
3720	case MBOX_PORT_ID_USED:
3721	case MBOX_ALL_IDS_USED:
3722		break;
3723
3724
3725	/*
3726	 * Be silent about these...
3727	 */
3728	case ASYNC_PDB_CHANGED:
3729		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_PDB_RCVD;
3730		break;
3731
3732	case ASYNC_LIP_OCCURRED:
3733		((fcparam *) isp->isp_param)->isp_lipseq = mbp->param[1];
3734		/* FALLTHROUGH */
3735	case ASYNC_LOOP_UP:
3736		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
3737		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_LIP_RCVD;
3738		break;
3739
3740	case ASYNC_LOOP_DOWN:
3741	case ASYNC_LOOP_RESET:
3742		((fcparam *) isp->isp_param)->isp_fwstate = FW_CONFIG_WAIT;
3743		((fcparam *) isp->isp_param)->isp_loopstate = LOOP_NIL;
3744		/* FALLTHROUGH */
3745	case ASYNC_CHANGE_NOTIFY:
3746		break;
3747
3748	default:
3749		/*
3750		 * The expected return of EXEC_FIRMWARE is zero.
3751		 */
3752		if ((opcode == MBOX_EXEC_FIRMWARE && mbp->param[0] != 0) ||
3753		    (opcode != MBOX_EXEC_FIRMWARE)) {
3754			PRINTF("%s: mbox cmd %x failed with error %x\n",
3755				isp->isp_name, opcode, mbp->param[0]);
3756		}
3757		break;
3758	}
3759}
3760
3761void
3762isp_lostcmd(isp, xs)
3763	struct ispsoftc *isp;
3764	ISP_SCSI_XFER_T *xs;
3765{
3766	mbreg_t mbs;
3767
3768	mbs.param[0] = MBOX_GET_FIRMWARE_STATUS;
3769	isp_mboxcmd(isp, &mbs);
3770	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3771		isp_dumpregs(isp, "couldn't GET FIRMWARE STATUS");
3772		return;
3773	}
3774	if (mbs.param[1]) {
3775		PRINTF("%s: %d commands on completion queue\n",
3776		    isp->isp_name, mbs.param[1]);
3777	}
3778	if (XS_NULL(xs))
3779		return;
3780
3781	mbs.param[0] = MBOX_GET_DEV_QUEUE_STATUS;
3782	mbs.param[1] = (XS_TGT(xs) << 8) | XS_LUN(xs); /* XXX: WHICH BUS? */
3783	isp_mboxcmd(isp, &mbs);
3784	if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3785		isp_dumpregs(isp, "couldn't GET DEVICE QUEUE STATUS");
3786		return;
3787	}
3788	PRINTF("%s: lost command for target %d lun %d, %d active of %d, "
3789		"Queue State: %x\n", isp->isp_name, XS_TGT(xs),
3790		XS_LUN(xs), mbs.param[2], mbs.param[3], mbs.param[1]);
3791
3792	isp_dumpregs(isp, "lost command");
3793	/*
3794	 * XXX: Need to try and do something to recover.
3795	 */
3796}
3797
3798static void
3799isp_dumpregs(isp, msg)
3800	struct ispsoftc *isp;
3801	const char *msg;
3802{
3803	PRINTF("%s: %s\n", isp->isp_name, msg);
3804	if (IS_SCSI(isp))
3805		PRINTF("    biu_conf1=%x", ISP_READ(isp, BIU_CONF1));
3806	else
3807		PRINTF("    biu_csr=%x", ISP_READ(isp, BIU2100_CSR));
3808	PRINTF(" biu_icr=%x biu_isr=%x biu_sema=%x ", ISP_READ(isp, BIU_ICR),
3809	    ISP_READ(isp, BIU_ISR), ISP_READ(isp, BIU_SEMA));
3810	PRINTF("risc_hccr=%x\n", ISP_READ(isp, HCCR));
3811
3812
3813	if (IS_SCSI(isp)) {
3814		ISP_WRITE(isp, HCCR, HCCR_CMD_PAUSE);
3815		PRINTF("    cdma_conf=%x cdma_sts=%x cdma_fifostat=%x\n",
3816			ISP_READ(isp, CDMA_CONF), ISP_READ(isp, CDMA_STATUS),
3817			ISP_READ(isp, CDMA_FIFO_STS));
3818		PRINTF("    ddma_conf=%x ddma_sts=%x ddma_fifostat=%x\n",
3819			ISP_READ(isp, DDMA_CONF), ISP_READ(isp, DDMA_STATUS),
3820			ISP_READ(isp, DDMA_FIFO_STS));
3821		PRINTF("    sxp_int=%x sxp_gross=%x sxp(scsi_ctrl)=%x\n",
3822			ISP_READ(isp, SXP_INTERRUPT),
3823			ISP_READ(isp, SXP_GROSS_ERR),
3824			ISP_READ(isp, SXP_PINS_CTRL));
3825		ISP_WRITE(isp, HCCR, HCCR_CMD_RELEASE);
3826	}
3827	PRINTF("    mbox regs: %x %x %x %x %x\n",
3828	    ISP_READ(isp, OUTMAILBOX0), ISP_READ(isp, OUTMAILBOX1),
3829	    ISP_READ(isp, OUTMAILBOX2), ISP_READ(isp, OUTMAILBOX3),
3830	    ISP_READ(isp, OUTMAILBOX4));
3831	ISP_DUMPREGS(isp);
3832}
3833
3834static void
3835isp_fw_state(isp)
3836	struct ispsoftc *isp;
3837{
3838	mbreg_t mbs;
3839	if (IS_FC(isp)) {
3840		int once = 0;
3841		fcparam *fcp = isp->isp_param;
3842again:
3843		mbs.param[0] = MBOX_GET_FW_STATE;
3844		isp_mboxcmd(isp, &mbs);
3845		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3846			IDPRINTF(1, ("%s: isp_fw_state 0x%x\n", isp->isp_name,
3847			    mbs.param[0]));
3848			switch (mbs.param[0]) {
3849			case ASYNC_PDB_CHANGED:
3850				if (once++ < 10) {
3851					goto again;
3852				}
3853				fcp->isp_fwstate = FW_CONFIG_WAIT;
3854				fcp->isp_loopstate = LOOP_PDB_RCVD;
3855				goto again;
3856			case ASYNC_LIP_OCCURRED:
3857				fcp->isp_lipseq = mbs.param[1];
3858				/* FALLTHROUGH */
3859			case ASYNC_LOOP_UP:
3860				fcp->isp_fwstate = FW_CONFIG_WAIT;
3861				fcp->isp_loopstate = LOOP_LIP_RCVD;
3862				if (once++ < 10) {
3863					goto again;
3864				}
3865				break;
3866			case ASYNC_LOOP_RESET:
3867			case ASYNC_LOOP_DOWN:
3868				fcp->isp_fwstate = FW_CONFIG_WAIT;
3869				fcp->isp_loopstate = LOOP_NIL;
3870				/* FALLTHROUGH */
3871			case ASYNC_CHANGE_NOTIFY:
3872				if (once++ < 10) {
3873					goto again;
3874				}
3875				break;
3876			}
3877			PRINTF("%s: GET FIRMWARE STATE failed (0x%x)\n",
3878			    isp->isp_name, mbs.param[0]);
3879			return;
3880		}
3881		fcp->isp_fwstate = mbs.param[1];
3882	}
3883}
3884
3885static void
3886isp_update(isp)
3887	struct ispsoftc *isp;
3888{
3889	int bus;
3890
3891	for (bus = 0; isp->isp_update != 0; bus++) {
3892		if (isp->isp_update & (1 << bus)) {
3893			isp_update_bus(isp, bus);
3894			isp->isp_update ^= (1 << bus);
3895		}
3896	}
3897}
3898
3899static void
3900isp_update_bus(isp, bus)
3901	struct ispsoftc *isp;
3902	int bus;
3903{
3904	int tgt;
3905	mbreg_t mbs;
3906	sdparam *sdp;
3907
3908	if (IS_FC(isp)) {
3909		return;
3910	}
3911
3912	sdp = isp->isp_param;
3913	sdp += bus;
3914
3915	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
3916		u_int16_t flags, period, offset;
3917		int get;
3918
3919		if (sdp->isp_devparam[tgt].dev_enable == 0) {
3920			IDPRINTF(1, ("%s: skipping target %d bus %d update\n",
3921			    isp->isp_name, tgt, bus));
3922			continue;
3923		}
3924
3925		/*
3926		 * If the goal is to update the status of the device,
3927		 * take what's in dev_flags and try and set the device
3928		 * toward that. Otherwise, if we're just refreshing the
3929		 * current device state, get the current parameters.
3930		 */
3931		if (sdp->isp_devparam[tgt].dev_update) {
3932			mbs.param[0] = MBOX_SET_TARGET_PARAMS;
3933			mbs.param[2] = sdp->isp_devparam[tgt].dev_flags;
3934			/*
3935			 * Insist that PARITY must be enabled if SYNC
3936			 * is enabled.
3937			 */
3938			if (mbs.param[2] & DPARM_SYNC) {
3939				mbs.param[2] |= DPARM_PARITY;
3940			}
3941			mbs.param[3] =
3942				(sdp->isp_devparam[tgt].sync_offset << 8) |
3943				(sdp->isp_devparam[tgt].sync_period);
3944			sdp->isp_devparam[tgt].dev_update = 0;
3945			/*
3946			 * A command completion later that has
3947			 * RQSTF_NEGOTIATION set will cause
3948			 * the dev_refresh/announce cycle.
3949			 *
3950			 * Note: It is really important to update our current
3951			 * flags with at least the state of TAG capabilities-
3952			 * otherwise we might try and send a tagged command
3953			 * when we have it all turned off. So change it here
3954			 * to say that current already matches goal.
3955			 */
3956			sdp->isp_devparam[tgt].cur_dflags &= ~DPARM_TQING;
3957			sdp->isp_devparam[tgt].cur_dflags |=
3958			    (sdp->isp_devparam[tgt].dev_flags & DPARM_TQING);
3959			sdp->isp_devparam[tgt].dev_refresh = 1;
3960			IDPRINTF(3, ("%s: bus %d set tgt %d flags 0x%x off 0x%x"
3961			    " period 0x%x\n", isp->isp_name, bus, tgt,
3962			    mbs.param[2], mbs.param[3] >> 8,
3963			    mbs.param[3] & 0xff));
3964			get = 0;
3965		} else if (sdp->isp_devparam[tgt].dev_refresh) {
3966			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
3967			sdp->isp_devparam[tgt].dev_refresh = 0;
3968			get = 1;
3969		} else {
3970			continue;
3971		}
3972		mbs.param[1] = (bus << 15) | (tgt << 8) ;
3973		isp_mboxcmd(isp, &mbs);
3974		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
3975			PRINTF("%s: failed to %cet SCSI parameters for "
3976			    "target %d\n", isp->isp_name, (get)? 'g' : 's',
3977			    tgt);
3978			continue;
3979		}
3980		if (get == 0) {
3981			isp->isp_sendmarker |= (1 << bus);
3982			continue;
3983		}
3984		flags = mbs.param[2];
3985		period = mbs.param[3] & 0xff;
3986		offset = mbs.param[3] >> 8;
3987		sdp->isp_devparam[tgt].cur_dflags = flags;
3988		sdp->isp_devparam[tgt].cur_period = period;
3989		sdp->isp_devparam[tgt].cur_offset = offset;
3990		get = (bus << 16) | tgt;
3991		(void) isp_async(isp, ISPASYNC_NEW_TGT_PARAMS, &get);
3992	}
3993}
3994
3995static void
3996isp_setdfltparm(isp, channel)
3997	struct ispsoftc *isp;
3998	int channel;
3999{
4000	int tgt;
4001	mbreg_t mbs;
4002	sdparam *sdp;
4003
4004	if (IS_FC(isp)) {
4005		fcparam *fcp = (fcparam *) isp->isp_param;
4006		fcp += channel;
4007		if (fcp->isp_gotdparms) {
4008			return;
4009		}
4010		fcp->isp_gotdparms = 1;
4011		fcp->isp_maxfrmlen = ICB_DFLT_FRMLEN;
4012		fcp->isp_maxalloc = ICB_DFLT_ALLOC;
4013		fcp->isp_execthrottle = ICB_DFLT_THROTTLE;
4014		fcp->isp_retry_delay = ICB_DFLT_RDELAY;
4015		fcp->isp_retry_count = ICB_DFLT_RCOUNT;
4016		/* Platform specific.... */
4017		fcp->isp_loopid = DEFAULT_LOOPID(isp);
4018		fcp->isp_nodewwn = DEFAULT_WWN(isp);
4019		if ((fcp->isp_nodewwn >> 60) == 2) {
4020			fcp->isp_nodewwn &= ~((u_int64_t) 0xfff << 48);
4021			fcp->isp_portwwn = fcp->isp_nodewwn |
4022			    (((u_int64_t)(isp->isp_unit+1)) << 48);
4023		} else {
4024			fcp->isp_portwwn = fcp->isp_nodewwn;
4025		}
4026		/*
4027		 * Now try and read NVRAM
4028		 */
4029		if ((isp->isp_confopts & (ISP_CFG_NONVRAM|ISP_CFG_OWNWWN)) ||
4030		    (isp_read_nvram(isp))) {
4031			PRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
4032			    isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
4033			    (u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
4034			    (u_int32_t) (fcp->isp_portwwn >> 32),
4035			    (u_int32_t) (fcp->isp_portwwn & 0xffffffff));
4036		}
4037		return;
4038	}
4039
4040	sdp = (sdparam *) isp->isp_param;
4041	sdp += channel;
4042
4043	/*
4044	 * Been there, done that, got the T-shirt...
4045	 */
4046	if (sdp->isp_gotdparms) {
4047		return;
4048	}
4049	sdp->isp_gotdparms = 1;
4050
4051	/*
4052	 * If we've not been told to avoid reading NVRAM, try and read it.
4053	 * If we're successful reading it, we can return since NVRAM will
4054	 * tell us the right thing to do. Otherwise, establish some reasonable
4055	 * defaults.
4056	 */
4057	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4058		if (isp_read_nvram(isp) == 0) {
4059			return;
4060		}
4061	}
4062
4063	/*
4064	 * Now try and see whether we have specific values for them.
4065	 */
4066	if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4067		mbs.param[0] = MBOX_GET_ACT_NEG_STATE;
4068		isp_mboxcmd(isp, &mbs);
4069		if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4070			IDPRINTF(2, ("could not GET ACT NEG STATE\n"));
4071			sdp->isp_req_ack_active_neg = 1;
4072			sdp->isp_data_line_active_neg = 1;
4073		} else {
4074			sdp->isp_req_ack_active_neg =
4075			    (mbs.param[1+channel] >> 4) & 0x1;
4076			sdp->isp_data_line_active_neg =
4077			    (mbs.param[1+channel] >> 5) & 0x1;
4078		}
4079	} else {
4080		sdp->isp_req_ack_active_neg = 1;
4081		sdp->isp_data_line_active_neg = 1;
4082	}
4083
4084	IDPRINTF(3, ("%s: defaulting bus %d REQ/ACK Active Negation is %d\n",
4085	    isp->isp_name, channel, sdp->isp_req_ack_active_neg));
4086	IDPRINTF(3, ("%s: defaulting bus %d DATA Active Negation is %d\n",
4087	    isp->isp_name, channel, sdp->isp_data_line_active_neg));
4088
4089	/*
4090	 * The trick here is to establish a default for the default (honk!)
4091	 * state (dev_flags). Then try and get the current status from
4092	 * the card to fill in the current state. We don't, in fact, set
4093	 * the default to the SAFE default state- that's not the goal state.
4094	 */
4095	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
4096		sdp->isp_devparam[tgt].cur_offset = 0;
4097		sdp->isp_devparam[tgt].cur_period = 0;
4098		sdp->isp_devparam[tgt].dev_flags = DPARM_DEFAULT;
4099		sdp->isp_devparam[tgt].cur_dflags = 0;
4100		/*
4101		 * We default to Wide/Fast for versions less than a 1040
4102		 * (unless it's SBus).
4103		 */
4104		if ((isp->isp_bustype == ISP_BT_SBUS &&
4105		    isp->isp_type < ISP_HA_SCSI_1020A) ||
4106		    (isp->isp_bustype == ISP_BT_PCI &&
4107		    isp->isp_type < ISP_HA_SCSI_1040) ||
4108		    (isp->isp_clock && isp->isp_clock < 60) ||
4109		    (sdp->isp_ultramode == 0)) {
4110			sdp->isp_devparam[tgt].sync_offset =
4111			    ISP_10M_SYNCPARMS >> 8;
4112			sdp->isp_devparam[tgt].sync_period =
4113			    ISP_10M_SYNCPARMS & 0xff;
4114		} else if (IS_ULTRA2(isp)) {
4115			sdp->isp_devparam[tgt].sync_offset =
4116			    ISP_40M_SYNCPARMS >> 8;
4117			sdp->isp_devparam[tgt].sync_period =
4118			    ISP_40M_SYNCPARMS & 0xff;
4119		} else {
4120			sdp->isp_devparam[tgt].sync_offset =
4121			    ISP_20M_SYNCPARMS >> 8;
4122			sdp->isp_devparam[tgt].sync_period =
4123			    ISP_20M_SYNCPARMS & 0xff;
4124		}
4125
4126		/*
4127		 * Don't get current target parameters if we've been
4128		 * told not to use NVRAM- it's really the same thing.
4129		 */
4130		if ((isp->isp_confopts & ISP_CFG_NONVRAM) == 0) {
4131
4132			mbs.param[0] = MBOX_GET_TARGET_PARAMS;
4133			mbs.param[1] = tgt << 8;
4134			isp_mboxcmd(isp, &mbs);
4135			if (mbs.param[0] != MBOX_COMMAND_COMPLETE) {
4136				continue;
4137			}
4138			sdp->isp_devparam[tgt].cur_dflags = mbs.param[2];
4139			sdp->isp_devparam[tgt].dev_flags = mbs.param[2];
4140			sdp->isp_devparam[tgt].cur_period = mbs.param[3] & 0xff;
4141			sdp->isp_devparam[tgt].cur_offset = mbs.param[3] >> 8;
4142
4143			/*
4144			 * The maximum period we can really see
4145			 * here is 100 (decimal), or 400 ns.
4146			 * For some unknown reason we sometimes
4147			 * get back wildass numbers from the
4148			 * boot device's parameters (alpha only).
4149			 */
4150			if ((mbs.param[3] & 0xff) <= 0x64) {
4151				sdp->isp_devparam[tgt].sync_period =
4152				    mbs.param[3] & 0xff;
4153				sdp->isp_devparam[tgt].sync_offset =
4154				    mbs.param[3] >> 8;
4155			}
4156
4157			/*
4158			 * It is not safe to run Ultra Mode with a clock < 60.
4159			 */
4160			if (((isp->isp_clock && isp->isp_clock < 60) ||
4161			    (isp->isp_type < ISP_HA_SCSI_1020A)) &&
4162			    (sdp->isp_devparam[tgt].sync_period <=
4163			    (ISP_20M_SYNCPARMS & 0xff))) {
4164				sdp->isp_devparam[tgt].sync_offset =
4165				    ISP_10M_SYNCPARMS >> 8;
4166				sdp->isp_devparam[tgt].sync_period =
4167				    ISP_10M_SYNCPARMS & 0xff;
4168			}
4169		}
4170		IDPRINTF(3, ("%s: bus %d tgt %d flags %x offset %x period %x\n",
4171		    isp->isp_name, channel, tgt,
4172		    sdp->isp_devparam[tgt].dev_flags,
4173		    sdp->isp_devparam[tgt].sync_offset,
4174		    sdp->isp_devparam[tgt].sync_period));
4175	}
4176
4177	/*
4178	 * Establish default some more default parameters.
4179	 */
4180	sdp->isp_cmd_dma_burst_enable = 1;
4181	sdp->isp_data_dma_burst_enabl = 1;
4182	sdp->isp_fifo_threshold = 0;
4183	sdp->isp_initiator_id = 7;
4184	/* XXXX This is probably based upon clock XXXX */
4185	if (isp->isp_type >= ISP_HA_SCSI_1040) {
4186		sdp->isp_async_data_setup = 9;
4187	} else {
4188		sdp->isp_async_data_setup = 6;
4189	}
4190	sdp->isp_selection_timeout = 250;
4191	sdp->isp_max_queue_depth = MAXISPREQUEST;
4192	sdp->isp_tag_aging = 8;
4193	sdp->isp_bus_reset_delay = 3;
4194	sdp->isp_retry_count = 2;
4195	sdp->isp_retry_delay = 2;
4196
4197	for (tgt = 0; tgt < MAX_TARGETS; tgt++) {
4198		sdp->isp_devparam[tgt].exc_throttle = 16;
4199		sdp->isp_devparam[tgt].dev_enable = 1;
4200	}
4201}
4202
4203/*
4204 * Re-initialize the ISP and complete all orphaned commands
4205 * with a 'botched' notice. The reset/init routines should
4206 * not disturb an already active list of commands.
4207 *
4208 * Locks held prior to coming here.
4209 */
4210
4211void
4212isp_restart(isp)
4213	struct ispsoftc *isp;
4214{
4215	ISP_SCSI_XFER_T *xs;
4216	u_int32_t handle;
4217
4218#if	0
4219	isp->isp_gotdparms = 0;
4220#endif
4221	isp_reset(isp);
4222	if (isp->isp_state == ISP_RESETSTATE) {
4223		isp_init(isp);
4224		if (isp->isp_state == ISP_INITSTATE) {
4225			isp->isp_state = ISP_RUNSTATE;
4226		}
4227	}
4228	if (isp->isp_state != ISP_RUNSTATE) {
4229		PRINTF("%s: isp_restart cannot restart ISP\n", isp->isp_name);
4230	}
4231	isp->isp_nactive = 0;
4232
4233	for (handle = 1; handle <= (int) isp->isp_maxcmds; handle++) {
4234		xs = isp_find_xs(isp, handle);
4235		if (xs == NULL) {
4236			continue;
4237		}
4238		isp_destroy_handle(isp, handle);
4239		if (XS_XFRLEN(xs)) {
4240			ISP_DMAFREE(isp, xs, handle);
4241			XS_RESID(xs) = XS_XFRLEN(xs);
4242		} else {
4243			XS_RESID(xs) = 0;
4244		}
4245		XS_SETERR(xs, HBA_BUSRESET);
4246		XS_CMD_DONE(xs);
4247	}
4248}
4249
4250/*
4251 * NVRAM Routines
4252 */
4253static int
4254isp_read_nvram(isp)
4255	struct ispsoftc *isp;
4256{
4257	int i, amt;
4258	u_int8_t csum, minversion;
4259	union {
4260		u_int8_t _x[ISP2100_NVRAM_SIZE];
4261		u_int16_t _s[ISP2100_NVRAM_SIZE>>1];
4262	} _n;
4263#define	nvram_data	_n._x
4264#define	nvram_words	_n._s
4265
4266	if (IS_FC(isp)) {
4267		amt = ISP2100_NVRAM_SIZE;
4268		minversion = 1;
4269	} else if (IS_ULTRA2(isp)) {
4270		amt = ISP1080_NVRAM_SIZE;
4271		minversion = 0;
4272	} else {
4273		amt = ISP_NVRAM_SIZE;
4274		minversion = 2;
4275	}
4276
4277	/*
4278	 * Just read the first two words first to see if we have a valid
4279	 * NVRAM to continue reading the rest with.
4280	 */
4281	for (i = 0; i < 2; i++) {
4282		isp_rdnvram_word(isp, i, &nvram_words[i]);
4283	}
4284	if (nvram_data[0] != 'I' || nvram_data[1] != 'S' ||
4285	    nvram_data[2] != 'P') {
4286		if (isp->isp_bustype != ISP_BT_SBUS) {
4287			PRINTF("%s: invalid NVRAM header (%x,%x,%x,%x)\n",
4288			    isp->isp_name, nvram_data[0], nvram_data[1],
4289			    nvram_data[2], nvram_data[3]);
4290		}
4291		return (-1);
4292	}
4293	for (i = 2; i < amt>>1; i++) {
4294		isp_rdnvram_word(isp, i, &nvram_words[i]);
4295	}
4296	for (csum = 0, i = 0; i < amt; i++) {
4297		csum += nvram_data[i];
4298	}
4299	if (csum != 0) {
4300		PRINTF("%s: invalid NVRAM checksum\n", isp->isp_name);
4301		return (-1);
4302	}
4303	if (ISP_NVRAM_VERSION(nvram_data) < minversion) {
4304		PRINTF("%s: version %d NVRAM not understood\n", isp->isp_name,
4305		    ISP_NVRAM_VERSION(nvram_data));
4306		return (-1);
4307	}
4308
4309	if (IS_ULTRA3(isp)) {
4310		isp_parse_nvram_12160(isp, 0, nvram_data);
4311		isp_parse_nvram_12160(isp, 1, nvram_data);
4312	} else if (IS_1080(isp)) {
4313		isp_parse_nvram_1080(isp, 0, nvram_data);
4314	} else if (IS_1280(isp) || IS_1240(isp)) {
4315		isp_parse_nvram_1080(isp, 0, nvram_data);
4316		isp_parse_nvram_1080(isp, 1, nvram_data);
4317	} else if (IS_SCSI(isp)) {
4318		isp_parse_nvram_1020(isp, nvram_data);
4319	} else {
4320		isp_parse_nvram_2100(isp, nvram_data);
4321	}
4322	IDPRINTF(3, ("%s: NVRAM is valid\n", isp->isp_name));
4323	return (0);
4324#undef	nvram_data
4325#undef	nvram_words
4326}
4327
4328static void
4329isp_rdnvram_word(isp, wo, rp)
4330	struct ispsoftc *isp;
4331	int wo;
4332	u_int16_t *rp;
4333{
4334	int i, cbits;
4335	u_int16_t bit, rqst;
4336
4337	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
4338	SYS_DELAY(2);
4339	ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
4340	SYS_DELAY(2);
4341
4342	if (IS_FC(isp)) {
4343		wo &= ((ISP2100_NVRAM_SIZE >> 1) - 1);
4344		rqst = (ISP_NVRAM_READ << 8) | wo;
4345		cbits = 10;
4346	} else if (IS_ULTRA2(isp)) {
4347		wo &= ((ISP1080_NVRAM_SIZE >> 1) - 1);
4348		rqst = (ISP_NVRAM_READ << 8) | wo;
4349		cbits = 10;
4350	} else {
4351		wo &= ((ISP_NVRAM_SIZE >> 1) - 1);
4352		rqst = (ISP_NVRAM_READ << 6) | wo;
4353		cbits = 8;
4354	}
4355
4356	/*
4357	 * Clock the word select request out...
4358	 */
4359	for (i = cbits; i >= 0; i--) {
4360		if ((rqst >> i) & 1) {
4361			bit = BIU_NVRAM_SELECT | BIU_NVRAM_DATAOUT;
4362		} else {
4363			bit = BIU_NVRAM_SELECT;
4364		}
4365		ISP_WRITE(isp, BIU_NVRAM, bit);
4366		SYS_DELAY(2);
4367		ISP_WRITE(isp, BIU_NVRAM, bit | BIU_NVRAM_CLOCK);
4368		SYS_DELAY(2);
4369		ISP_WRITE(isp, BIU_NVRAM, bit);
4370		SYS_DELAY(2);
4371	}
4372	/*
4373	 * Now read the result back in (bits come back in MSB format).
4374	 */
4375	*rp = 0;
4376	for (i = 0; i < 16; i++) {
4377		u_int16_t rv;
4378		*rp <<= 1;
4379		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT|BIU_NVRAM_CLOCK);
4380		SYS_DELAY(2);
4381		rv = ISP_READ(isp, BIU_NVRAM);
4382		if (rv & BIU_NVRAM_DATAIN) {
4383			*rp |= 1;
4384		}
4385		SYS_DELAY(2);
4386		ISP_WRITE(isp, BIU_NVRAM, BIU_NVRAM_SELECT);
4387		SYS_DELAY(2);
4388	}
4389	ISP_WRITE(isp, BIU_NVRAM, 0);
4390	SYS_DELAY(2);
4391#if	BYTE_ORDER == BIG_ENDIAN
4392	*rp = ((*rp >> 8) | ((*rp & 0xff) << 8));
4393#endif
4394}
4395
4396static void
4397isp_parse_nvram_1020(isp, nvram_data)
4398	struct ispsoftc *isp;
4399	u_int8_t *nvram_data;
4400{
4401	int i;
4402	static char *tru = "true";
4403	static char *not = "false";
4404	sdparam *sdp = (sdparam *) isp->isp_param;
4405
4406	sdp->isp_fifo_threshold =
4407		ISP_NVRAM_FIFO_THRESHOLD(nvram_data) |
4408		(ISP_NVRAM_FIFO_THRESHOLD_128(nvram_data) << 2);
4409
4410	sdp->isp_initiator_id =
4411		ISP_NVRAM_INITIATOR_ID(nvram_data);
4412
4413	sdp->isp_bus_reset_delay =
4414		ISP_NVRAM_BUS_RESET_DELAY(nvram_data);
4415
4416	sdp->isp_retry_count =
4417		ISP_NVRAM_BUS_RETRY_COUNT(nvram_data);
4418
4419	sdp->isp_retry_delay =
4420		ISP_NVRAM_BUS_RETRY_DELAY(nvram_data);
4421
4422	sdp->isp_async_data_setup =
4423		ISP_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data);
4424
4425	if (isp->isp_type >= ISP_HA_SCSI_1040) {
4426		if (sdp->isp_async_data_setup < 9) {
4427			sdp->isp_async_data_setup = 9;
4428		}
4429	} else {
4430		if (sdp->isp_async_data_setup != 6) {
4431			sdp->isp_async_data_setup = 6;
4432		}
4433	}
4434
4435	sdp->isp_req_ack_active_neg =
4436		ISP_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data);
4437
4438	sdp->isp_data_line_active_neg =
4439		ISP_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data);
4440
4441	sdp->isp_data_dma_burst_enabl =
4442		ISP_NVRAM_DATA_DMA_BURST_ENABLE(nvram_data);
4443
4444	sdp->isp_cmd_dma_burst_enable =
4445		ISP_NVRAM_CMD_DMA_BURST_ENABLE(nvram_data);
4446
4447	sdp->isp_tag_aging =
4448		ISP_NVRAM_TAG_AGE_LIMIT(nvram_data);
4449
4450	sdp->isp_selection_timeout =
4451		ISP_NVRAM_SELECTION_TIMEOUT(nvram_data);
4452
4453	sdp->isp_max_queue_depth =
4454		ISP_NVRAM_MAX_QUEUE_DEPTH(nvram_data);
4455
4456	isp->isp_fast_mttr = ISP_NVRAM_FAST_MTTR_ENABLE(nvram_data);
4457	if (isp->isp_dblev > 2) {
4458		PRINTF("%s: NVRAM values:\n", isp->isp_name);
4459		PRINTF("             Fifo Threshold = 0x%x\n",
4460		    sdp->isp_fifo_threshold);
4461		PRINTF("            Bus Reset Delay = %d\n",
4462		    sdp->isp_bus_reset_delay);
4463		PRINTF("                Retry Count = %d\n",
4464		    sdp->isp_retry_count);
4465		PRINTF("                Retry Delay = %d\n",
4466		    sdp->isp_retry_delay);
4467		PRINTF("              Tag Age Limit = %d\n",
4468		    sdp->isp_tag_aging);
4469		PRINTF("          Selection Timeout = %d\n",
4470		    sdp->isp_selection_timeout);
4471		PRINTF("            Max Queue Depth = %d\n",
4472		    sdp->isp_max_queue_depth);
4473		PRINTF("           Async Data Setup = 0x%x\n",
4474		    sdp->isp_async_data_setup);
4475		PRINTF("    REQ/ACK Active Negation = %s\n",
4476		    sdp->isp_req_ack_active_neg? tru : not);
4477		PRINTF("  Data Line Active Negation = %s\n",
4478		    sdp->isp_data_line_active_neg? tru : not);
4479		PRINTF("      Data DMA Burst Enable = %s\n",
4480		    sdp->isp_data_dma_burst_enabl? tru : not);
4481		PRINTF("       Cmd DMA Burst Enable = %s\n",
4482		    sdp->isp_cmd_dma_burst_enable? tru : not);
4483		PRINTF("                  Fast MTTR = %s\n",
4484		    isp->isp_fast_mttr? tru : not);
4485	}
4486	for (i = 0; i < MAX_TARGETS; i++) {
4487		sdp->isp_devparam[i].dev_enable =
4488			ISP_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i);
4489		sdp->isp_devparam[i].exc_throttle =
4490			ISP_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i);
4491		sdp->isp_devparam[i].sync_offset =
4492			ISP_NVRAM_TGT_SYNC_OFFSET(nvram_data, i);
4493		sdp->isp_devparam[i].sync_period =
4494			ISP_NVRAM_TGT_SYNC_PERIOD(nvram_data, i);
4495
4496		if (isp->isp_type < ISP_HA_SCSI_1040) {
4497			/*
4498			 * If we're not ultra, we can't possibly
4499			 * be a shorter period than this.
4500			 */
4501			if (sdp->isp_devparam[i].sync_period < 0x19) {
4502				sdp->isp_devparam[i].sync_period =
4503				    0x19;
4504			}
4505			if (sdp->isp_devparam[i].sync_offset > 0xc) {
4506				sdp->isp_devparam[i].sync_offset =
4507				    0x0c;
4508			}
4509		} else {
4510			if (sdp->isp_devparam[i].sync_offset > 0x8) {
4511				sdp->isp_devparam[i].sync_offset = 0x8;
4512			}
4513		}
4514		sdp->isp_devparam[i].dev_flags = 0;
4515		if (ISP_NVRAM_TGT_RENEG(nvram_data, i))
4516			sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
4517		if (ISP_NVRAM_TGT_QFRZ(nvram_data, i)) {
4518			PRINTF("%s: not supporting QFRZ option for "
4519			    "target %d\n", isp->isp_name, i);
4520		}
4521		sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
4522		if (ISP_NVRAM_TGT_ARQ(nvram_data, i) == 0) {
4523			PRINTF("%s: not disabling ARQ option for "
4524			    "target %d\n", isp->isp_name, i);
4525		}
4526		if (ISP_NVRAM_TGT_TQING(nvram_data, i))
4527			sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
4528		if (ISP_NVRAM_TGT_SYNC(nvram_data, i))
4529			sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
4530		if (ISP_NVRAM_TGT_WIDE(nvram_data, i))
4531			sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
4532		if (ISP_NVRAM_TGT_PARITY(nvram_data, i))
4533			sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
4534		if (ISP_NVRAM_TGT_DISC(nvram_data, i))
4535			sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
4536		sdp->isp_devparam[i].cur_dflags = 0; /* we don't know */
4537		if (isp->isp_dblev > 2) {
4538			PRINTF("   Target %d: Enabled %d Throttle %d "
4539			    "Offset %d Period %d Flags 0x%x\n", i,
4540			    sdp->isp_devparam[i].dev_enable,
4541			    sdp->isp_devparam[i].exc_throttle,
4542			    sdp->isp_devparam[i].sync_offset,
4543			    sdp->isp_devparam[i].sync_period,
4544			    sdp->isp_devparam[i].dev_flags);
4545		}
4546	}
4547}
4548
4549static void
4550isp_parse_nvram_1080(isp, bus, nvram_data)
4551	struct ispsoftc *isp;
4552	int bus;
4553	u_int8_t *nvram_data;
4554{
4555	static char *tru = "true";
4556	static char *not = "false";
4557	int i;
4558	sdparam *sdp = (sdparam *) isp->isp_param;
4559	sdp += bus;
4560
4561	sdp->isp_fifo_threshold =
4562	    ISP1080_NVRAM_FIFO_THRESHOLD(nvram_data);
4563
4564	sdp->isp_initiator_id =
4565	    ISP1080_NVRAM_INITIATOR_ID(nvram_data, bus);
4566
4567	sdp->isp_bus_reset_delay =
4568	    ISP1080_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
4569
4570	sdp->isp_retry_count =
4571	    ISP1080_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
4572
4573	sdp->isp_retry_delay =
4574	    ISP1080_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
4575
4576	sdp->isp_async_data_setup =
4577	    ISP1080_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data,
4578	    bus);
4579
4580	sdp->isp_req_ack_active_neg =
4581	    ISP1080_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data,
4582	    bus);
4583
4584	sdp->isp_data_line_active_neg =
4585	    ISP1080_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data,
4586	    bus);
4587
4588	sdp->isp_data_dma_burst_enabl =
4589	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
4590
4591	sdp->isp_cmd_dma_burst_enable =
4592	    ISP1080_NVRAM_BURST_ENABLE(nvram_data);
4593
4594	sdp->isp_selection_timeout =
4595	    ISP1080_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
4596
4597	sdp->isp_max_queue_depth =
4598	     ISP1080_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
4599
4600	if (isp->isp_dblev >= 3) {
4601		PRINTF("%s: ISP1080 bus %d NVRAM values:\n",
4602		    isp->isp_name, bus);
4603		PRINTF("               Initiator ID = %d\n",
4604		    sdp->isp_initiator_id);
4605		PRINTF("             Fifo Threshold = 0x%x\n",
4606		    sdp->isp_fifo_threshold);
4607		PRINTF("            Bus Reset Delay = %d\n",
4608		    sdp->isp_bus_reset_delay);
4609		PRINTF("                Retry Count = %d\n",
4610		    sdp->isp_retry_count);
4611		PRINTF("                Retry Delay = %d\n",
4612		    sdp->isp_retry_delay);
4613		PRINTF("              Tag Age Limit = %d\n",
4614		    sdp->isp_tag_aging);
4615		PRINTF("          Selection Timeout = %d\n",
4616		    sdp->isp_selection_timeout);
4617		PRINTF("            Max Queue Depth = %d\n",
4618		    sdp->isp_max_queue_depth);
4619		PRINTF("           Async Data Setup = 0x%x\n",
4620		    sdp->isp_async_data_setup);
4621		PRINTF("    REQ/ACK Active Negation = %s\n",
4622		    sdp->isp_req_ack_active_neg? tru : not);
4623		PRINTF("  Data Line Active Negation = %s\n",
4624		    sdp->isp_data_line_active_neg? tru : not);
4625		PRINTF("       Cmd DMA Burst Enable = %s\n",
4626		    sdp->isp_cmd_dma_burst_enable? tru : not);
4627	}
4628	for (i = 0; i < MAX_TARGETS; i++) {
4629		sdp->isp_devparam[i].dev_enable =
4630		    ISP1080_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
4631		sdp->isp_devparam[i].exc_throttle =
4632			ISP1080_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus);
4633		sdp->isp_devparam[i].sync_offset =
4634			ISP1080_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus);
4635		sdp->isp_devparam[i].sync_period =
4636			ISP1080_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus);
4637		sdp->isp_devparam[i].dev_flags = 0;
4638		if (ISP1080_NVRAM_TGT_RENEG(nvram_data, i, bus))
4639			sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
4640		if (ISP1080_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
4641			PRINTF("%s: not supporting QFRZ option "
4642			    "for target %d bus %d\n",
4643			    isp->isp_name, i, bus);
4644		}
4645		sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
4646		if (ISP1080_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
4647			PRINTF("%s: not disabling ARQ option "
4648			    "for target %d bus %d\n",
4649			    isp->isp_name, i, bus);
4650		}
4651		if (ISP1080_NVRAM_TGT_TQING(nvram_data, i, bus))
4652			sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
4653		if (ISP1080_NVRAM_TGT_SYNC(nvram_data, i, bus))
4654			sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
4655		if (ISP1080_NVRAM_TGT_WIDE(nvram_data, i, bus))
4656			sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
4657		if (ISP1080_NVRAM_TGT_PARITY(nvram_data, i, bus))
4658			sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
4659		if (ISP1080_NVRAM_TGT_DISC(nvram_data, i, bus))
4660			sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
4661		sdp->isp_devparam[i].cur_dflags = 0;
4662		if (isp->isp_dblev >= 3) {
4663			PRINTF("   Target %d: Ena %d Throttle "
4664			    "%d Offset %d Period %d Flags "
4665			    "0x%x\n", i,
4666			    sdp->isp_devparam[i].dev_enable,
4667			    sdp->isp_devparam[i].exc_throttle,
4668			    sdp->isp_devparam[i].sync_offset,
4669			    sdp->isp_devparam[i].sync_period,
4670			    sdp->isp_devparam[i].dev_flags);
4671		}
4672	}
4673}
4674
4675static void
4676isp_parse_nvram_12160(isp, bus, nvram_data)
4677	struct ispsoftc *isp;
4678	int bus;
4679	u_int8_t *nvram_data;
4680{
4681	static char *tru = "true";
4682	static char *not = "false";
4683	sdparam *sdp = (sdparam *) isp->isp_param;
4684	int i;
4685
4686	sdp += bus;
4687
4688	sdp->isp_fifo_threshold =
4689	    ISP12160_NVRAM_FIFO_THRESHOLD(nvram_data);
4690
4691	sdp->isp_initiator_id =
4692	    ISP12160_NVRAM_INITIATOR_ID(nvram_data, bus);
4693
4694	sdp->isp_bus_reset_delay =
4695	    ISP12160_NVRAM_BUS_RESET_DELAY(nvram_data, bus);
4696
4697	sdp->isp_retry_count =
4698	    ISP12160_NVRAM_BUS_RETRY_COUNT(nvram_data, bus);
4699
4700	sdp->isp_retry_delay =
4701	    ISP12160_NVRAM_BUS_RETRY_DELAY(nvram_data, bus);
4702
4703	sdp->isp_async_data_setup =
4704	    ISP12160_NVRAM_ASYNC_DATA_SETUP_TIME(nvram_data,
4705	    bus);
4706
4707	sdp->isp_req_ack_active_neg =
4708	    ISP12160_NVRAM_REQ_ACK_ACTIVE_NEGATION(nvram_data,
4709	    bus);
4710
4711	sdp->isp_data_line_active_neg =
4712	    ISP12160_NVRAM_DATA_LINE_ACTIVE_NEGATION(nvram_data,
4713	    bus);
4714
4715	sdp->isp_data_dma_burst_enabl =
4716	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
4717
4718	sdp->isp_cmd_dma_burst_enable =
4719	    ISP12160_NVRAM_BURST_ENABLE(nvram_data);
4720
4721	sdp->isp_selection_timeout =
4722	    ISP12160_NVRAM_SELECTION_TIMEOUT(nvram_data, bus);
4723
4724	sdp->isp_max_queue_depth =
4725	     ISP12160_NVRAM_MAX_QUEUE_DEPTH(nvram_data, bus);
4726
4727	if (isp->isp_dblev >= 3) {
4728		PRINTF("%s: ISP12160 bus %d NVRAM values:\n",
4729		    isp->isp_name, bus);
4730		PRINTF("               Initiator ID = %d\n",
4731		    sdp->isp_initiator_id);
4732		PRINTF("             Fifo Threshold = 0x%x\n",
4733		    sdp->isp_fifo_threshold);
4734		PRINTF("            Bus Reset Delay = %d\n",
4735		    sdp->isp_bus_reset_delay);
4736		PRINTF("                Retry Count = %d\n",
4737		    sdp->isp_retry_count);
4738		PRINTF("                Retry Delay = %d\n",
4739		    sdp->isp_retry_delay);
4740		PRINTF("              Tag Age Limit = %d\n",
4741		    sdp->isp_tag_aging);
4742		PRINTF("          Selection Timeout = %d\n",
4743		    sdp->isp_selection_timeout);
4744		PRINTF("            Max Queue Depth = %d\n",
4745		    sdp->isp_max_queue_depth);
4746		PRINTF("           Async Data Setup = 0x%x\n",
4747		    sdp->isp_async_data_setup);
4748		PRINTF("    REQ/ACK Active Negation = %s\n",
4749		    sdp->isp_req_ack_active_neg? tru : not);
4750		PRINTF("  Data Line Active Negation = %s\n",
4751		    sdp->isp_data_line_active_neg? tru : not);
4752		PRINTF("       Cmd DMA Burst Enable = %s\n",
4753		    sdp->isp_cmd_dma_burst_enable? tru : not);
4754	}
4755
4756	for (i = 0; i < MAX_TARGETS; i++) {
4757		sdp->isp_devparam[i].dev_enable =
4758		    ISP12160_NVRAM_TGT_DEVICE_ENABLE(nvram_data, i, bus);
4759		sdp->isp_devparam[i].exc_throttle =
4760			ISP12160_NVRAM_TGT_EXEC_THROTTLE(nvram_data, i, bus);
4761		sdp->isp_devparam[i].sync_offset =
4762			ISP12160_NVRAM_TGT_SYNC_OFFSET(nvram_data, i, bus);
4763		sdp->isp_devparam[i].sync_period =
4764			ISP12160_NVRAM_TGT_SYNC_PERIOD(nvram_data, i, bus);
4765		sdp->isp_devparam[i].dev_flags = 0;
4766		if (ISP12160_NVRAM_TGT_RENEG(nvram_data, i, bus))
4767			sdp->isp_devparam[i].dev_flags |= DPARM_RENEG;
4768		if (ISP12160_NVRAM_TGT_QFRZ(nvram_data, i, bus)) {
4769			PRINTF("%s: not supporting QFRZ option "
4770			    "for target %d bus %d\n", isp->isp_name, i, bus);
4771		}
4772		sdp->isp_devparam[i].dev_flags |= DPARM_ARQ;
4773		if (ISP12160_NVRAM_TGT_ARQ(nvram_data, i, bus) == 0) {
4774			PRINTF("%s: not disabling ARQ option "
4775			    "for target %d bus %d\n", isp->isp_name, i, bus);
4776		}
4777		if (ISP12160_NVRAM_TGT_TQING(nvram_data, i, bus))
4778			sdp->isp_devparam[i].dev_flags |= DPARM_TQING;
4779		if (ISP12160_NVRAM_TGT_SYNC(nvram_data, i, bus))
4780			sdp->isp_devparam[i].dev_flags |= DPARM_SYNC;
4781		if (ISP12160_NVRAM_TGT_WIDE(nvram_data, i, bus))
4782			sdp->isp_devparam[i].dev_flags |= DPARM_WIDE;
4783		if (ISP12160_NVRAM_TGT_PARITY(nvram_data, i, bus))
4784			sdp->isp_devparam[i].dev_flags |= DPARM_PARITY;
4785		if (ISP12160_NVRAM_TGT_DISC(nvram_data, i, bus))
4786			sdp->isp_devparam[i].dev_flags |= DPARM_DISC;
4787		sdp->isp_devparam[i].cur_dflags = 0;
4788		if (isp->isp_dblev >= 3) {
4789			PRINTF("   Target %d: Ena %d Throttle %d Offset %d "
4790			    "Period %d Flags 0x%x\n", i,
4791			    sdp->isp_devparam[i].dev_enable,
4792			    sdp->isp_devparam[i].exc_throttle,
4793			    sdp->isp_devparam[i].sync_offset,
4794			    sdp->isp_devparam[i].sync_period,
4795			    sdp->isp_devparam[i].dev_flags);
4796		}
4797	}
4798}
4799
4800static void
4801isp_parse_nvram_2100(isp, nvram_data)
4802	struct ispsoftc *isp;
4803	u_int8_t *nvram_data;
4804{
4805	fcparam *fcp = (fcparam *) isp->isp_param;
4806	union {
4807		struct {
4808#if	BYTE_ORDER == BIG_ENDIAN
4809			u_int32_t hi32;
4810			u_int32_t lo32;
4811#else
4812			u_int32_t lo32;
4813			u_int32_t hi32;
4814#endif
4815		} wd;
4816		u_int64_t full64;
4817	} wwnstore;
4818
4819	/*
4820	 * There is supposed to be WWNN storage as distinct
4821	 * from WWPN storage in NVRAM, but it doesn't appear
4822	 * to be used sanely.
4823	 */
4824
4825	wwnstore.full64 = ISP2100_NVRAM_PORT_NAME(nvram_data);
4826	if (wwnstore.full64 != 0LL) {
4827		switch ((int) (wwnstore.full64 >> 60)) {
4828		case 0:
4829			/*
4830			 * Broken cards with nothing in the top nibble.
4831			 * Pah.
4832			 */
4833			wwnstore.full64 |= (2LL << 60);
4834			/* FALLTHROUGH */
4835		case 2:
4836			fcp->isp_portwwn = wwnstore.full64;
4837			fcp->isp_nodewwn = wwnstore.full64;
4838			fcp->isp_nodewwn &= ~((0xfffLL) << 48);
4839			if (fcp->isp_nodewwn == fcp->isp_portwwn) {
4840				fcp->isp_portwwn |=
4841				    (((u_int64_t)(isp->isp_unit+1)) << 48);
4842			}
4843			break;
4844		default:
4845			fcp->isp_portwwn = wwnstore.full64;
4846			fcp->isp_nodewwn = wwnstore.full64;
4847		}
4848	}
4849	CFGPRINTF("%s: Node WWN 0x%08x%08x, Port WWN 0x%08x%08x\n",
4850	    isp->isp_name, (u_int32_t) (fcp->isp_nodewwn >> 32),
4851	    (u_int32_t) (fcp->isp_nodewwn & 0xffffffff),
4852	    (u_int32_t) (fcp->isp_portwwn >> 32),
4853	    (u_int32_t) (fcp->isp_portwwn & 0xffffffff));
4854
4855	fcp->isp_maxalloc =
4856		ISP2100_NVRAM_MAXIOCBALLOCATION(nvram_data);
4857	fcp->isp_maxfrmlen =
4858		ISP2100_NVRAM_MAXFRAMELENGTH(nvram_data);
4859	fcp->isp_retry_delay =
4860		ISP2100_NVRAM_RETRY_DELAY(nvram_data);
4861	fcp->isp_retry_count =
4862		ISP2100_NVRAM_RETRY_COUNT(nvram_data);
4863	fcp->isp_loopid =
4864		ISP2100_NVRAM_HARDLOOPID(nvram_data);
4865	fcp->isp_execthrottle =
4866		ISP2100_NVRAM_EXECUTION_THROTTLE(nvram_data);
4867	fcp->isp_fwoptions = ISP2100_NVRAM_OPTIONS(nvram_data);
4868	if (isp->isp_dblev > 2) {
4869		PRINTF("%s: NVRAM values:\n", isp->isp_name);
4870		PRINTF("  Max IOCB Allocation = %d\n",
4871		    fcp->isp_maxalloc);
4872		PRINTF("     Max Frame Length = %d\n",
4873		    fcp->isp_maxfrmlen);
4874		PRINTF("   Execution Throttle = %d\n",
4875		    fcp->isp_execthrottle);
4876		PRINTF("          Retry Count = %d\n",
4877		    fcp->isp_retry_count);
4878		PRINTF("          Retry Delay = %d\n",
4879		    fcp->isp_retry_delay);
4880		PRINTF("         Hard Loop ID = %d\n",
4881		    fcp->isp_loopid);
4882		PRINTF("              Options = 0x%x\n",
4883		    fcp->isp_fwoptions);
4884		PRINTF("          HBA Options = 0x%x\n",
4885		    ISP2100_NVRAM_HBA_OPTIONS(nvram_data));
4886	}
4887}
4888